FlaresendDocs

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.com

Every 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 with 400 invalid_body, and a missing body where one is needed fails with 400 missing_body.
  • Query parameters are plain strings, for example ?limit=50&status=bounced.
  • Dates are ISO 8601 strings. Parameters such as scheduledAt, since and until need a time zone offset: 2026-10-01T09:00:00Z or 2026-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:

ShapeUsed byExample
A single objectCreating, reading or changing one thingGET /v1/emails/:id returns the email
{ "data": [...] }Short lists that are never paginatedGET /v1/webhooks, GET /v1/domains
{ "data": [...], "nextCursor": "..." }Lists that can be longGET /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/client

Cloudflare 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

On this page