Skip to main content
Documentation

API Reference

API v1

CoffeeMail exposes a public REST API for integration via API Key. This reference covers only Product routes (/v1/product/*) consumed by the Node SDK and external clients. Internal routes (Platform and Infrastructure) are not part of this public contract.

Scope of this reference

This page documents only the public Product routes (/v1/product/*) consumed by external clients via API Key. Internal Platform routes (/v1/platform/*, used by the dashboard via HttpOnly cookie) and Infrastructure routes (/v1/internal/*) are reserved and not part of this public contract.

Base URL

bashbash
https://api.coffeemail.com.br/v1/product

Authentication

All requests require a Bearer Token in the Authorization header. You can create and revoke API Keys in Dashboard → API Keys.

bashbash
curl https://api.coffeemail.com.br/v1/product/emails \  -H "Authorization: Bearer cm_live_sua_chave" \  -H "Content-Type: application/json" \  -H "Accept-Language: pt-BR"
Product keys (prefix cm_live_) and test keys (prefix cm_test_) are isolated — use cm_test_ keys in development to avoid consuming your quota.

Language

The API detects the language via the Accept-Language header. Supported values: pt-BR (default), en, es. Validation messages and error codes are localized.

Error shape

All error responses follow the same JSON envelope:

JSONjson
{  "error": {    "code": "VALIDATION_ERROR",    "message": "O campo 'from' deve ser um e-mail válido.",    "details": { "field": "from" }  }}

Rate limit

X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset headers are returned on every request. Limits are applied per API key and per IP. See the full table in Error Codes.

API endpoints

Emails

POST/emails202 Accepted

Send emails

Enqueues a transactional email. Accepts raw HTML, raw text, or a templateId + variables. Supports attachments (base64 string or Uint8Array), custom headers, scheduling (scheduledAt) and idempotency (idempotencyKey).

Request body

FieldTypeDescription
from*string | { email, name? }Sender (must be a verified domain).
to*string | string[] | { email, name? }[]A recipient or list.
subject*stringSubject.
htmlstringHTML content.
textstringPlain text fallback.
templateIdstringRenders an existing template.
variablesRecord<string, unknown>Variables for the template.
cc / bcc / replyToEmailAddressInputCc, Bcc and reply-to.
attachmentsEmailAttachment[]Attachments. content accepts base64 string or Uint8Array.
scheduledAtISO 8601 | DateScheduled send.
idempotencyKeystringPrevents duplication on retries.
tagsEmailTag[]Tags for metrics.
isSandboxbooleanDoes not actually send (simulation).

Attachment Rules & Limits

Supports up to 10 files per email with a cumulative size limit of 25 MB. Content must be Base64-encoded in the REST API (the Node SDK accepts Buffer directly). The cid field is mandatory for attachments with disposition 'inline'.

EmailAttachment Object Schema

FieldTypeDescription
filename*string (1-255)Filename with extension (e.g. invoice.pdf). Up to 255 characters.
content*string (Base64)Base64-encoded binary content.
contentType*string (MIME)MIME type (e.g. application/pdf, image/png). SDK default: application/octet-stream.
disposition*'attachment' | 'inline'Delivery mode: 'attachment' (standard download) or 'inline' (embedded inside the HTML body).
cidstring (opcional)Unique Content-ID used to reference inline images inside the HTML body (e.g. cid:logo referenced in img).

Request example

curl (básico)
curl -X POST https://api.coffeemail.com.br/v1/product/emails \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY" \  -H "Content-Type: application/json" \  -d '{    "from": "noreply@seudominio.com.br",    "to": ["cliente@example.com"],    "subject": "Confirmação do pedido #123",    "html": "<h1>Obrigado!</h1><p>Seu pedido está em processamento.</p>"  }'

Response

FieldTypeDescription
idstringUnique identifier of the email.
status'queued' | 'scheduled'Initial status after sending.
queuedAtstring (ISO 8601)Timestamp of queue entry.

Response example

JSONjson
{  "id": "eml_8f3a2c1b",  "status": "queued",  "queuedAt": "2026-09-10T18:21:14.000Z"}
GET/emails200 OK

List emails

Lists the organization's emails with cursor-based pagination. Accepts filters by status, recipient, sender, subject, tag, API key and time range.

Request body

FieldTypeDescription
status'queued' | 'processing' | 'sent' | 'delivered' | 'bounced' | 'complained' | 'failed' | 'skipped' | 'scheduled' | 'cancelled'Filters emails by delivery status.
recipientstringPartial search on recipient across to/cc/bcc.
fromEmailstringFilters emails by sender address.
subjectContainsstringPartial search on the email subject.
apiKeyIdstring (uuid)Filters emails sent by a specific API key.
tagstringFilters emails that have this tag.
fromstring (ISO 8601)Start date/time of the search range.
tostring (ISO 8601)End date/time of the search range.
afterstring (ISO 8601)Pagination cursor to fetch the next records.
limitnumberMaximum number of emails returned (default 50, max 100).

Request example

curl
curl "https://api.coffeemail.com.br/v1/product/emails?status=delivered&limit=20" \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"

Response

FieldTypeDescription
emailsEmailResponse[]List of returned emails.
nextCursorstring | nullCursor to fetch the next page, or null if there are no more records.

Response example

JSONjson
{  "emails": [    {      "id": "5b3f9e2a-6c1d-4e8a-9f0b-2a1c3d4e5f6a",      "from": "noreply@seudominio.com.br",      "to": ["cliente@example.com"],      "cc": null,      "bcc": null,      "subject": "Confirmação do pedido #123",      "status": "delivered",      "attempts": 1,      "lastError": null,      "messageId": "<abc123@coffeemail.com.br>",      "apiKey": { "id": "9c1a2b3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d", "name": "chave-producao" },      "createdAt": "2026-09-10T18:21:14.000Z",      "scheduledAt": null,      "sentAt": "2026-09-10T18:21:16.000Z",      "deliveredAt": "2026-09-10T18:21:20.000Z",      "bouncedAt": null,      "failedAt": null,      "complainedAt": null,      "suppressedAt": null,      "openedAt": null,      "firstClickedAt": null,      "openCount": 0,      "clickCount": 0,      "tags": [{ "name": "order_id", "value": "123" }],      "html": "<h1>Obrigado!</h1>",      "text": null    }  ],  "nextCursor": null}
POST/emails/batch202 Accepted

Send emails in batch

Sends up to 100 emails in a single call. Each item follows the same format as a single send (from, to, subject/html/text or templateId, etc). Individual item failures do not fail the whole batch.

Request body

FieldTypeDescription
(array)*SendEmailRequest[]Array of 1 to 100 send payloads, in the same format as POST /emails.

Request example

curl
curl -X POST https://api.coffeemail.com.br/v1/product/emails/batch \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY" \  -H "Content-Type: application/json" \  -d '[    {      "from": "noreply@seudominio.com.br",      "to": ["cliente1@example.com"],      "subject": "Pedido #123 confirmado",      "html": "<p>Seu pedido foi confirmado.</p>"    },    {      "from": "noreply@seudominio.com.br",      "to": ["cliente2@example.com"],      "subject": "Pedido #124 confirmado",      "html": "<p>Seu pedido foi confirmado.</p>"    }  ]'

Response

FieldTypeDescription
[].okbooleanIndicates whether the item was accepted successfully.
[].data.idstringUnique identifier of the created email (when ok is true).
[].data.status'queued' | 'scheduled'Initial status of the email after sending (when ok is true).
[].data.queuedAtstring (ISO 8601)Timestamp of queue entry (when ok is true).
[].errorstringError message for the item that failed (when ok is false).

Response example

JSONjson
[  {    "ok": true,    "data": {      "id": "5b3f9e2a-6c1d-4e8a-9f0b-2a1c3d4e5f6a",      "status": "queued",      "queuedAt": "2026-09-10T18:21:14.000Z"    }  },  {    "ok": false,    "error": "domain not verified"  }]
GET/emails/tags200 OK

List used tags

Returns the distinct tags already used across the organization's sent emails, along with the recorded values for each one. Useful for populating filters in the UI.

Request example

curl
curl https://api.coffeemail.com.br/v1/product/emails/tags \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"

Response

FieldTypeDescription
tags{ name, values }[]Distinct tags used across emails, each with its already recorded values.

Response example

JSONjson
{  "tags": [    { "name": "order_id", "values": ["123", "124"] },    { "name": "campaign", "values": ["black-friday"] }  ]}
GET/emails/:id200 OK

Get email by ID

Returns the full details of an email: status, attempts, lifecycle timestamps, tags, body (html/text) and the API key used to send it.

Request example

curl
curl https://api.coffeemail.com.br/v1/product/emails/5b3f9e2a-6c1d-4e8a-9f0b-2a1c3d4e5f6a \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"

Response

FieldTypeDescription
idstring (uuid)Unique ID of the email.
fromstringSender address.
tostring[]List of recipients.
cc / bccstring[] | nullList of cc and bcc recipients.
subjectstring | nullEmail subject.
status'queued' | 'processing' | 'sent' | 'delivered' | 'bounced' | 'failed' | 'skipped' | 'scheduled' | 'cancelled'Current delivery status.
attemptsnumberNumber of send attempts made.
lastErrorstring | nullLast error message recorded for the send.
messageIdstring | nullMessage ID returned by the sending provider.
createdAt / scheduledAt / sentAtstring (ISO 8601) | nullCreation, scheduling and sending date/time of the email.
deliveredAt / bouncedAt / failedAt / complainedAt / suppressedAtstring (ISO 8601) | nullDelivery, bounce, failure or spam complaint date/time, if any.
openedAt / firstClickedAtstring (ISO 8601) | nullDate/time of the first open and the first link click.
openCount / clickCountnumberNumber of opens and clicks recorded.
tags{ name, value }[] | nullTags associated with the email.
html / textstring | nullEmail body in HTML and plain text.
apiKey{ id, name } | nullAPI key used to send the email.

Response example

JSONjson
{  "id": "5b3f9e2a-6c1d-4e8a-9f0b-2a1c3d4e5f6a",  "from": "noreply@seudominio.com.br",  "to": ["cliente@example.com"],  "cc": null,  "bcc": null,  "subject": "Confirmação do pedido #123",  "status": "delivered",  "attempts": 1,  "lastError": null,  "messageId": "<abc123@coffeemail.com.br>",  "createdAt": "2026-09-10T18:21:14.000Z",  "scheduledAt": null,  "sentAt": "2026-09-10T18:21:16.000Z",  "deliveredAt": "2026-09-10T18:21:20.000Z",  "bouncedAt": null,  "failedAt": null,  "complainedAt": null,  "suppressedAt": null,  "openedAt": null,  "firstClickedAt": null,  "openCount": 0,  "clickCount": 0,  "tags": [{ "name": "order_id", "value": "123" }],  "html": "<h1>Obrigado!</h1>",  "text": null,  "apiKey": { "id": "9c1a2b3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d", "name": "chave-producao" }}
GET/emails/:id/events200 OK

Event timeline

Returns the event history of an email (queued, processing, sent, delivered, opened, clicked, bounced, complained, failed), in chronological order.

Request example

curl
curl https://api.coffeemail.com.br/v1/product/emails/5b3f9e2a-6c1d-4e8a-9f0b-2a1c3d4e5f6a/events \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"

Response

FieldTypeDescription
idstring (uuid)Unique ID of the email.
events{ type, timestamp, metadata? }[]Timeline of the email's events, each with type, timestamp and optional metadata.

Response example

JSONjson
{  "id": "5b3f9e2a-6c1d-4e8a-9f0b-2a1c3d4e5f6a",  "events": [    { "type": "queued", "timestamp": "2026-09-10T18:21:14.000Z" },    { "type": "sent", "timestamp": "2026-09-10T18:21:16.000Z" },    { "type": "delivered", "timestamp": "2026-09-10T18:21:20.000Z" },    { "type": "opened", "timestamp": "2026-09-10T18:25:02.000Z", "metadata": { "userAgent": "Mozilla/5.0" } }  ]}
POST/emails/:id/cancel204 No Content

Cancel scheduled email

Cancels an email that is still in scheduled status. Has no effect on emails that already entered processing or were sent. Returns no body.

Request example

curl
curl -X POST https://api.coffeemail.com.br/v1/product/emails/5b3f9e2a-6c1d-4e8a-9f0b-2a1c3d4e5f6a/cancel \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"
POST/emails/:id/resend202 Accepted

Resend email

Re-queues an email that failed or was cancelled, creating a new send cycle.

Request example

curl
curl -X POST https://api.coffeemail.com.br/v1/product/emails/5b3f9e2a-6c1d-4e8a-9f0b-2a1c3d4e5f6a/resend \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"

Response

FieldTypeDescription
idstringUnique identifier of the new send.
status'queued' | 'scheduled'Initial status of the email after resending.
queuedAtstring (ISO 8601)Timestamp of queue entry.

Response example

JSONjson
{  "id": "7d4a1e2b-8c3f-4a5b-9c6d-1e2f3a4b5c6d",  "status": "queued",  "queuedAt": "2026-09-10T19:02:31.000Z"}

Domains

POST/domains201 Created

Add domain

Registers a domain in the organization and returns the DNS records (SPF, DKIM, DMARC and ownership) that need to be configured in the provider.

Request body

FieldTypeDescription
name*stringFQDN to be registered (e.g. company.com).

Request example

curl
curl -X POST https://api.coffeemail.com.br/v1/product/domains \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY" \  -H "Content-Type: application/json" \  -d '{ "name": "empresa.com.br" }'

Response

FieldTypeDescription
idstringDomain ID.
namestringDomain name.
status'verified' | 'pending' | 'failed'Validation status.
recordsDomainDnsRecord[]SPF/DKIM/DMARC/ownership.
POST/domains/:id/verify202 Accepted

Verify domain

Runs on-demand verification of DNS records. Returns detailed checks (spf, dkim, dmarc, ownership).

Request example

curl
curl -X POST https://api.coffeemail.com.br/v1/product/domains/dom_123/verify \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"
POST/domains/:id/health200 OK

Domain health

Reputation diagnostic, blacklist presence, and improvement recommendations.

Request example

curl
curl -X POST https://api.coffeemail.com.br/v1/product/domains/dom_123/health \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"
GET/domains200 OK

List domains

Lists all domains registered under the organization, with verification status and DKIM data.

Request example

curl
curl https://api.coffeemail.com.br/v1/product/domains \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"

Response

FieldTypeDescription
domainsDomainListItem[]List of domains registered under the organization.
domains[].idstring (uuid)Domain unique identifier.
domains[].namestringRegistered domain name.
domains[].status'pending' | 'verified' | 'failed'Current verification status of the domain.
domains[].dkimSelectorstringSelector used in the domain's DKIM record.
domains[].dkimPublicKeystring | nullDKIM public key generated for the domain.
domains[].verifiedAtstring (ISO 8601) | nullDate and time the domain was verified.
domains[].lastCheckAtstring (ISO 8601) | nullDate and time of the last DNS check performed.
domains[].createdAtstring (ISO 8601)Date and time the domain was registered.

Response example

JSONjson
{  "domains": [    {      "id": "5e2f1a3c-9b7d-4e6a-8c1f-2d3b4a5e6f7a",      "name": "empresa.com.br",      "status": "verified",      "dkimSelector": "cm2026",      "dkimPublicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC...",      "verifiedAt": "2026-08-20T14:03:11.000Z",      "lastCheckAt": "2026-09-09T09:12:00.000Z",      "createdAt": "2026-08-19T10:00:00.000Z"    }  ]}
GET/domains/:id200 OK

Get domain

Returns the detail of a domain, including the pending DNS records (TXT/CNAME) that still need to be published.

Request example

curl
curl https://api.coffeemail.com.br/v1/product/domains/dom_123 \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"

Response

FieldTypeDescription
idstring (uuid)Domain unique identifier.
namestringRegistered domain name.
status'pending' | 'verified' | 'failed'Current verification status of the domain.
dkimSelectorstringSelector used in the domain's DKIM record.
dkimPublicKeystring | nullDKIM public key generated for the domain.
verifiedAtstring (ISO 8601) | nullDate and time the domain was verified.
lastCheckAtstring (ISO 8601) | nullDate and time of the last DNS check performed.
createdAtstring (ISO 8601)Date and time the domain was registered.
dnsRecordsToPublishDnsRecord[]Pending DNS records the client needs to publish.
dnsRecordsToPublish[].type'TXT' | 'CNAME'Type of DNS record to publish (TXT or CNAME).
dnsRecordsToPublish[].hoststringHost/subdomain name where the record should be created.
dnsRecordsToPublish[].valuestringValue that must be published in the DNS record.
dnsRecordsToPublish[].ttlnumberSuggested TTL in seconds for the record.

Response example

JSONjson
{  "id": "5e2f1a3c-9b7d-4e6a-8c1f-2d3b4a5e6f7a",  "name": "empresa.com.br",  "status": "pending",  "dkimSelector": "cm2026",  "dkimPublicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC...",  "verifiedAt": null,  "lastCheckAt": "2026-09-09T09:12:00.000Z",  "createdAt": "2026-08-19T10:00:00.000Z",  "dnsRecordsToPublish": [    {      "type": "TXT",      "host": "_coffeemail.empresa.com.br",      "value": "coffeemail-site-verification=abc123",      "ttl": 3600    },    {      "type": "CNAME",      "host": "cm2026._domainkey.empresa.com.br",      "value": "cm2026.dkim.coffeemail.com.br"    }  ]}
DELETE/domains/:id200 OK

Delete domain

Soft-deletes a domain from the organization. If the account has reauthentication configured, method + credential must be sent; rate-limited to 5 requests per minute.

Request body

FieldTypeDescription
method'totp' | 'password'Reauthentication method, 'totp' or 'password'. Required only if the account has reauth configured.
credentialstringTOTP code or password used to confirm the deletion.

Request example

curl
curl -X DELETE https://api.coffeemail.com.br/v1/product/domains/dom_123 \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY" \  -H "Content-Type: application/json" \  -d '{ "method": "totp", "credential": "123456" }'

Response

FieldTypeDescription
okbooleanConfirms that the domain was removed.

Response example

JSONjson
{  "ok": true}
GET/domains/:id/warmup200 OK

Warmup status

Checks the progress of IP/domain warmup. Returns null when the domain has not started warmup yet.

Request example

curl
curl https://api.coffeemail.com.br/v1/product/domains/dom_123/warmup \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"

Response

FieldTypeDescription
domainIdstring (uuid)Domain unique identifier.
currentDaynumberCurrent day of the warmup period.
dailyQuotanumberDaily sending limit allowed for the current day.
sentTodaynumberNumber of emails already sent today.
remainingTodaynumberNumber of sends remaining in the daily quota.
quotaUsedPercentnumber (0-100)Percentage of the daily quota already used.
lastSendDatestring | nullDate of the last recorded send for the domain.

Response example

JSONjson
{  "domainId": "5e2f1a3c-9b7d-4e6a-8c1f-2d3b4a5e6f7a",  "currentDay": 4,  "dailyQuota": 500,  "sentToday": 120,  "remainingToday": 380,  "quotaUsedPercent": 24,  "lastSendDate": "2026-09-10"}

Templates

POST/templates201 Created

Create template

Registers a template. Supports Handlebars HTML (format: handlebars) or React Email TSX (format: react_email).

Request body

FieldTypeDescription
name*stringTemplate name.
subjectstringDefault subject.
htmlstringContent (Handlebars).
textstringPlain text version.
format'handlebars' | 'react_email'Template engine.
variables{ name, defaultValue? }[]Expected variables.

Request example

curl
curl -X POST https://api.coffeemail.com.br/v1/product/templates \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY" \  -H "Content-Type: application/json" \  -d '{    "name": "Boas-vindas",    "subject": "Bem-vindo, {{ name }}!",    "html": "<h1>Oi {{ name }}</h1>",    "format": "handlebars",    "variables": [{ "name": "name", "defaultValue": "" }]  }'
POST/templates/preview200 OK

Render preview

Renders a preview without sending — useful for the playground and variable validation.

Request example

curl
curl -X POST https://api.coffeemail.com.br/v1/product/templates/preview \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY" \  -H "Content-Type: application/json" \  -d '{ "html": "<h1>Oi {{ name }}</h1>", "format": "html", "variables": { "name": "Maria" } }'
GET/templates200 OK

List templates

Returns every template registered for the organisation, including the full source of each one.

Request example

curl
curl https://api.coffeemail.com.br/v1/product/templates \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"

Response

FieldTypeDescription
dataTemplateDetail[]List of registered email templates.
data[].idstring (uuid)Unique identifier of the template.
data[].namestringTemplate name.
data[].subjectstring | nullDefault email subject.
data[].htmlstringHTML or JSX source of the template.
data[].textPayloadstring | nullPlain-text version of the template.
data[].variables{ name, description? }[]Variables available for interpolation in the template.
data[].isActivebooleanWhether the template is active for use.
data[].format'html' | 'react'Format of the template source.
data[].sourceLocalestringSource language of the template content.
data[].starterSlugstring | nullSlug of the starter template used as a base, if any.
data[].createdAtstring (ISO 8601)Template creation date.
data[].updatedAtstring (ISO 8601)Date of the last template update.

Response example

JSONjson
{  "data": [    {      "id": "3f9a2c1b-6e2d-4b3a-9c5f-1a2b3c4d5e6f",      "name": "Boas-vindas",      "subject": "Bem-vindo, {{ name }}!",      "html": "<h1>Oi {{ name }}</h1>",      "textPayload": null,      "variables": [{ "name": "name", "description": "Nome do destinatário" }],      "isActive": true,      "format": "html",      "sourceLocale": "pt-BR",      "starterSlug": null,      "createdAt": "2026-08-01T12:00:00.000Z",      "updatedAt": "2026-08-01T12:00:00.000Z"    }  ]}
GET/templates/:id200 OK

Get template

Returns a single template by id, including the full source and available variables.

Request example

curl
curl https://api.coffeemail.com.br/v1/product/templates/3f9a2c1b-6e2d-4b3a-9c5f-1a2b3c4d5e6f \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"

Response

FieldTypeDescription
idstring (uuid)Unique identifier of the template.
namestringTemplate name.
subjectstring | nullDefault email subject.
htmlstringHTML or JSX source of the template.
textPayloadstring | nullPlain-text version of the template.
variables{ name, description? }[]Variables available for interpolation in the template.
isActivebooleanWhether the template is active for use.
format'html' | 'react'Format of the template source.
sourceLocalestringSource language of the template content.
starterSlugstring | nullSlug of the starter template used as a base, if any.
createdAtstring (ISO 8601)Template creation date.
updatedAtstring (ISO 8601)Date of the last template update.

Response example

JSONjson
{  "id": "3f9a2c1b-6e2d-4b3a-9c5f-1a2b3c4d5e6f",  "name": "Boas-vindas",  "subject": "Bem-vindo, {{ name }}!",  "html": "<h1>Oi {{ name }}</h1>",  "textPayload": null,  "variables": [{ "name": "name", "description": "Nome do destinatário" }],  "isActive": true,  "format": "html",  "sourceLocale": "pt-BR",  "starterSlug": null,  "createdAt": "2026-08-01T12:00:00.000Z",  "updatedAt": "2026-08-01T12:00:00.000Z"}
PATCH/templates/:id200 OK

Update template

Partially updates an existing template. Send only the fields you want to change.

Request body

FieldTypeDescription
namestringNew template name.
subjectstring | nullNew default email subject.
htmlstringNew HTML or JSX source.
textPayloadstring | nullNew plain-text version.
variables{ name, description? }[]New list of variables available for interpolation.
format'html' | 'react'New format of the source code.
isActivebooleanEnables or disables the template.
sourceLocalestringNew source language of the content.
starterSlugstring | nullSlug of the starter template used as a base.

Request example

curl
curl -X PATCH https://api.coffeemail.com.br/v1/product/templates/3f9a2c1b-6e2d-4b3a-9c5f-1a2b3c4d5e6f \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY" \  -H "Content-Type: application/json" \  -d '{ "isActive": false }'

Response

FieldTypeDescription
idstring (uuid)Unique identifier of the template.
namestringTemplate name.
isActivebooleanWhether the template is active for use.
updatedAtstring (ISO 8601)Date of the last template update.

Response example

JSONjson
{  "id": "3f9a2c1b-6e2d-4b3a-9c5f-1a2b3c4d5e6f",  "name": "Boas-vindas",  "subject": "Bem-vindo, {{ name }}!",  "html": "<h1>Oi {{ name }}</h1>",  "textPayload": null,  "variables": [{ "name": "name", "description": "Nome do destinatário" }],  "isActive": false,  "format": "html",  "sourceLocale": "pt-BR",  "starterSlug": null,  "createdAt": "2026-08-01T12:00:00.000Z",  "updatedAt": "2026-09-10T09:30:00.000Z"}
DELETE/templates/:id204 No Content

Delete template

Permanently removes a template. This action cannot be undone.

Request example

curl
curl -X DELETE https://api.coffeemail.com.br/v1/product/templates/3f9a2c1b-6e2d-4b3a-9c5f-1a2b3c4d5e6f \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"
POST/templates/format200 OK

Format template

Formats a template's source code (HTML or JSX) via Prettier, without persisting anything.

Request body

FieldTypeDescription
html*stringHTML or JSX source to format.
format'html' | 'react'Format of the source code.

Request example

curl
curl -X POST https://api.coffeemail.com.br/v1/product/templates/format \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY" \  -H "Content-Type: application/json" \  -d '{ "html": "<h1>Oi   {{name}}</h1>", "format": "html" }'

Response

FieldTypeDescription
htmlstringFormatted source code.

Response example

JSONjson
{  "html": "<h1>Oi {{ name }}</h1>\n"}
POST/templates/test-render200 OK

Sanitized test render

Renders a template with variables and sanitizes the resulting HTML (strips scripts, iframes, javascript: links and inline event handlers). Unlike /templates/preview, which does not sanitize — use this endpoint to test untrusted content.

Request body

FieldTypeDescription
html*stringHTML or JSX source of the template to render.
format'html' | 'react'Format of the source template.
variablesRecord<string, unknown>Variable values used to populate the template.

Request example

curl
curl -X POST https://api.coffeemail.com.br/v1/product/templates/test-render \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY" \  -H "Content-Type: application/json" \  -d '{ "html": "<h1>Oi {{ name }}</h1><script>alert(1)</script>", "format": "html", "variables": { "name": "Maria" } }'

Response

FieldTypeDescription
htmlstringFinal rendered and sanitized HTML.
textstringPlain-text version of the rendered email.
sanitizeReport{ scripts, iframes, javascriptHrefs, eventHandlers }Report with the number of elements removed by sanitization (scripts, iframes, javascript: links and event handlers).

Response example

JSONjson
{  "html": "<h1>Oi Maria</h1>",  "text": "Oi Maria",  "sanitizeReport": {    "scripts": 1,    "iframes": 0,    "javascriptHrefs": 0,    "eventHandlers": 0  }}

Audiences and contacts

POST/audiences201 Created

Create audience

Creates a segmented contact list.

Request example

curl
curl -X POST https://api.coffeemail.com.br/v1/product/audiences \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY" \  -H "Content-Type: application/json" \  -d '{ "name": "Newsletter PT", "description": "Leads do blog BR" }'
POST/audiences/:id/contacts201 Created

Add contact

Inserts a contact into an audience. Accepts firstName, lastName and arbitrary metadata.

Request example

curl
curl -X POST https://api.coffeemail.com.br/v1/product/audiences/aud_123/contacts \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY" \  -H "Content-Type: application/json" \  -d '{ "email": "maria@example.com", "firstName": "Maria", "metadata": { "plan": "pro" } }'
GET/audiences200 OK

List audiences

Lists the organization's audiences, with pagination.

Request body

FieldTypeDescription
limitnumberMaximum number of items per page (default 50, max 200).
offsetnumberNumber of items to skip from the start (default 0).

Request example

curl
curl "https://api.coffeemail.com.br/v1/product/audiences?limit=50&offset=0" \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"

Response

FieldTypeDescription
audiencesAudience[]List of audiences found.
totalnumberTotal number of audiences in the organization.

Response example

JSONjson
{  "audiences": [    {      "id": "aud_123",      "name": "Newsletter PT",      "description": "Leads do blog BR",      "active": true,      "contactsCount": 0,      "createdAt": "2026-09-01T12:00:00.000Z",      "updatedAt": "2026-09-01T12:00:00.000Z"    }  ],  "total": 1}
GET/audiences/:id200 OK

Get audience

Returns the data for a specific audience.

Request example

curl
curl https://api.coffeemail.com.br/v1/product/audiences/aud_123 \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"

Response

FieldTypeDescription
idstringUnique identifier of the audience.
namestringAudience name.
descriptionstring | nullAudience description.
activebooleanWhether the audience is active.
contactsCountnumberNumber of contacts in the audience.
createdAtstring (ISO 8601)Audience creation date.
updatedAtstring (ISO 8601)Date of the audience's last update.

Response example

JSONjson
{  "id": "aud_123",  "name": "Newsletter PT",  "description": "Leads do blog BR",  "active": true,  "contactsCount": 42,  "createdAt": "2026-09-01T12:00:00.000Z",  "updatedAt": "2026-09-05T09:30:00.000Z"}
PUT/audiences/:id200 OK

Update audience

Updates the name, description, and/or status of an audience. At least one field must be sent.

Request body

FieldTypeDescription
namestringNew audience name.
descriptionstring | nullNew audience description. Send null to clear it.
activebooleanWhether the audience is active.

Request example

curl
curl -X PUT https://api.coffeemail.com.br/v1/product/audiences/aud_123 \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY" \  -H "Content-Type: application/json" \  -d '{ "name": "Newsletter PT-BR", "active": false }'

Response

FieldTypeDescription
idstringUnique identifier of the updated audience.

Response example

JSONjson
{  "id": "aud_123"}
DELETE/audiences/:id204 No Content

Delete audience

Permanently removes an audience and its contacts. Returns no response body.

Request example

curl
curl -X DELETE https://api.coffeemail.com.br/v1/product/audiences/aud_123 \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"
GET/audiences/:id/contacts200 OK

List audience contacts

Lists the contacts in an audience, with pagination.

Request body

FieldTypeDescription
limitnumberMaximum number of items per page (default 100, max 500).
offsetnumberNumber of items to skip from the start (default 0).

Request example

curl
curl "https://api.coffeemail.com.br/v1/product/audiences/aud_123/contacts?limit=100&offset=0" \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"

Response

FieldTypeDescription
contactsContact[]List of contacts found.
totalnumberTotal number of contacts in the audience.

Response example

JSONjson
{  "contacts": [    {      "id": "cnt_123",      "email": "maria@example.com",      "firstName": "Maria",      "lastName": null,      "metadata": { "plan": "pro" },      "createdAt": "2026-09-01T12:00:00.000Z"    }  ],  "total": 1}
POST/audiences/:id/contacts/bulk200 OK

Bulk add contacts

Adds up to 10,000 contacts at once to an audience.

Request body

FieldTypeDescription
contacts*{ email, firstName?, lastName?, metadata? }[]List of contacts to add (email required; firstName, lastName, and metadata optional).

Request example

curl
curl -X POST https://api.coffeemail.com.br/v1/product/audiences/aud_123/contacts/bulk \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY" \  -H "Content-Type: application/json" \  -d '{    "contacts": [      { "email": "maria@example.com", "firstName": "Maria" },      { "email": "joao@example.com", "firstName": "João", "metadata": { "plan": "free" } }    ]  }'

Response

FieldTypeDescription
insertednumberNumber of contacts successfully inserted.
skippednumberNumber of contacts skipped (e.g. duplicate emails within the audience).
errors{ email, reason }[]List of per-email errors, with the reason for each failure.

Response example

JSONjson
{  "inserted": 1,  "skipped": 1,  "errors": [    { "email": "joao@example.com", "reason": "duplicate email in audience" }  ]}
PUT/audiences/:id/contacts/:contactId200 OK

Update contact

Updates firstName, lastName, and/or metadata for a contact. At least one field must be sent.

Request body

FieldTypeDescription
firstNamestring | nullNew first name for the contact. Send null to clear it.
lastNamestring | nullNew last name for the contact. Send null to clear it.
metadataRecord<string, unknown>Free-form extra data for the contact.

Request example

curl
curl -X PUT https://api.coffeemail.com.br/v1/product/audiences/aud_123/contacts/cnt_123 \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY" \  -H "Content-Type: application/json" \  -d '{ "firstName": "Maria", "metadata": { "plan": "enterprise" } }'

Response

FieldTypeDescription
idstringUnique identifier of the updated contact.

Response example

JSONjson
{  "id": "cnt_123"}
DELETE/audiences/:id/contacts/:contactId204 No Content

Remove contact

Removes a contact from an audience. Returns no response body.

Request example

curl
curl -X DELETE https://api.coffeemail.com.br/v1/product/audiences/aud_123/contacts/cnt_123 \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"

Campaigns (broadcasts)

POST/broadcasts201 Created

Create campaign

Creates a campaign for an audience. Can use an existing template (templateId) or own HTML. Accepts scheduling via scheduledAt.

Request example

curl
curl -X POST https://api.coffeemail.com.br/v1/product/broadcasts \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY" \  -H "Content-Type: application/json" \  -d '{    "audienceId": "aud_123",    "fromEmail": "news@seudominio.com.br",    "subject": "Novidades da semana",    "templateId": "tpl_123"  }'
POST/broadcasts/:id/send202 Accepted

Send campaign

Sets the campaign to sending state. RFC 8058 headers (List-Unsubscribe and List-Unsubscribe-Post) are injected automatically.

Request example

curl
curl -X POST https://api.coffeemail.com.br/v1/product/broadcasts/bc_123/send \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"
GET/broadcasts200 OK

List campaigns

Lists the organization's broadcast campaigns. Filters by status and date range, with cursor pagination.

Request body

FieldTypeDescription
status'draft' | 'scheduled' | 'sending' | 'sent' | 'failed' | 'cancelled'Filters by broadcast status.
fromstring (ISO 8601)Start of the search date range.
tostring (ISO 8601)End of the search date range.
afterstringPagination cursor returned by a previous call.
limitnumber (max 200)Maximum number of broadcasts returned per page.

Request example

curl
curl "https://api.coffeemail.com.br/v1/product/broadcasts?status=sent&limit=20" \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"

Response

FieldTypeDescription
broadcastsBroadcast[]List of broadcasts on the current page.
nextCursorstring | nullCursor to fetch the next page, or null if there are no more results.

Response example

JSONjson
{  "broadcasts": [    {      "id": "bc_123",      "audienceId": "aud_123",      "audienceName": "Newsletter PT",      "templateId": "tpl_123",      "subject": "Novidades da semana",      "fromEmail": "news@seudominio.com.br",      "replyTo": null,      "status": "sent",      "scheduledAt": null,      "sentAt": "2026-09-09T13:00:00.000Z",      "cancelledAt": null,      "recipientsTotal": 4820,      "recipientsQueued": 4820,      "recipientsFailed": 12,      "createdAt": "2026-09-08T18:21:14.000Z",      "updatedAt": "2026-09-09T13:00:00.000Z"    }  ],  "nextCursor": null}
GET/broadcasts/:id200 OK

Get campaign

Returns the full data for a specific campaign, including status and recipient counters.

Request example

curl
curl https://api.coffeemail.com.br/v1/product/broadcasts/bc_123 \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"

Response

FieldTypeDescription
idstringUnique identifier of the broadcast.
audienceIdstringIdentifier of the target audience.
audienceNamestring | nullName of the target audience.
templateIdstring | nullIdentifier of the template used in the send, if any.
subjectstringEmail subject.
fromEmailstringSender email address.
replyTostring | nullReply-to email address.
status'draft' | 'scheduled' | 'sending' | 'sent' | 'failed' | 'cancelled'Current status of the broadcast.
scheduledAtstring (ISO 8601) | nullDate and time scheduled for the send.
sentAtstring (ISO 8601) | nullDate and time the send completed.
cancelledAtstring (ISO 8601) | nullDate and time the broadcast was cancelled.
recipientsTotalnumberTotal number of recipients for the broadcast.
recipientsQueuednumberNumber of recipients queued for sending.
recipientsFailednumberNumber of recipients that failed to receive the send.
createdAtstring (ISO 8601)Date the broadcast was created.
updatedAtstring (ISO 8601)Date the broadcast was last updated.

Response example

JSONjson
{  "id": "bc_123",  "audienceId": "aud_123",  "audienceName": "Newsletter PT",  "templateId": "tpl_123",  "subject": "Novidades da semana",  "fromEmail": "news@seudominio.com.br",  "replyTo": null,  "status": "sending",  "scheduledAt": null,  "sentAt": null,  "cancelledAt": null,  "recipientsTotal": 4820,  "recipientsQueued": 3110,  "recipientsFailed": 4,  "createdAt": "2026-09-08T18:21:14.000Z",  "updatedAt": "2026-09-10T12:05:41.000Z"}
POST/broadcasts/:id/cancel200 OK

Cancel campaign

Cancels a scheduled or in-progress broadcast. Emails already delivered are not affected.

Request example

curl
curl -X POST https://api.coffeemail.com.br/v1/product/broadcasts/bc_123/cancel \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"

Response

FieldTypeDescription
idstringUnique identifier of the broadcast.
status'cancelled'Broadcast status after cancellation.
cancelledAtstring (ISO 8601) | nullDate and time the broadcast was cancelled.

Response example

JSONjson
{  "id": "bc_123",  "status": "cancelled",  "cancelledAt": "2026-09-10T12:06:02.000Z"}

Suppressions

GET/suppressions200 OK

List suppressions

Lists active blocks (bounces, complaints, unsubscribes and manual).

Request example

curl
curl https://api.coffeemail.com.br/v1/product/suppressions \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"
POST/suppressions201 Created

Add suppression

Manually adds an email to the suppression list.

Request body

FieldTypeDescription
email*string (email)Email address to suppress.
reason'manual' | 'bounce' | 'complaint'Reason for the suppression. Only accepts 'manual', 'bounce', or 'complaint'.
expiresAtstring (ISO 8601)Date when the suppression expires and the email can receive sends again.

Request example

curl
curl -X POST https://api.coffeemail.com.br/v1/product/suppressions \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY" \  -H "Content-Type: application/json" \  -d '{    "email": "cliente@example.com",    "reason": "manual"  }'

Response

FieldTypeDescription
idstring (uuid)Unique identifier of the suppression.
emailstringSuppressed email address.
reason'manual' | 'bounce' | 'isp_block' | 'mailbox_not_found' | 'complaint' | 'unsubscribe'Reason that caused the suppression.
source'manual' | 'auto'Suppression origin: manual or automatic.
categorystringClassification category of the suppression.
status'active' | 'expired' | 'inactive'Current status of the suppression.
expiresAtstring (ISO 8601) | nullDate when the suppression expires and the email can receive sends again.
createdAtstring (ISO 8601)Date the suppression was created.

Response example

JSONjson
{  "id": "6f1a2b3c-4d5e-4f60-8a9b-0c1d2e3f4a5b",  "email": "cliente@example.com",  "reason": "manual",  "source": "manual",  "category": "manual",  "status": "active",  "expiresAt": null,  "createdAt": "2026-09-10T18:21:14.000Z"}
GET/suppressions/:id200 OK

Get suppression

Returns the details of a specific suppression by id.

Request example

curl
curl https://api.coffeemail.com.br/v1/product/suppressions/6f1a2b3c-4d5e-4f60-8a9b-0c1d2e3f4a5b \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"

Response

FieldTypeDescription
idstring (uuid)Unique identifier of the suppression.
emailstringSuppressed email address.
reason'manual' | 'bounce' | 'isp_block' | 'mailbox_not_found' | 'complaint' | 'unsubscribe'Reason that caused the suppression.
source'manual' | 'auto'Suppression origin: manual or automatic.
categorystringClassification category of the suppression.
status'active' | 'expired' | 'inactive'Current status of the suppression.
expiresAtstring (ISO 8601) | nullDate when the suppression expires and the email can receive sends again.
createdAtstring (ISO 8601)Date the suppression was created.

Response example

JSONjson
{  "id": "6f1a2b3c-4d5e-4f60-8a9b-0c1d2e3f4a5b",  "email": "cliente@example.com",  "reason": "bounce",  "source": "auto",  "category": "bounce",  "status": "active",  "expiresAt": null,  "createdAt": "2026-09-10T18:21:14.000Z"}
DELETE/suppressions/:id204 No Content

Remove suppression

Permanently removes a suppression from the list.

Request example

curl
curl -X DELETE https://api.coffeemail.com.br/v1/product/suppressions/6f1a2b3c-4d5e-4f60-8a9b-0c1d2e3f4a5b \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"
POST/suppressions/:id/reactivate204 No Content

Reactivate suppression

Undoes a suppression, allowing the email to receive sends again.

Request example

curl
curl -X POST https://api.coffeemail.com.br/v1/product/suppressions/6f1a2b3c-4d5e-4f60-8a9b-0c1d2e3f4a5b/reactivate \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"

Webhooks

POST/webhooks201 Created

Register webhook

Registers an HTTPS endpoint to receive events. We recommend providing a secret for HMAC SHA-256 validation.

Request body

FieldTypeDescription
url*string (HTTPS)Destination URL.
events*WebhookEventType[]Events to subscribe to (e.g. email.delivered).
secretstringSecret key for HMAC.

Request example

curl
curl -X POST https://api.coffeemail.com.br/v1/product/webhooks \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY" \  -H "Content-Type: application/json" \  -d '{    "url": "https://api.seusite.com.br/webhooks/coffeemail",    "events": ["email.delivered", "email.bounced", "email.complained"],    "secret": "whsec_meu_segredo"  }'
POST/webhooks/:id/test202 Accepted

Test webhook

Triggers a simulated event to validate the endpoint and configuration.

Request example

curl
curl -X POST https://api.coffeemail.com.br/v1/product/webhooks/wh_123/test \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"
GET/webhooks200 OK

List webhooks

Lists the webhooks registered for the organization, with an optional status filter.

Request body

FieldTypeDescription
status'active' | 'paused' | 'disabled'Filters webhooks by their current status (active, paused, or disabled).

Request example

curl
curl "https://api.coffeemail.com.br/v1/product/webhooks?status=active" \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"

Response

FieldTypeDescription
webhooksWebhookListItem[]List of webhooks registered for the organization.
webhooks[].idstring (uuid)Webhook identifier.
webhooks[].urlstringDestination URL that receives the events.
webhooks[].eventsstring[]Events the webhook is subscribed to.
webhooks[].status'active' | 'paused' | 'disabled'Current status of the webhook.
webhooks[].descriptionstring | nullUser-provided description for the webhook.
webhooks[].hasSecretbooleanWhether the webhook has a signing secret configured.
webhooks[].createdAtstring (ISO 8601)Date and time the webhook was created.

Response example

JSONjson
{  "webhooks": [    {      "id": "3d2f6a10-8b5e-4a2b-9c1d-7e6f5a4b3c2d",      "url": "https://api.seusite.com.br/webhooks/coffeemail",      "events": ["email.delivered", "email.bounced"],      "status": "active",      "description": "Webhook de produção",      "hasSecret": true,      "createdAt": "2026-08-01T12:00:00.000Z"    }  ]}
GET/webhooks/:id200 OK

Get webhook

Returns details for a specific webhook, including a truncated preview of the signing secret.

Request example

curl
curl https://api.coffeemail.com.br/v1/product/webhooks/3d2f6a10-8b5e-4a2b-9c1d-7e6f5a4b3c2d \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"

Response

FieldTypeDescription
idstring (uuid)Webhook identifier.
urlstringDestination URL that receives the events.
eventsstring[]Events the webhook is subscribed to.
status'active' | 'paused' | 'disabled'Current status of the webhook.
descriptionstring | nullUser-provided description for the webhook.
createdAtstring (ISO 8601)Date and time the webhook was created.
secretnullAlways null on this route — the full secret isn't re-exposed after creation.
secretPreviewstring | nullTruncated preview of the secret, for safe display.

Response example

JSONjson
{  "id": "3d2f6a10-8b5e-4a2b-9c1d-7e6f5a4b3c2d",  "url": "https://api.seusite.com.br/webhooks/coffeemail",  "events": ["email.delivered", "email.bounced"],  "status": "active",  "description": "Webhook de produção",  "createdAt": "2026-08-01T12:00:00.000Z",  "secret": null,  "secretPreview": "whsec_****3f2a"}
PUT/webhooks/:id200 OK

Update webhook

Updates url, events, and/or description on an existing webhook. At least one field must be sent.

Request body

FieldTypeDescription
urlstring (URL)New destination URL that will receive the events.
eventsWebhookEventType[]New events the webhook should subscribe to.
descriptionstring | nullNew description for the webhook (send null to clear it).

Request example

curl
curl -X PUT https://api.coffeemail.com.br/v1/product/webhooks/3d2f6a10-8b5e-4a2b-9c1d-7e6f5a4b3c2d \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY" \  -H "Content-Type: application/json" \  -d '{    "url": "https://api.seusite.com.br/webhooks/coffeemail-v2",    "events": ["email.delivered", "email.bounced", "email.complained"]  }'

Response

FieldTypeDescription
idstring (uuid)Webhook identifier.
urlstringDestination URL that receives the events.
eventsstring[]Events the webhook is subscribed to.
status'active' | 'paused' | 'disabled'Current status of the webhook.
descriptionstring | nullUser-provided description for the webhook.
createdAtstring (ISO 8601)Date and time the webhook was created.
secretnullAlways null on this route — the full secret isn't re-exposed after creation.
secretPreviewstring | nullTruncated preview of the secret, for safe display.

Response example

JSONjson
{  "id": "3d2f6a10-8b5e-4a2b-9c1d-7e6f5a4b3c2d",  "url": "https://api.seusite.com.br/webhooks/coffeemail-v2",  "events": ["email.delivered", "email.bounced", "email.complained"],  "status": "active",  "description": "Webhook de produção",  "createdAt": "2026-08-01T12:00:00.000Z",  "secret": null,  "secretPreview": "whsec_****3f2a"}
PATCH/webhooks/:id200 OK

Activate or pause webhook

Changes only the webhook's status (active or paused), without touching url, events, or description.

Request body

FieldTypeDescription
status*'active' | 'paused'New status for the webhook (active or paused).

Request example

curl
curl -X PATCH https://api.coffeemail.com.br/v1/product/webhooks/3d2f6a10-8b5e-4a2b-9c1d-7e6f5a4b3c2d \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY" \  -H "Content-Type: application/json" \  -d '{ "status": "paused" }'

Response

FieldTypeDescription
idstring (uuid)Webhook identifier.
status'active' | 'paused'New status applied to the webhook.

Response example

JSONjson
{  "id": "3d2f6a10-8b5e-4a2b-9c1d-7e6f5a4b3c2d",  "status": "paused"}
DELETE/webhooks/:id204 No Content

Delete webhook

Permanently removes the webhook from the organization. Returns no response body.

Request example

curl
curl -X DELETE https://api.coffeemail.com.br/v1/product/webhooks/3d2f6a10-8b5e-4a2b-9c1d-7e6f5a4b3c2d \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"
GET/webhooks/:id/deliveries200 OK

List webhook deliveries

Lists event delivery attempts for a webhook, with filters by event type, status, and time period.

Request body

FieldTypeDescription
eventTypestringFilters deliveries by event type.
status'pending' | 'success' | 'failed' | 'exhausted'Filters deliveries by their current status.
fromstring (ISO 8601)Start date of the search period.
tostring (ISO 8601)End date of the search period.
limitnumber (max 200)Maximum number of deliveries returned (up to 200).

Request example

curl
curl "https://api.coffeemail.com.br/v1/product/webhooks/3d2f6a10-8b5e-4a2b-9c1d-7e6f5a4b3c2d/deliveries?status=failed&limit=50" \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"

Response

FieldTypeDescription
deliveriesWebhookDelivery[]List of delivery attempts for the webhook.
deliveries[].idstring (uuid)Delivery attempt identifier.
deliveries[].webhookIdstring (uuid)Identifier of the associated webhook.
deliveries[].emailEventIdstring (uuid) | nullEmail event that triggered the delivery.
deliveries[].eventTypestringType of event fired (e.g. email.delivered).
deliveries[].responseStatusnumber | nullHTTP status returned by the destination endpoint.
deliveries[].responseBodystring | nullResponse body returned by the destination endpoint.
deliveries[].attemptsnumberNumber of delivery attempts made so far.
deliveries[].lastErrorstring | nullMessage from the last error encountered while sending.
deliveries[].status'pending' | 'success' | 'failed' | 'exhausted'Current delivery status.
deliveries[].nextRunAtstring (ISO 8601)Date and time of the next retry attempt.
deliveries[].createdAtstring (ISO 8601)Date and time the delivery was created.

Response example

JSONjson
{  "deliveries": [    {      "id": "9a1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d",      "webhookId": "3d2f6a10-8b5e-4a2b-9c1d-7e6f5a4b3c2d",      "emailEventId": "1f2e3d4c-5b6a-7c8d-9e0f-1a2b3c4d5e6f",      "eventType": "email.bounced",      "responseStatus": 500,      "responseBody": "Internal Server Error",      "attempts": 3,      "lastError": "connect ETIMEDOUT",      "status": "failed",      "nextRunAt": "2026-09-10T19:00:00.000Z",      "createdAt": "2026-09-10T18:00:00.000Z"    }  ]}
POST/webhooks/:id/rotate-secret200 OK

Rotate secret

Generates a new HMAC signing secret for the webhook, invalidating the previous one. The full value is returned only in this response.

Request example

curl
curl -X POST https://api.coffeemail.com.br/v1/product/webhooks/3d2f6a10-8b5e-4a2b-9c1d-7e6f5a4b3c2d/rotate-secret \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"

Response

FieldTypeDescription
webhookIdstring (uuid)Webhook identifier.
secretstringNew full secret, used to sign outgoing payloads — shown only once.

Response example

JSONjson
{  "webhookId": "3d2f6a10-8b5e-4a2b-9c1d-7e6f5a4b3c2d",  "secret": "9f8e7d6c5b4a3928f1e0d9c8b7a6958473625140f3e2d1c0b9a8f7e6d5c4b3a"}

Statistics

GET/stats200 OK

General metrics

Returns aggregated counters (sent, delivered, failed, bounced, complained, opened?, clicked?).

Request example

curl
curl "https://api.coffeemail.com.br/v1/product/stats?startDate=2026-09-01T00:00:00.000Z&endDate=2026-09-30T23:59:59.000Z&granularity=day" \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"

Senders

POST/senders201 Created

Create sender

Registers a single-email sender identity and triggers a verification email. The response includes a verificationToken, but the identity can't be used for sending until POST /senders/verify confirms the verification.

Request body

FieldTypeDescription
email*string (email)Sender email address to be verified.
displayNamestring (max 200)Sender display name.

Request example

curl
curl -X POST https://api.coffeemail.com.br/v1/product/senders \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY" \  -H "Content-Type: application/json" \  -d '{    "email": "vendas@seudominio.com.br",    "displayName": "Equipe de Vendas"  }'

Response

FieldTypeDescription
idstring (uuid)Unique sender identifier.
emailstringSender email address.
displayNamestring | nullSender display name.
verificationTokenstringToken sent to the email to confirm verification.
verifiedAtstring (ISO 8601) | nullDate/time the sender was verified.
activebooleanWhether the sender is active for sending.
createdAtstring (ISO 8601)Sender creation date/time.

Response example

JSONjson
{  "id": "b3f2a1c4-1234-4a5b-9c8d-1234567890ab",  "email": "vendas@seudominio.com.br",  "displayName": "Equipe de Vendas",  "verificationToken": "8e2f6a90-4b3c-4d5e-9f10-abcdef123456",  "verifiedAt": null,  "active": true,  "createdAt": "2026-09-10T18:21:14.000Z"}
GET/senders200 OK

List senders

Lists the single-email sender identities registered for the organisation.

Request example

curl
curl https://api.coffeemail.com.br/v1/product/senders \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"

Response

FieldTypeDescription
sendersSender[]List of the organisation's senders.

Response example

JSONjson
{  "senders": [    {      "id": "b3f2a1c4-1234-4a5b-9c8d-1234567890ab",      "email": "vendas@seudominio.com.br",      "displayName": "Equipe de Vendas",      "verifiedAt": "2026-09-10T18:25:02.000Z",      "active": true,      "createdAt": "2026-09-10T18:21:14.000Z"    }  ]}
POST/senders/verify200 OK

Verify sender

Confirms verification of a single-email sender using the token sent by email. Once verified, the address can be used in the "from" field of outgoing emails.

Request body

FieldTypeDescription
token*string (uuid)Verification token received by email.

Request example

curl
curl -X POST https://api.coffeemail.com.br/v1/product/senders/verify \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY" \  -H "Content-Type: application/json" \  -d '{ "token": "8e2f6a90-4b3c-4d5e-9f10-abcdef123456" }'

Response

FieldTypeDescription
idstring (uuid)Unique sender identifier.
emailstringSender email address.

Response example

JSONjson
{  "id": "b3f2a1c4-1234-4a5b-9c8d-1234567890ab",  "email": "vendas@seudominio.com.br"}
DELETE/senders/:id204 No Content

Delete sender

Removes a single-email sender identity from the organisation. Deletion is permanent and the address must be verified again if re-registered.

Request example

curl
curl -X DELETE https://api.coffeemail.com.br/v1/product/senders/send_123 \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY"