Prerequisites
Before you start, make sure you have:- Node.js 18+ installed
- A Courier account (sign up free)
- Your Courier API key from Settings > API Keys
- A test user profile in Courier with an email address (create one in the Users page or via the API)
Which channels work out of the box?
Not every channel requires provider setup. Here’s what you can use right away and what needs configuration:| Channel | Ready out of the box? | Setup needed |
|---|---|---|
| Inbox | Yes | None. Courier’s in-app inbox works immediately. |
| Yes (test mode) | Courier provides a built-in email provider for testing. For production, add a provider like SendGrid or AWS SES. | |
| Push | No | Requires a push provider (Firebase, APNs) and device tokens on user profiles. |
| SMS | No | Requires an SMS provider (Twilio, Vonage) and phone numbers on user profiles. |
Project setup
Understanding the routing model
Every Couriersend call accepts a routing object with two fields:
| Method | Behavior |
|---|---|
single | Try each channel in order, stop at the first successful delivery |
all | Deliver to every channel in the array simultaneously |
single, Courier works through it top to bottom. For all, every channel fires at once.
Pattern 1: Urgency-based routing
The most common pattern for agent-driven notifications. Instead of hardcoding a channel, the agent expresses urgency and a helper function maps it to a routing strategy. Createsrc/send-notification.ts:
| Urgency | Method | Channels | When to use |
|---|---|---|---|
critical | all | email, SMS, push, inbox | Security alerts, outages, account compromises |
high | single | push → email → inbox | Time-sensitive operational alerts |
normal | single | email → inbox | Reports, digests, routine updates |
low | single | inbox | Informational, non-time-sensitive |
Test it
Add a quick test script at the bottom ofsend-notification.ts (or in a separate file):
low urgency to confirm your setup works. This sends to inbox only, which requires no provider configuration:
Pattern 2: Channel failover
Some users don’t have push tokens configured. Some haven’t verified their phone number. Withmethod: "single", Courier attempts each channel in order and stops at the first success:
The
requestId returned by the send call lets you check delivery status later using the Messages API. This is useful for agents that need to confirm a notification landed before continuing.Pattern 3: Provider failover
Channel failover handles “which channel.” Provider failover handles “which service within a channel.” If your primary email provider goes down, Courier can silently retry through a backup. Add achannels object to configure per-channel provider ordering:
- Channel level: email → push → inbox
- Provider level (within email): SendGrid → AWS SES
Pattern 4: Template-based multi-channel
For notifications that need branded designs, channel-specific copy, or complex layouts, use a Courier template instead of inline content. Design the template once in the template designer, and Courier renders the appropriate version for each channel.data object passes dynamic values into your template variables. The email version can include a full HTML layout with error details, the push notification can be a short summary, and the inbox message can include action buttons.
To create the
DEPLOYMENT_ALERT template, go to Templates, click New, and add channel blocks for each delivery channel. Use {service}, {environment}, and {exitCode} as template variables.Exposing to your agent
ThesendNotification function from Pattern 1 works as a tool in any agent framework. Here are three ways to connect it:
Option 1: Courier MCP server
If your agent runs in Cursor, Claude Code, or another MCP-compatible environment, the Courier MCP server exposes asend_message tool that already supports routing, channels, and template fields. No custom code needed.
Add to your .cursor/mcp.json:
Option 2: Courier CLI
For agents that work through shell commands, usecourier send message with the same JSON structure:
Option 3: Custom tool definition
WrapsendNotification as a tool in your framework of choice. The function signature maps directly to a tool schema: userId, title, body, and urgency as parameters, with the urgency descriptions guiding the LLM’s selection.
This works with OpenAI function calling, Vercel AI SDK, LangChain, or any framework that supports structured tool definitions.
Verify delivery
After sending, check delivery status in two ways:- Courier Logs UI: Go to app.courier.com/logs to see the full delivery timeline for each notification, including which channels were attempted, which succeeded, and which providers were used.
- Messages API: Query delivery status programmatically:
| Status | Meaning |
|---|---|
| Delivered | The provider accepted and delivered the notification |
| Sent | The provider accepted the notification (delivery confirmation pending) |
| Unroutable | No provider is configured for this channel. Expected if you haven’t set up that channel yet. |
| Undeliverable | A provider is configured but delivery failed (bad address, expired token, etc.) |
What’s next
Configure multi-channel routing
Set up routing rules in the Send API and the visual designer
Agent quickstart
Set up your AI agent with Courier’s MCP server, CLI, and Skills
CLI reference
Send and manage notifications from the command line
Send API reference
Full API documentation for the Send endpoint