curl --request POST \
--url https://brew.new/api/v1/sends \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"test": true,
"emailId": "V1StGXR8_Z5jdHi6B-myT",
"subject": "Welcome to Brew",
"to": "qa@acme.com"
}
'{
"status": "completed",
"recipient": "qa@acme.com"
}Send an email
Sends an email design. Polymorphic on test: a campaign send mints a new Send (the unit of delivery and analytics) and delivers to a saved audience or an inline list through a verified domain; test: true delivers one synchronous QA copy to a single address and writes no send row.
Use when a design is ready to go out. For per-recipient event-driven delivery, publish an automation and fire its trigger (fireTrigger).
Input Campaign (test omitted or false): emailId (optionally pinned to emailVersionId), a verified domainId, subject, and exactly one of audienceId (a saved audience, or "all" for every contact in the brand) or to (one address or an array of up to 50). Optional from ({ email, name? }, an address on the send domain), previewText, replyTo, scheduledAt, gradualSend, and consent provenance (source, optional capturedAt, policyVersion, evidence) for inline recipients that are not yet contacts: each is created as a subscribed contact carrying that record. An existing opt-out is never re-subscribed. Inline recipients face the same unsubscribe and suppression gate and per-recipient quota as audience sends. Test (test: true): emailId, subject, one to address, optional emailVersionId, previewText, replyTo, domainId (a verified org-owned domain; otherwise the Brew default sender, and an unverified or foreign domain is rejected, never downgraded), from ({ email, name? }, an address on that domain), variables (example values for {{ var | fallback }} merge tags; a value wins over the fallback) and payload (template data; nested JSON renders via Liquid as trigger.*); the subject carries a [TEST] prefix. The same design can be sent unlimited times; every campaign call mints a new send.
Returns campaign 202 { status: 'queued' | 'scheduled', sendId, scheduledAt?, warnings? } (poll getSend; warnings[] carries one CONSENT_RECORD_MISSING per inline recipient that is a subscribed contact with no consent record); test 200 { status: 'completed', recipient }.
Errors 404 EMAIL_NOT_FOUND, DOMAIN_NOT_FOUND, AUDIENCE_NOT_FOUND (a resource in another brand also surfaces as 404); 422 EMAIL_NOT_READY, DOMAIN_NOT_READY, DOMAIN_PURPOSE_NOT_ALLOWED, LIQUID_RENDER_ERROR; 422 CONSENT_REQUIRED when an inline marketing recipient has no contact record with marketing consent and no consent was supplied (details.recipients); 422 RECIPIENT_UNSUBSCRIBED when an inline recipient is an existing contact who opted out (details.recipients, never re-subscribed); 402 SEND_QUOTA_EXCEEDED when the plan’s monthly volume would be exceeded (no Retry-After).
See also listSends, cancelSend, fireTrigger.
curl --request POST \
--url https://brew.new/api/v1/sends \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"test": true,
"emailId": "V1StGXR8_Z5jdHi6B-myT",
"subject": "Welcome to Brew",
"to": "qa@acme.com"
}
'{
"status": "completed",
"recipient": "qa@acme.com"
}Authorizations
Send your Brew API key as Authorization: Bearer brew_xxx.
Headers
Optional idempotency key for safe retries. Reusing the same key with the same request body returns the original response for 24 hours.
1 - 100The brand this request acts on. REQUIRED for organization-scoped credentials (otherwise 400 BRAND_ID_REQUIRED — there is no default brand); list ids with GET /v1/brands. Brand-scoped credentials may omit it, and sending a different brand returns 403 BRAND_SCOPE_MISMATCH. A brand outside your organization returns 404 BRAND_NOT_FOUND.
1 - 64Body
- Option 1
- Option 2
true 111Inbox preheader for this test send — overrides the design's JSX . Omit to deliver the design's own preview line.
200OPTIONAL verified sending domain for this test. Omit for the Brew default sender (hello@email.brew.new). Must be a verified domain owned by this org/brand — an unverified or foreign domain is rejected (404/422), never silently downgraded to the Brew default.
1Sender override { email, name? }; the address must be on the send domain. Omit to use the domain defaults.
Show child attributes
Show child attributes
Example values for {{ var | fallback }} merge tags in the subject, previewText, and body. A supplied value wins over contact fields and the declared fallback; undefined variables render their fallback (or empty). Max 25 entries; keys must match the merge-tag grammar (letter/_/$ start, then word chars/dots/$, max 64 chars); values max 256 chars.
Show child attributes
Show child attributes
Nested JSON template data, exposed to the ONE Liquid engine as trigger.* / payload.* and as top-level keys. Nested values are always legal and resolve via dotted access ({{ plan.name }}) and {% for %}. Flat variables resolve {{ tag | fallback }} merge tags at higher precedence; send both if a design mixes syntaxes.
Show child attributes
Show child attributes
Was this page helpful?