Skip to main content
Routing decides which channels and providers a message goes through. Set a routing method and channel list on the send, or save a routing strategy on the template. Courier tries them in order. When one is unavailable, it fails over to the next provider or channel.

How it works

method: single vs all

routing.method decides how Courier uses the channels list:
  • single tries channels in order and stops at the first that works. The rest are its failover.
  • all sends through every channel in the list, so email and push go out together.
If you omit routing, Courier uses the template’s routing strategy, or a default of { "method": "single", "channels": ["email"] }.

What goes in the channels list

Each entry in channels is one of:
  • A channel key: email, sms, push, inbox, direct_message.
  • A provider key to target one provider directly: twilio, sendgrid. See .
  • A nested routing object: a group of channels with its own method. Use it to express “try push, then fall back to email or SMS together.”

Channel priority

Within a channel, Courier tries providers in priority order. The order you set in the channel’s settings comes first, then any other configured providers. Each provider can carry an if condition. Courier skips a provider that is not configured or whose condition fails. The channel’s own routing_method (single or all) decides whether it delivers through the first working provider or all of them.

Reaching iOS and Android in one send

APNs and FCM are two providers inside the one push channel, and a channel’s routing_method defaults to single. Courier delivers through the first provider that works and stops, so a user with both an iPhone and an Android tablet gets the notification on one device. Set that channel’s routing_method to all. It goes in message.channels, keyed by channel name, not in the routing object:
routing.method chooses between channels. A channel’s routing_method chooses between the providers inside it. A user with only an iPhone is unaffected either way, because FCM is skipped without a token.
Both providers have to be on the channel first.
A channel delivers through the providers attached to it, and routing_method only decides how many of them it uses. Install each provider under , then open the template’s routing selector in the and add both APNs and Firebase FCM to the push channel. An older template routes only through the providers on its own channel, so one you skipped there never becomes a candidate.

Failover

Failover is automatic and works at two levels. Within a channel, if the first provider fails, Courier tries the next configured provider. Across channels, if a whole channel fails, Courier moves to the next channel in the list. A channel fails when no provider worked on a single route, or when the user has no address for it. Courier retries transient provider errors before marking a provider failed. The message log records each attempt.

Routing configuration and strategies

Rather than repeat a routing object on every send, save a routing strategy and attach it to a template. A strategy (ID prefixed rs_) holds a reusable method, channel order, and provider order, so content and routing change independently.

Delivery pipeline resilience

The pipeline honors timeouts so a slow provider does not block the send. A message-level timeout is available on every plan. Per-provider and per-channel custom timeouts (message.timeout.provider, message.timeout.channel, or a timeout on a specific channel or provider) are set the same way. Failover itself is never gated.

Limits & behavior

  • Omitted routing falls back to single email. With no routing and no template strategy, Courier routes single to email.
  • Message-level and custom per-provider or per-channel timeouts both apply. Failover is not gated.
  • Failover is automatic. Courier tries the next provider, then the next channel, retrying transient errors, and logs each attempt.

FAQ

single sends through the first channel that works (the rest are failover). all sends through every channel in the list at once.
Within a channel it uses your configured provider order first, then any other configured providers. It skips providers whose condition fails or that are not set up. If the first fails, it fails over to the next.
Attach a routing strategy to the template and omit routing on the send to reuse it. Set routing inline only when you want to override the strategy for one message.
Set the push channel’s routing_method to all in message.channels, and make sure both providers are on that channel in the template’s routing selector. APNs and FCM are two providers in the one push channel, and the default single treats them as failover, so a user with devices on both platforms only gets one. See reaching iOS and Android in one send.
Failover itself is never gated, and both message-level and custom per-provider or per-channel timeouts apply.