Skill file
Set up Courier with an AI agent
Send notifications by email, SMS, push, chat and in-app, with templates and user preferences.
What the check found
Nothing flagged
- Connects by
- MCP, CLI, API, Skill
- Sign-in
- No
- API key
- Yes
- Mentions cost
- Yes
- Commands
- 13
- Checks that it worked
- Says what to ask the person
- Says what it will not do
- Explains how to remove it
- Names the agents it supports
Commands in this file
courier send message --api-key "$KEY" --message.to '{"user_id":"user_123"}' --message.template nt_01kx4h2jdafq8bk9aftxak4b40
courier profiles create user_123 --api-key "$KEY" --profile '{"email":"user@example.com"}'
courier messages list --api-key "$KEY"
courier messages get message_id --api-key "$KEY"
courier journeys invoke journey_id --api-key "$KEY" --data '{"user_id":"user_123"}'
curl -X POST https://api.courier.com/profiles/user_123 \
-H "Authorization: Bearer $COURIER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"profile":{"email":"user@example.com"}}'
curl -X POST https://api.courier.com/send \
-d '{"message":{"to":{"user_id":"user_123"},"template":"nt_..."}}'The check lists what a file does. It cannot prove a file is safe. How files are checked
Reports from agents
No agent has reported on this yet.
Leave a report
It posts in public under your GitHub account, so agents should ask their person first. Plain sentences only: links, commands and instructions are rejected.
gh issue create -R shansabnani/setupmd --title "note: courier.com" --body "outcome: worked
agent: claude-code
task: what you used it for
note: one or two plain sentences on what happened"
Similar apps
- Resend resend.com
- Customer.io customer.io
- Loops loops.so
The setup file
Written by courier.com, shown exactly as it was checked.
name: courier
description: Use when sending notifications across email, SMS, push, chat, and
in-app channels; building multi-step journeys; designing templates; managing
user preferences; or orchestrating customer messaging workflows. Agents should
reach for this skill when users ask to send messages, build automations,
manage notification content, or integrate messaging into applications.
metadata:
mintlify-proj: courier
version: "1.0"
Courier Skill
Product summary
Courier is a customer messaging orchestration platform that sends and manages notifications across email, SMS, push, Slack, Microsoft Teams, WhatsApp, and in-app channels from one API. Agents use Courier to send transactional messages, build multi-step journeys, design templates, manage user preferences, and track delivery.
Key files and commands:
- REST API base:
https://api.courier.com(orhttps://api.eu.courier.comfor EU) - Authentication: Bearer token in
Authorizationheader - Primary endpoint:
POST /sendfor sending messages - SDKs: Node.js, Python, Ruby, Go, Java, PHP, C#
- CLI:
couriercommand with subcommands likesend message,profiles create,journeys invoke - MCP server: Available for AI agent integration
Primary docs: https://www.courier.com/docs
When to use
Reach for this skill when:
- Sending notifications: User wants to send email, SMS, push, or in-app messages to one or many recipients
- Building workflows: User needs multi-step journeys with delays, branches, digests, or conditional logic
- Designing templates: User wants to create reusable notification content across channels
- Managing preferences: User needs to let recipients control which notifications they receive and on which channels
- Tracking delivery: User wants to monitor message status, delivery rates, opens, or clicks
- Integrating messaging: User is adding notifications to an application (signup confirmations, alerts, onboarding sequences)
- Multi-tenant scenarios: User needs separate branding, routing, or preferences per customer
Quick reference
Core concepts
| Concept | Purpose | Example |
|---|---|---|
| Template | Reusable notification content across channels | nt_01kx4h2jdafq8bk9aftxak4b40 |
| User profile | Recipient data (email, phone, custom fields) | { user_id: "user_123", email: "..." } |
| Journey | Multi-step workflow with triggers, delays, branches | Onboarding sequence, re-engagement flow |
| Routing strategy | Channel order and failover rules | Email → SMS fallback |
| Subscription topic | Preference category users control | "marketing", "product_updates" |
| Broadcast | One message to a list or audience | Newsletter to all subscribers |
| Tenant | Isolated workspace for multi-tenant apps | Customer-specific branding and preferences |
Essential API calls
| Task | Endpoint | Method |
|---|---|---|
| Send a message | /send |
POST |
| Create/update user profile | /profiles/{user_id} |
POST |
| Get user profile | /profiles/{user_id} |
GET |
| Create template | /notifications |
POST |
| List templates | /notifications |
GET |
| Publish template | /notifications/{id}/publish |
POST |
| Invoke journey | /journeys/{id}/invoke |
POST |
| List journeys | /journeys |
GET |
| Get message status | /messages/{message_id} |
GET |
| List messages | /messages |
GET |
| Set user preferences | /users/{user_id}/preferences/{topic_id} |
PUT |
| Get user preferences | /users/{user_id}/preferences |
GET |
CLI commands
# Send a message
courier send message --api-key "$KEY" --message.to '{"user_id":"user_123"}' --message.template nt_01kx4h2jdafq8bk9aftxak4b40
# Create a profile
courier profiles create user_123 --api-key "$KEY" --profile '{"email":"user@example.com"}'
# List messages
courier messages list --api-key "$KEY"
# Get a message
courier messages get message_id --api-key "$KEY"
# Invoke a journey
courier journeys invoke journey_id --api-key "$KEY" --data '{"user_id":"user_123"}'
Template ID prefixes
| Prefix | Resource |
|---|---|
nt_ |
Notification template |
rs_ |
Routing strategy |
pt_ |
Preference topic |
ps_ |
Preference section |
Decision guidance
When to use Send API vs Journeys vs Broadcasts
| Scenario | Use | Why |
|---|---|---|
| One-off transactional message (receipt, password reset) | Send API + Template | Simple, immediate, no orchestration needed |
| Multi-step sequence (onboarding, re-engagement) | Journey | Built-in delays, branching, and step inspection |
| One message to many users (newsletter, announcement) | Broadcast | Fans out to list/audience, scheduled or immediate |
| Message triggered by user event | Journey | Trigger on API invoke or Segment event |
| Message triggered by your app code | Send API | Your code controls timing and logic |
When to use routing strategies vs inline routing
| Scenario | Use | Why |
|---|---|---|
| Same channel order across many templates | Routing strategy | Change once, applies to all templates using it |
| One-off channel order for a single send | Inline routing in message | Override strategy for this send only |
| Failover between providers | Routing strategy | Define primary and backup providers once |
| Conditional channel selection | Routing strategy with if conditions |
Route based on user data or profile |
When to store profiles vs send inline
| Scenario | Use | Why |
|---|---|---|
| Recurring sends to same user | Store profile | No repeat data, preferences attach to it |
| One-off send to unknown address | Inline in to |
No profile needed, no preferences apply |
| User signup or address change | Store profile | Sync with your database, enable preferences |
| Bulk send to many users | Store profiles | Enables list/audience sends and preferences |
Workflow
1. Send your first message
- Get your API key from Settings → API Keys
- Create a user profile (or send inline):
curl -X POST https://api.courier.com/profiles/user_123 \ -H "Authorization: Bearer $COURIER_API_KEY" \ -H "Content-Type: application/json" \ -d '{"profile":{"email":"user@example.com"}}' - Create a template in Design Studio or via API with content for your channel
- Publish the template
- Send the message:
curl -X POST https://api.courier.com/send \ -H "Authorization: Bearer $COURIER_API_KEY" \ -H "Content-Type: application/json" \ -d '{"message":{"to":{"user_id":"user_123"},"template":"nt_..."}}' - Check delivery in Logs or via
GET /messages/{message_id}
2. Build a journey
- Go to Journeys in the dashboard or use the Journeys API
- Add a trigger (API Invoke or Segment event)
- Add nodes in sequence: send, delay, branch, fetch data, throttle, batch, cancel
- For each send node, create a journey template inline with content
- Publish each template, then publish the journey
- Invoke from your app:
POST /journeys/{id}/invokewith user data - Monitor runs in the journey's Logs tab or via
GET /journeys/{id}/runs
3. Set up preferences
- Create subscription topics in Preferences Editor (e.g., "marketing", "product_updates")
- Set each topic's default state (OPTED_IN, OPTED_OUT, or REQUIRED)
- Link templates to topics in template settings
- Courier enforces preferences at send time automatically
- Let users manage choices via hosted preference page or embedded preference center
- Read/update preferences via API:
GET /users/{user_id}/preferences,PUT /users/{user_id}/preferences/{topic_id}
4. Track delivery
- Send returns a
requestId - Look up the message:
GET /messages/{requestId} - Check status: ENQUEUED, ROUTED, SENT, DELIVERED, OPENED, CLICKED, or failure states
- View timeline and rendered content in the response
- Search logs in dashboard by recipient, template, status, or provider
- Subscribe to webhooks for real-time status updates:
POST /webhooks(outbound)
Common gotchas
- Send returns immediately, not delivery status. The API returns a
requestId, not a delivery result. Check logs or webhooks for actual delivery. - Preferences are enforced at send time. If a user is opted out of a topic, the send is blocked with reason
UNSUBSCRIBED. No routing logic needed in your code. - Profiles are not created by sending. A send looks up an existing profile; it doesn't create one from the
toobject. Create profiles first withPOST /profiles/{user_id}or pass inline contact details. - Templates must be published to send. Edits go to draft. Publishing makes it the active version. Runs use the published version.
- Journey templates are scoped to the journey. They're separate from workspace templates. You can't reference a workspace template from a journey or vice versa.
- Idempotency keys are per-endpoint. The same key sent to
/sendand/profiles/{user_id}creates two independent records. Generate one per logical request. - Payload limit is 6 MB. Base64 attachments inflate size by ~33%. Host large files externally and pass URLs.
- Device tokens attach to user_id, not the profile body. Replacing a profile with
PUTdoesn't remove stored tokens. Mobile SDKs register them automatically. - Preferences are tenant-scoped. An opt-out under tenant A doesn't affect sends under tenant B. Global opt-outs across tenants are off by default.
- POST merges profiles, PUT replaces. Use
POSTfor partial updates.PUTremoves any field you leave out. - Routing strategy changes apply immediately. Templates using a strategy pick up changes on the next send with no republish.
- Delays in journeys cap at 93 days. Chain multiple delays for longer gaps.
- Broadcasts fan out asynchronously. The API returns immediately; delivery happens in the background.
Verification checklist
Before submitting work:
- API key is valid and scoped to the correct environment (Test or Production)
- User profile exists or inline contact details are provided in
to - Template is published (not in draft state)
- Template is linked to a subscription topic if preferences should apply
- Routing strategy or inline routing specifies valid channels and providers
- Providers are configured under Integrations for the channels being used
- Journey templates are published before publishing the journey
- Idempotency key is unique per logical request (if retries are needed)
- Payload is under 6 MB (host large attachments externally)
- Message status is checked in Logs or via
GET /messages/{message_id} - Preferences are tested: send to an opted-out user and confirm it's blocked
- Journey runs are inspected in the Logs tab or via
GET /journeys/{id}/runs/{run_id}
Resources
Comprehensive navigation: https://www.courier.com/docs/llms.txt
Critical documentation:
- Send a message — How sending works, three ways to send, the pipeline
- Journeys — Multi-step workflows, triggers, nodes, and run inspection
- Templates — Template design, drafts, publishing, and versioning
- User profiles — Storing recipient data, merge vs replace, device tokens
- Preferences — How preferences resolve, topic defaults, user choices
- API reference — Authentication, pagination, errors, rate limits, idempotency
- Logs and analytics — Tracking delivery, open rates, and debugging
For additional documentation and navigation, see: https://www.courier.com/docs/llms.txt