Introduction
How the Flaresend HTTP API works: base URL, requests, responses and request IDs.
The Flaresend API is a JSON REST API served by your own mailer Worker. Every app that isn't a Cloudflare Worker in the same account uses it to send email, read what happened to it, and manage webhooks, templates and contacts.
Base URL
Flaresend is not a hosted service, so there is no shared API host. The base URL is wherever you deployed the mailer Worker. These docs use:
https://mailer.example.comEvery API route is under /v1, for example POST https://mailer.example.com/v1/emails.
Authentication
Send a project API key as a Bearer token:
curl https://mailer.example.com/v1/me \
-H "Authorization: Bearer $FLARESEND_API_KEY"The key decides which project the request acts on. Routes under /v1/admin take the admin key instead. See Authentication.
Requests
- Send bodies as JSON with
Content-Type: application/json. A body that isn't valid JSON fails with400 invalid_body, and a missing body where one is needed fails with400 missing_body. - Query parameters are plain strings, for example
?limit=50&status=bounced. - Dates are ISO 8601 strings. Parameters such as
scheduledAt,sinceanduntilneed a time zone offset:2026-10-01T09:00:00Zor2026-10-01T11:00:00+02:00. - IDs have a prefix that tells you what they are:
email_,evt_,wh_,whd_,ct_,aud_,bc_,tmpl_,key_,proj_, followed by a 26-character ULID.
Responses
Every response is JSON and has one of three shapes:
| Shape | Used by | Example |
|---|---|---|
| A single object | Creating, reading or changing one thing | GET /v1/emails/:id returns the email |
{ "data": [...] } | Short lists that are never paginated | GET /v1/webhooks, GET /v1/domains |
{ "data": [...], "nextCursor": "..." } | Lists that can be long | GET /v1/emails, GET /v1/events |
See Pagination for the third shape. Errors always have the same body, described in Errors:
{
"error": {
"type": "permission_error",
"code": "invalid_sender",
"message": "from must be an address on acme.com",
"param": "from"
}
}Request IDs
Every response has an X-Request-Id header. If you send your own X-Request-Id on the request, Flaresend uses that value instead of generating one, which makes it easy to follow one request through your logs and the Worker's logs. Unexpected errors are logged by the mailer with this ID.
Health check
GET /health needs no key. It runs one query against the D1 database and returns:
{ "ok": true }SDK and RPC
The @flaresend/client package wraps every endpoint on this page, with retries and idempotency keys built in:
npm install @flaresend/clientCloudflare Workers in the same account can skip HTTP entirely and call the mailer over a service binding. That path needs no API key. See the RPC client.
Endpoints
Emails
Send, batch send, list, read, reschedule and cancel.
Events
Every timeline event across the project.
Domains
Sending domains and their verification status.
API keys
The project's keys, and the key you're calling with.
Webhooks
Endpoints that receive signed events.
Templates
Stored templates with versions and previews.
Analytics
Sent, delivered, bounced and more, per day or hour.
Contacts
People you send broadcasts to.
Audiences
Named lists of contacts.
Broadcasts
One email to a small, opted-in audience.
Admin API
Projects, keys, suppressions and stats, with the admin key.
SDK
The typed client for all of the above.