Skip to main content

Overview

The Transactional resource allows you to send transactional emails using your published Brew templates. Access it via client.send.transactional.
SDK Parameter Names: The SDK uses chat_id for template IDs and variables for template data. The REST API uses different names (transactionalId and dataVariables). This documentation covers the SDK interface.

Methods

MethodDescription
send.transactional.send()Send a transactional email
send.transactional.documentation()Get API documentation info

Send Transactional Email

Send a transactional email using a published email template.
The template must be published (status: “live”) in Brew before it can be used via API.

Basic Usage

from brew_sdk import BrewSDK

client = BrewSDK()

response = client.send.transactional.send(
    chat_id="your-template-id",
    to="[email protected]",
    variables={
        "firstName": "John",
        "orderNumber": "ORD-12345",
    },
)

print("Emails sent:", response.data.sent)

Send to Multiple Recipients

Send the same email to multiple recipients (up to 1000):
response = client.send.transactional.send(
    chat_id="announcement-template",
    to=[
        "[email protected]",
        "[email protected]",
        "[email protected]",
    ],
    variables={
        "announcement": "New feature launched!",
        "ctaUrl": "https://example.com/new-feature",
    },
)

print(f"Sent: {response.data.sent}, Failed: {response.data.failed}")

Override Sender and Subject

response = client.send.transactional.send(
    chat_id="order-confirmation",
    to="[email protected]",
    from_="[email protected]",
    reply_to="[email protected]",
    subject="Your Order #12345 is Confirmed!",
    variables={
        "orderNumber": "12345",
        "orderTotal": "$99.99",
        "deliveryDate": "January 25, 2024",
    },
)
Note that from_ has a trailing underscore because from is a reserved keyword in Python.

With Request Options

You can pass additional options like custom timeouts:
response = client.with_options(
    timeout=10.0,      # 10 second timeout
    max_retries=5,     # Retry up to 5 times
).send.transactional.send(
    chat_id="urgent-notification",
    to="[email protected]",
    variables={"message": "Important update"},
)

Parameters

chat_id
str
required
The transactional email template ID from Brew.
to
str | List[str]
required
Recipient email address(es). Can be a single email or a list of up to 1000 emails.
variables
Dict[str, Any]
Template variables as key-value pairs. These populate dynamic content in your email template.
from_
str
Override the default sender email address.
reply_to
str
Set the reply-to email address.
subject
str
Override the default subject line.

Response Type

from brew_sdk.types.send import TransactionalSendResponse

class TransactionalSendResponse:
    success: Literal[True]
    data: Data
    meta: Optional[Meta]

class Data:
    sent: Optional[int]           # Number of emails sent successfully
    failed: Optional[int]         # Number of emails that failed
    results: Optional[List[Result]]

class Result:
    email: Optional[str]
    id: Optional[str]             # Email ID (if successful)
    error: Optional[str]          # Error message (if failed)

Get API Documentation

Retrieve API documentation and endpoint information:
docs = client.send.transactional.documentation()

print("API Version:", docs.version)
print("Documentation:", docs.documentation)

for endpoint in docs.endpoints or []:
    print(f"{', '.join(endpoint.methods or [])} {endpoint.path}")
    print(f"  {endpoint.description}")

Response Type

from brew_sdk.types.send import TransactionalDocumentationResponse

class TransactionalDocumentationResponse:
    version: Optional[str]               # API version
    documentation: Optional[str]         # Link to full docs
    endpoints: Optional[List[Endpoint]]

class Endpoint:
    path: Optional[str]
    methods: Optional[List[str]]
    description: Optional[str]

Common Use Cases

Password Reset Email

response = client.send.transactional.send(
    chat_id="password-reset-template",
    to=user.email,
    variables={
        "userName": user.first_name,
        "resetLink": f"https://app.example.com/reset?token={token}",
        "expiryHours": 24,
    },
)

Order Confirmation

def format_currency(amount: float) -> str:
    return f"${amount:.2f}"

