Skip to main content
A send begins when your application calls the Courier API. Courier renders your content, applies user preferences, determines the right channel, and sends the message through your configured providers. Each message is tracked from request to delivery so you can monitor outcomes in real time. Courier provides a single source of truth for message observability across every channel.
Your App   β†’   Courier API   β†’   Providers   β†’   User
You decide what to send and who should receive it. Courier manages how it gets there, including routing, preferences, retries, failover, and logging. A single API call is all it takes to send a notification. One request can handle rendering, routing, preferences, and delivery across email, SMS, push, inbox, chat apps, and more. See Send a Message for code examples in every supported language.

Core Concepts

Every send request is built around a few core ideas: Recipients
You can include contact details, such as email, phone number, or push token, directly in your request or reference a user_id linked to a stored user profile.
Templates
Define content inline or reference a saved template that your team manages visually. Templates keep messaging consistent across channels and editable without code changes.
Data
Pass dynamic variables, such as {{name}} or {{order_id}}, to personalize content at send time.
Routing
Deliver messages using priority routing through a single channel or by broadcasting across multiple channels at once. Courier automatically selects the right route for each message based on your configuration.
User Preferences
Courier automatically enforces each user’s notification preferences at send time, respecting channel choices, frequency settings, and opt-outs without extra logic in your code.

Beyond Single Sends

The Send API is the right choice for most notifications. Use it when your application controls the recipient, timing, content, and data for a single message. When your product needs more structure, Courier gives you two ways to build on top of direct sends.

Templates

Move content out of code so PMs, designers, and operators can update messages without a deploy. Your application keeps the same send call and passes the data needed to render each message.

Journeys

Build multi-step customer messaging flows in a visual editor. Use Journeys to orchestrate onboarding, activation, reminders, and re-engagement with triggers, delays, branching, enrichment, throttling, and run inspection.
Journeys start with a trigger from your application or an event stream. Courier then executes each step in the workflow, including sends, delays, branches, data fetches, and throttles. Each Journey can define a typed data contract, which powers autofill and variable hints in the editor. Run inspection gives you a step-by-step view of what happened for a specific user, so you can debug complex messaging flows with production data. Start with direct sends, move reusable content into templates, and use Journeys when your messaging needs orchestration. See Choose a Sending Strategy for a detailed comparison.

FAQ

Yes. Pass an array of recipients in the to field to send a single message to multiple users. You can also send to a List or Audience to target dynamic groups. For larger volumes, use the Bulk API to create a job, add users, and run the job asynchronously.
Courier automatically fails over based on your routing configuration. If the primary provider for a channel is unavailable, Courier tries the next configured provider. If the entire channel fails, such as when the user has no email address, Courier moves to the next channel in priority order. See Automated Failover for details.
Courier retries failed sends automatically using exponential backoff. Transient errors from providers, such as rate limits or temporary outages, are retried before the send is marked as failed. You can monitor retry attempts and final delivery status in Message Logs.
Yes. Include an idempotency_key in your send request header. If Courier receives a second request with the same key, it returns the original response without sending again. This is useful for safely retrying requests after network failures.
Yes. Use the delay object in your send request to hold a message for a specified duration or until a specific time. See Delays & Delivery Windows for configuration options.

Choose a Sending Strategy

Inline sends, templates, or Journeys; pick the right level

Send a Message

Code examples for every supported language

Journeys Overview

Visual workflows for multi-step customer messaging

Automated Failover

Automatic provider and channel failover