Skip to main content
The Courier API is a single REST API for everything Courier does: send messages, build journeys, manage templates and brands, and read delivery logs. Anything you can do in the dashboard, you can do through the API. Browse the API reference for every endpoint. This page covers the conventions they all share.
  • New to Courier? Send your first notification in two minutes with the Quickstart.
  • Building with an AI coding agent like Claude Code, Codex, or Cursor? Connect Courier over MCP or the CLI. Start with AI onboarding.
  • Prefer a GUI? Explore every endpoint in the Postman collection.

Client libraries

Official server SDKs wrap the REST API with typed methods, retries, and idempotency helpers. Use them instead of raw HTTP wherever possible. Client-side SDKs embed prebuilt UI in your app: an in-app notification center and a preference center, for React, React Native, iOS, Android, and Flutter. Any language can call the REST API directly.

Authentication

Courier authenticates every request with a bearer token. Pass your API key in the Authorization header:
Requests without a valid key return 401 Unauthorized. Keys are scoped to a single environment (Test or Production), so a Test key never sends real notifications and a Production key is never used for experiments. Create and rotate keys in Settings → API Keys.
Your API key is a secret. Use it only from server-side code, never in a browser, mobile app, or committed source. To authenticate a client (for Inbox or preferences), issue a short-lived user token instead.

Requests and responses

  • All requests and responses use JSON. Send Content-Type: application/json on requests with a body.
  • Timestamps are returned as Unix epoch milliseconds (int64), not ISO 8601 strings.
  • Send responses return a requestId. Use it to look up a message or trace delivery in Message Logs.

Payload limits

The maximum request body size for all endpoints is 6 MB. Requests over the limit return 413 Payload Too Large. Base64-encoded content (such as inline attachments) inflates size by roughly 33%, so a 6 MB payload holds about 4.5 MB of raw attachment data. For anything larger, host the file and pass a URL instead of embedding it.

Idempotency

Safely retry requests without sending duplicates by setting an Idempotency-Key header. Use a unique value, such as a UUID, for each logical request, and reuse the same value when you retry:
Add the header to any POST request. Courier caches the first response for that key and replays it on retries, so the request runs only once. Keys expire after 24 hours.

Pagination

List endpoints use cursor-based pagination. Every response includes a paging object with a more boolean and a cursor:
When paging.more is true, pass paging.cursor back as the cursor query parameter to fetch the next page:
The data array field name depends on the endpoint: messages return results, while lists and audiences return items. Check each endpoint’s schema in the API reference.

Errors

Courier uses standard HTTP status codes. Codes in the 2xx range mean success, 4xx means a problem with the request, and 5xx means a Courier-side error. Error responses include a JSON body with a human-readable message and a machine-readable type:

Message statuses

A 202 from POST /send means Courier accepted the request, not that the message was delivered. Track the outcome with the get-message endpoint, which returns one of these statuses: ENQUEUED, ROUTED, SENT, DELIVERED, OPENED, CLICKED, DELAYED, DIGESTED, THROTTLED, FILTERED, CANCELED, SIMULATED, and three failure states:
  • UNROUTABLE: no channel could be resolved (missing provider, or no channel data on the profile)
  • UNDELIVERABLE: the provider rejected the recipient (invalid address or blocked domain)
  • UNMAPPED: the referenced template could not be found
Failed messages also carry a reason (such as BOUNCED, NO_PROVIDERS, OPT_IN_REQUIRED, or UNSUBSCRIBED) for more context.

Rate limits

Rate limits apply per environment and vary by endpoint. POST /send is not subject to the limits below; it is bounded by the 6 MB payload cap and any workspace send limits you configure. The following limits apply to management endpoints: Exceeding a limit returns 429 Too Many Requests. Back off and retry after a short delay.

FAQ

Anything you can do in the Courier dashboard. Send notifications across email, SMS, push, chat, and in-app, and manage user profiles, preferences, lists, templates, brands, and tenants. Every resource has full REST API coverage.
All requests go to https://api.courier.com over HTTPS.
Pass your API key as a bearer token in the Authorization header: Authorization: Bearer YOUR_API_KEY. Keys are scoped per environment (Test or Production) and used only in server-side code.
Courier maintains official server SDKs for Node.js, Python, Ruby, Go, Java, PHP, and C# / .NET, plus client SDKs for React, React Native, iOS, Android, and Flutter. Any language can call the REST API directly.
Management endpoints are limited per environment (for example, 20 requests/minute on Lists and Events, 200 requests/minute on Brands). Exceeding a limit returns 429 Too Many Requests.
Set an Idempotency-Key header with a unique value. Courier replays the original response for 24 hours, so a retried request runs only once.

What’s next

Send a message

Full request and response schema for the send endpoint

How sending works

Routing, channels, fallback, and the delivery pipeline

Courier CLI

Send and manage notifications from your terminal or CI

Manage profiles

Store recipient contact info and channel tokens