response = client.send.transactional.send(
    chat_id="order-confirmation-template",
    to=order.customer_email,
    subject=f"Order Confirmed - #{order.id}",
    variables={
        "orderNumber": order.id,
        "orderTotal": format_currency(order.total),
        "items": [
            {
                "name": item.name,
                "quantity": item.quantity,
                "price": format_currency(item.price),
            }
            for item in order.items
        ],
        "shippingAddress": order.shipping_address,
        "estimatedDelivery": order.estimated_delivery,
    },
)

Welcome Email

response = client.send.transactional.send(
    chat_id="welcome-email-template",
    to=new_user.email,
    variables={
        "firstName": new_user.first_name,
        "dashboardUrl": "https://app.example.com/dashboard",
        "helpCenterUrl": "https://help.example.com",
        "trialDays": 14,
    },
)

Team Invitation

response = client.send.transactional.send(
    chat_id="team-invitation-template",
    to=invitee.email,
    reply_to=inviter.email,
    variables={
        "inviterName": inviter.name,
        "teamName": team.name,
        "inviteLink": f"https://app.example.com/invite/{invite_token}",
        "expiryDays": 7,
    },
)

Handling Results

Check Individual Results

When sending to multiple recipients, check each result:
response = client.send.transactional.send(
    chat_id="newsletter-template",
    to=["[email protected]", "[email protected]", "invalid-email"],
    variables={...},
)

# Log successful sends
for result in response.data.results or []:
    if result.id:
        print(f"Sent to {result.email}: ID {result.id}")
    else:
        print(f"Failed for {result.email}: {result.error}")

# Summary
print(f"Total: {response.data.sent} sent, {response.data.failed} failed")

Async Examples

All methods work with the async client:
import asyncio
from brew_sdk import AsyncBrewSDK

async def send_emails():
    async with AsyncBrewSDK() as client:
        # Send single email
        result = await client.send.transactional.send(
            chat_id="welcome-template",
            to="[email protected]",
            variables={"name": "User"},
        )
        
        # Send to multiple recipients
        batch_result = await client.send.transactional.send(
            chat_id="announcement-template",
            to=["[email protected]", "[email protected]"],
            variables={"message": "Hello!"},
        )
        
        return result, batch_result

asyncio.run(send_emails())

Type Imports

Import types for type hints:
# Parameter types
from brew_sdk.types.send import TransactionalSendParams

# Response types
from brew_sdk.types.send import (
    TransactionalSendResponse,
    TransactionalDocumentationResponse,
)

Error Handling

import brew_sdk
from brew_sdk import BrewSDK

client = BrewSDK()

try:
    client.send.transactional.send(
        chat_id="invalid-template-id",
        to="[email protected]",
    )
except brew_sdk.NotFoundError:
    print("Template not found or not published")
except brew_sdk.BadRequestError as e:
    print(f"Invalid request: {e}")
except brew_sdk.RateLimitError:
    print("Rate limited - try again later")
except brew_sdk.APIStatusError as e:
    print(f"API error: {e.status_code}")

Best Practices

Name your templates descriptively in Brew so the IDs are easy to identify:
  • welcome-email
  • password-reset
  • order-confirmation
Ensure all required template variables are present:
def send_order_confirmation(order):
    if not all([order.id, order.customer_email, order.total]):
        raise ValueError("Missing required order data")
    
    return client.send.transactional.send(
        chat_id="order-confirmation",
        to=order.customer_email,
        variables={
            "orderNumber": order.id,
            "orderTotal": order.total,
        },
    )
Always check results and handle failures:
response = client.send.transactional.send(...)

if response.data.failed and response.data.failed > 0:
    # Log failures for investigation
    failures = [r for r in (response.data.results or []) if r.error]
    logger.error(f"Email failures: {failures}")
Set a reply-to address so customer replies go to the right place:
client.send.transactional.send(
    chat_id="support-response",
    to=customer.email,
    reply_to="[email protected]",
    ...
)
Use async with to ensure proper resource cleanup:
async with AsyncBrewSDK() as client:
    await client.send.transactional.send(...)
# Client is properly closed

Need Help?

Our team is ready to support you at every step of your journey with Brew. Choose the option that works best for you:

Search Documentation

Type in the “Ask any question” search bar at the top left to instantly find relevant documentation pages.

ChatGPT/Claude Integration

Click “Open in ChatGPT” at the top right of any page to analyze documentation with ChatGPT or Claude for deeper insights.