Quickstart
#quickstartGet to a working send in four steps — from a fresh deploy to a delivered email.
POST /v1/send with your key in the Authorization: Bearer header. Start with a test key and eftest_ prefix to skip Cloudflare credentials.Authentication
#authenticationAll /v1/send requests must include a bearer token in the Authorization header.
Key types
Prefix: eftest_. Sends go through SMTP — no Cloudflare credentials required. Set ENABLE_TEST_MODE=true to start the built-in Mailpit catcher at /mailpit/ (auth: root / ADMIN_TOKEN by default, override with MAILPIT_USER / MAILPIT_PASS).
Prefix: eflive_. Sends go through Cloudflare Email Sending. Requires valid CF_API_TOKEN and verified domain.
403.
POST /v1/send
#api-sendThe single endpoint for all transactional sends. Use templateSlug / templateId for stored templates, or pass raw html / text directly.
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
from | string | required | Sender email address. Must match a verified domain authorized for your key. |
fromName | string | optional | Display name shown in the From header, e.g. Acme Inc. |
to | string or string[] | required | Recipient address or array of up to 50 addresses. Duplicates are deduplicated. |
subject | string | optional | Overrides the template subject. Required for raw html/text sends. |
templateSlug | string | conditional | Stable slug-based template reference. Preferred for application code. |
templateId | string | conditional | Internal ID-based template reference. Use templateSlug when possible. |
themeId | string | optional | Applies a built-in colour theme to layout-based templates. See theme list below. Defaults to default. |
variables | object | optional | Key/value map for {{variable}} interpolation in subject and body. |
html | string | conditional | Raw HTML body. Used when not referencing a template. |
text | string | conditional | Plain-text body. Can be combined with html. |
replyTo | string | optional | Reply-to address for the recipient. |
templateSlug, templateId, html, or text must be provided.
cURL
fetch (JavaScript)
Response (200)
Templates & themes
#templatesEmailFlare ships 50 layout-based templates built with React Email. Reference them by their templateSlug. Pass themeId to switch colour palettes per send — no CSS edits needed.
Available themes
defaultoceanforestvioletslateTemplate reference tips
- Prefer
templateSlugovertemplateId— slugs are stable across restores. - Variable names follow the
{{camelCase}}convention used in the template body and subject. - If a variable is missing from the payload, it renders as the literal
{{variableName}}placeholder. themeIdonly applies to layout-based templates. Custom HTML templates ignore it.
Error responses
#errors| Status | Meaning | Common cause |
|---|---|---|
| 401 | Unauthorized | Missing or invalid Authorization header. |
| 403 | Forbidden | Key scope does not authorize the sender domain. |
| 404 | Not found | templateSlug or templateId does not exist. |
| 422 | Validation error | Missing required fields or invalid email format. |
| 429 | Rate limited | Per-key send limit reached. Check X-RateLimit-Reset header. |
| 502 | All recipients failed | Downstream delivery failed for every address in the request. |
| 500 | Server error | Unexpected backend error — check container logs. |
Rate limiting headers returned on every /v1/send response:
Troubleshooting
#troubleshooting401 on /v1/send
Confirm the header is exactly Authorization: Bearer <key> with no extra spaces. Verify the key is marked active on the Keys page.
403 with a domain-scoped key
The from address domain must be included in the key's allowed domains. Create a global scoped key to bypass domain restrictions while debugging.
Template not found (404)
Copy the slug exactly from the Templates page — it is case-sensitive. System templates use slugs like welcome, magic-link, otp.
Theme not applied to email
themeId only works with layout-based (built-in) templates. For custom HTML templates the field is ignored — you control the styles directly in the HTML body.
Sends succeed in test mode but fail in live mode
Test keys (eftest_) use SMTP and don't require Cloudflare credentials. Live keys use Cloudflare Email Sending — ensure CF_API_TOKEN has the correct permissions and the sender domain is verified. See the Cloudflare token guide →
To test with the built-in Mailpit catcher, set ENABLE_TEST_MODE=true — Mailpit will be available at /mailpit/ on the same port as the admin UI.
Database errors in logs
If you see "This SQL statement is not allowed on /query endpoint", upgrade to the latest EmailFlare image — this was a bug fixed in the backend send route.
docker compose logs -f emailflare. Most issues are visible in the startup or request output.