Skip to main content

Brew API Overview

Brew’s REST API gives you secure, programmatic access to core email marketing features. Use the API to:
  • Send transactional emails using your published email templates
  • Trigger automations with custom events and payloads
  • Import contacts in bulk with custom fields
  • Update and delete contacts by email address
The API is designed for easy integration with your backend, CRM, or internal tools. All API endpoints are secured with HTTPS and use Bearer token authentication.

Quick Start

Get up and running in under 5 minutes:
1

Get your API key

In Brew, go to Settings → API and click Create API Key. Give it a descriptive name like “Production App”. All API requests require authentication. You can use either header format:
Authorization: Bearer YOUR_API_KEY
X-API-Key: YOUR_API_KEY
Keep your API key secure. Never share it publicly or use it in client-side code. Store it in environment variables and never commit API keys to version control.
2

Test your connection

curl -H "Authorization: Bearer YOUR_API_KEY" \
     https://brew.new/api/send/transactional
This returns API documentation if your key is valid.
3

Start building

Explore the API endpoints and build your integration. Send your first transactional email, create contacts, or trigger automations.

Base URL and Authentication

Base URL: https://brew.new/api All requests must include your API key via one of these headers:
Authorization: Bearer YOUR_API_KEY
X-API-Key: YOUR_API_KEY
Brew’s API follows REST conventions using standard HTTP methods:
  • GET - Retrieve data
  • POST - Create new resources
  • PATCH - Update existing resources
  • DELETE - Remove resources
All requests must be made over HTTPS. We do not support HTTP.
Email addresses in request bodies: For contact operations (update, delete), the email address is passed in the JSON request body, not the URL. No URI encoding is needed.

API Endpoints

The Brew API provides the following endpoints:

Automations

MethodEndpointDescription
POST/automations/{automationId}/triggerTrigger an automation with a payload
GET/automations/{automationId}/triggerGet automation trigger info and schema
The {automationId} parameter accepts two formats:
  • Event ID (recommended): User-defined string like lead_generated, user_signup
  • Automation ID (legacy): Internal Convex document ID

Transactional Emails

MethodEndpointDescription
POST/send/transactionalSend a transactional email
GET/send/transactionalGet API documentation

Contacts

MethodEndpointDescription
POST/contacts/importBulk import contacts (up to 10,000 per request)
GET/contacts/importGet import status or list recent imports
PATCH/contactsUpdate a contact by email
DELETE/contactsDelete a contact or custom fields

Common Use Cases

Send password resets, order confirmations, and other triggered emails:
curl -X POST "https://brew.new/api/send/transactional" \
  -H "Authorization: Bearer brew_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "chatId": "YOUR_TEMPLATE_ID",
    "to": "user@example.com",
    "variables": {
      "resetLink": "https://app.example.com/reset-password?token=abc123",
      "expiryHours": 24
    }
  }'
Response:
{
  "success": true,
  "data": {
    "sent": 1,
    "failed": 0,
    "results": [
      { "email": "user@example.com", "id": "email_abc123" }
    ]
  },
  "meta": { "requestId": "req_xyz789" }
}
Send to multiple recipients (up to 1,000):
curl -X POST "https://brew.new/api/send/transactional" \
  -H "Authorization: Bearer brew_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "chatId": "YOUR_TEMPLATE_ID",
    "to": ["user1@example.com", "user2@example.com"],
    "variables": {
      "announcementTitle": "New Feature Released"
    }
  }'
Recipients on suppression lists (bounced, unsubscribed, complained) will be automatically skipped. Check the dropped and droppedRecipients fields in the response.

Custom Fields

Brew supports custom contact fields to store additional data for segmentation and personalization. Custom fields are passed in the customFields object when importing or updating contacts.

Supported Data Types

TypeDescriptionExample
stringText values"Enterprise", "Product Manager"
numberNumeric values50, 99.99, -10
booleanTrue/false valuestrue, false

Using Custom Fields

Include custom fields when importing or updating contacts:
{
  "email": "user@example.com",
  "firstName": "Jane",
  "customFields": {
    "companyName": "Acme Corp",
    "planType": "Enterprise",
    "teamSize": 50,
    "isTrialing": false
  }
}

Deleting Custom Fields

Use the DELETE endpoint with deleteFields to remove specific custom fields:
curl -X DELETE "https://brew.new/api/contacts" \
  -H "Authorization: Bearer brew_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "deleteFields": ["companyName", "planType"]
  }'

Reserved Field Names

The following field names are reserved and cannot be used as custom fields:
  • email, firstName, lastName, subscribed, createdAt, updatedAt, tags

Rate Limits

Brew enforces the following rate limits:
EndpointLimit
Contact endpoints (/contacts, /contacts/import)100 requests per minute
Contact import batch size10,000 contacts per request
Transactional email recipients1,000 per request
If you exceed the limit (429 response), implement retries with exponential backoff.

Error Handling

Brew uses standard HTTP status codes with consistent error responses:
StatusDescription
200Success
400Bad request
401Invalid API key
404Resource not found
409Conflict (duplicate)
429Rate limit exceeded
500Server error
Error response format:
{
  "success": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "Description of what went wrong",
    "details": { }
  },
  "meta": { "requestId": "req_xxx" }
}
Common error codes include:
  • INVALID_API_KEY - API key is invalid or expired
  • PERMISSION_DENIED - API key doesn’t have required permission
  • INVALID_REQUEST_BODY - Request body is malformed
  • MISSING_REQUIRED_FIELD - Required field is missing
  • CONTACT_NOT_FOUND - Contact with specified email not found
  • RATE_LIMITED - Rate limit exceeded
  • ALL_RECIPIENTS_BLOCKED - All transactional recipients were suppressed
When you receive errors, we recommend implementing appropriate retry logic with exponential backoff for server errors (5xx) and rate limiting (429).
401 Unauthorized:
  • Check your API key is correct and active
  • Ensure you’re using Bearer YOUR_API_KEY format
  • Generate a new key from Settings → API if needed
400 Bad Request:
  • Verify all required fields are included
  • Check data types match the API specification
  • Ensure email addresses are properly formatted
429 Rate Limited:
  • Implement exponential backoff in your retry logic
  • Consider batching requests where possible
  • Monitor rate limit headers in responses
Brew’s API does not support cross-origin requests from browsers. Always make API calls from your backend server.
If you see CORS errors, move your API requests to a server-side environment.

Idempotency

Idempotency ensures that operations (like sending emails) are only performed once, even if you make the same API request multiple times. This is particularly useful for:
  • Preventing duplicate emails when network issues cause retries
  • Safely retrying failed API calls without worrying about side effects
  • Maintaining data consistency during system outages or timeouts
For POST requests, include an Idempotency-Key header with a unique value:
curl -X POST "https://brew.new/api/send/transactional" \
  -H "Authorization: Bearer brew_YOUR_API_KEY" \
  -H "Idempotency-Key: unique-request-id-123" \
  -H "Content-Type: application/json" \
  -d '{
    "chatId": "YOUR_TEMPLATE_ID",
    "to": "user@example.com",
    "variables": { "firstName": "John" }
  }'

How Idempotency Works

  1. When you include an idempotency key with a request, Brew checks if it’s seen this key before
  2. If this is the first time seeing the key, Brew processes the request normally
  3. If the key was used in the last 24 hours, Brew returns the same response as the original request without performing the operation again

Best Practices

  • Use a unique identifier for each distinct operation (UUID is recommended)
  • Reuse the same key when retrying the exact same request
  • Keys can be up to 100 characters in length
  • Consider structuring keys that relate to your business logic (e.g., welcome-email/user-123)
  • Keys expire after 24 hours, after which they can be reused
If you send a different request body with a previously used idempotency key, you’ll receive an error. Each key must be associated with exactly one set of request parameters.

OpenAPI Specification

Get started quickly with the Brew API using our OpenAPI documents. Import these into API clients like Postman or Insomnia to explore all endpoints with example requests and responses.
Recommended tools: Import our OpenAPI spec into Postman or Insomnia for easy testing and debugging.

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.