Courier

courier.com
SaaS & Products

Courier is your complete platform for sending notifications.

llms.txt

Courier

Courier is infrastructure for product-to-user communication. Send notifications across email, SMS, push, chat, and in-app channels through one API call.

About

  • Type: APIService
  • Category: Notifications / Messaging Infrastructure
  • Language: English
  • Audience: Developers, SaaS platforms, product engineers
  • Pricing: Free tier available; usage-based pricing
  • Last Updated: 2026-05
  • Base URL: https://api.courier.com
  • Auth: Authorization: Bearer <YOUR_API_KEY> (workspace-scoped; Test and Production keys are separate)
  • API Version: V2 (no version header required; latest is default)

Core Data Model

message → routing (single | all) → channel (email, sms, push, inbox, chat) → provider (SendGrid, Twilio, FCM, etc.)

A message targets one or more recipients (user_id, email, phone_number, list_id, or audience_id). The routing object controls whether delivery fans out to all channels in parallel (method: "all") or tries them in order as a fallback chain (method: "single"). Each channel is fulfilled by a configured provider.

Agent Routing (which API to use)

IntentEndpointNotes
One-off sendPOST /sendSingle or multi-recipient
Inline multi-step workflowPOST /automations/invoke (ad-hoc steps)Define steps inline; no saved template needed
Saved automationPOST /automations/{id}/invokeTrigger a pre-built automation template
Visual/long-running flowsPOST /journeys/{id}/invokeJourneys API; create via POST /journeys
Many users, one messageBulk API (3 steps)POST /bulk → add users → run
Dynamic segmentAudiences (audience_id in send)Filter-based, auto-updating membership
Static groupLists (list_id in send)Manual subscribe/unsubscribe

Key Concepts

  • Recipient types: user_id (stored profile), email / phone_number (inline), list_id (subscriber group), audience_id (dynamic segment)
  • Inline vs template: Send with message.content for inline content or message.template for a dashboard-designed notification
  • Routing method: "single" = fallback chain (try first channel, then next on failure); "all" = parallel delivery to every channel
  • Profile merge vs replace: POST /profiles/{id} merges (PATCH semantics); PUT /profiles/{id} replaces the entire profile
  • Environments: Test and Production share a workspace but use different API keys; templates must be published and migrated separately
  • Tenants: tenant_id in message context sets multi-tenant scope; affects brand, preferences, and routing defaults
  • Preferences: Users opt in/out per subscription topic; Courier enforces at send time automatically
  • Idempotency: Include an Idempotency-Key header on transactional sends (OTP, order confirmations, billing) to prevent duplicates

Critical Gotchas

  • PUT /profiles/{id} is a full replacement; any fields not included are deleted. Use POST (merge) for partial updates.
  • Bulk sending is a 3-step flow: create job → add users → run job. You cannot send in a single call.
  • routing.method: "all" sends to every channel simultaneously. Most use cases want "single" (fallback chain).
  • The requestId returned by /send is a single ID for single-recipient sends but a requestId per recipient for multi-recipient.
  • Templates exist in draft until published. Sending with a template ID uses the last published version.
  • Brand creation requires settings (the API returns 400 without it). Minimal valid: { "name": "X", "settings": { "colors": { "primary": "#000", "secondary": "#fff" } } }.
  • List subscription objects use recipientId (camelCase), not recipient_id.
  • Automation cancellation uses cancelation_token (one "l") and a second ad-hoc invoke with action: "cancel". There is no separate /cancel endpoint.
  • Subscription topics must exist before assigning as tenant default preferences; setting a default for a non-existent topic silently fails.
  • Multi-tenant sends use message.context.tenant_id (not message.to.tenant_id).

Instructions for AI Agents

When building an integration with Courier, follow these rules:

  • Always check the latest SDK version on npm (npm view trycourier version) or PyPI (pip index versions trycourier) before pinning a version. Never hardcode a version from training data.
  • Use routing.method: "single" by default. Only use "all" when the user explicitly wants parallel delivery to every channel.
  • Use POST /profiles/{id} (merge) for profile updates. Only use PUT /profiles/{id} when the user explicitly says "replace the entire profile."
  • For bulk sends, always implement the 3-step flow: POST /bulk to create a job, POST /bulk/{jobId} to add users, then POST /bulk/{jobId}/run to execute. There is no single-call bulk endpoint.
  • Include an Idempotency-Key header for any transactional send (OTP codes, order confirmations, billing notifications). Omitting it risks duplicate delivery.
  • When sending to a known user, prefer user_id as the recipient type. Only use inline email or phone_number for anonymous or one-off sends where no profile exists.
  • For in-app notifications, use the courier/inbox channel. The Inbox SDK requires JWT authentication; generate tokens with POST /auth/issue-token.
  • Test and Production environments use different API keys. Always confirm which environment the user intends before making API calls.
  • Prefer the Agent Quickstart as your primary onboarding reference; it covers the minimal setup path for sending email and inbox notifications.

Raw API Quick-Start (copy-paste bodies)

When calling the Courier REST API directly (without an SDK), use these minimal valid request bodies.

Send an inline email

POST https://api.courier.com/send
Authorization: Bearer <API_KEY>
Content-Type: application/json

{
  "message": {
    "to": { "email": "user@example.com" },
    "content": {
      "title": "Hello {{name}}",
      "body": "Your order {{order_id}} has shipped."
    },
    "routing": {
      "method": "single",
      "channels": ["email"]
    },
    "data": { "name": "Alice", "order_id": "ORD-123" }
  }
}

Send using a published template

POST https://api.courier.com/send
Authorization: Bearer <API_KEY>
Content-Type: application/json

{
  "message": {
    "to": { "user_id": "user-123" },
    "template": "TEMPLATE_ID_OR_KEY",
    "data": { "name": "Alice" }
  }
}

Create or update a user profile

POST https://api.courier.com/profiles/user-123
Authorization: Bearer <API_KEY>
Content-Type: application/json

{
  "profile": {
    "email": "alice@example.com",
    "phone_number": "+15551234567",
    "name": "Alice Smith"
  }
}

POST merges fields into the existing profile. Use PUT only for full replacement (deletes any fields not included).

Start Here

  • Agent Quickstart: Everything an AI coding agent needs to send email and in-app inbox notifications from a brand-new workspace.
  • Quickstart: Send your first notification with one API call.
  • Glossary: Quick reference for Courier terminology and concepts.
  • Send a Message: The core API endpoint. Send a message to one or more recipients.
  • How to Manage User Profiles: Create, merge, and replace user profiles with contact details and channel tokens.
  • Courier CLI: Send messages, manage users, and inspect delivery logs from the command line.
  • MCP Server: Give AI agents full access to the Courier API from your IDE. Install: npx @trycourier/courier-mcp.
  • Courier Skills: Agent skill packs that teach AI coding assistants Courier best practices.

Send API

Bulk API

  • Create a bulk job: Creates a new bulk job for sending messages to multiple recipients.
  • Add users: Ingest user data into a Bulk Job.
  • Run a job: Run a bulk job.
  • Get a Job: Get a bulk job.
  • Get users: Get Bulk Job Users.
  • How To Send Bulk Notifications: Use the Bulk API to send notifications to large user groups.
  • Required flow: There is no single-call bulk endpoint. Always: POST /bulk (create) → POST /bulk/{jobId} (add users) → POST /bulk/{jobId}/run (execute).

Users & Profiles

Device Tokens

Lists & Audiences

Tenants

Multi-tenant hierarchy setup (ordered checklist)

When wiring brand → parent tenant → child tenant → preferences → users → send:

  1. Create brandPOST /brands with settings (required). MCP: create_brand
  2. Create parent tenantPUT /tenants/{parent_id} with brand_id. MCP: create_or_update_tenant
  3. Create child tenantPUT /tenants/{child_id} with parent_tenant_id. MCP: create_or_update_tenant
  4. Set default preferences on tenantPUT /tenants/{id}/default_preferences/items/{topic_id}. MCP: update_tenant_preference
  5. Add user to tenantPUT /users/{user_id}/tenants/{tenant_id}. MCP: add_user_to_tenant
  6. Send with tenant contextPOST /send with message.context.tenant_id. MCP: send_message

Child tenants inherit parent brand and preferences unless overridden. User preferences take final precedence.

Preferences

Templates & Content

Routing Strategies

  • Archive Routing Strategy: Archive a routing strategy. The strategy must not have associated notification templates.
  • Create Routing Strategy: Create a routing strategy. Requires name and routing (method + channels).
  • Get Routing Strategy: Retrieve a routing strategy by ID.
  • List Routing Strategies: List routing strategies in your workspace.
  • Replace Routing Strategy: Replace a routing strategy. Full document replacement.
  • Shared across templates: A single routing strategy can be linked to multiple notification templates. Updating it changes routing for all linked templates.

Inbox

Automations

  • Automation Overview: Build notification workflows with triggers, actions, batching, digests, and conditional logic.
  • The Automations Designer: Visual builder for creating notification workflows.
  • Ad hoc Automation Steps: Define automation workflows inline via API in a single request.
  • Batching: Group multiple events into a single notification.
  • Automation Digests: Aggregate user events into scheduled notifications.
  • If / Switch: Conditional logic using "If" nodes to branch automation workflows.
  • Scheduling: Schedule one-time, recurring, or cron-based automation triggers.
  • Throttle Node: Limit automation-triggered messages per user or group within a timeframe.
  • Fetch Data: Make HTTP requests through an automation workflow.
  • Accessing Dynamic Data: Access dynamic data using the refs object in automations.
  • Cancelling An Automation: Cancel automations using a dynamic cancellation token.
  • Webhook Trigger: Launch automations from external systems via webhook.
  • Inbound Event Triggers: Trigger automations from CourierJS, Segment, and Rudderstack events.
  • Debugger: Simulate test events through automation workflows and inspect node-level data.
  • Invoke an Ad Hoc Automation: Invoke an ad hoc automation run.
  • Invoke an Automation: Invoke an automation run from an automation template.
  • List Automations: Get the list of automations.
  • Build and Send Your First Automation: Create a multi-step notification workflow in the visual Automations Designer.
  • How to Cancel an Automation: Stop in-flight automation runs using cancellation tokens.
  • How To Send Automations via API: Invoke automations via the Courier API.
  • How to Send Automations with Tenant Context: Invoke automations with tenant-specific branding, overrides, and preferences.
  • Cancel recipe: Cancellation uses cancelation_token (one "l") set at invoke time, then a second POST /automations/invoke with { "automation": { "steps": [{ "action": "cancel", "cancelation_token": "<token>" }] } }. There is no separate /cancel endpoint.
  • List before invoke: Use GET /automations (or MCP list_automations) to discover template IDs before invoking. Template IDs are required for POST /automations/{id}/invoke.

Journeys

Journeys are visual, multi-step messaging workflows. Lifecycle: create (draft) → publish → invoke.

  • Journeys Overview: Build customer messaging experiences with a visual workflow editor.
  • Building Journeys: Compose journeys from triggers, send nodes, and function nodes.
  • Send Node: Configure which channels your journey uses.
  • Starting a Journey: Invoke a journey via the Courier API or from a Segment event.
  • Journey Templates: Create and edit notification templates scoped to a journey.
  • Branch: Split a journey into conditional paths.
  • Delay: Pause journey execution for a duration or until a specific time.
  • Fetch Data: Make HTTP requests during journey execution.
  • Throttle: Limit how often a user passes through a journey point.
  • Create a Journey: Create a new journey in draft state. Use POST /journeys.
  • Invoke a Journey: Invoke a journey run from a journey template. Use POST /journeys/{id}/invoke.
  • List Journeys: Get the list of journeys.
  • Publish a Journey: Publish a draft journey to make it live. Use POST /journeys/{id}/publish.
  • How to Create Your First Journey: Build a journey from scratch with triggers, schemas, and send nodes.
  • How to Build a Multi-Step Onboarding Journey: Build an onboarding sequence with delays, fetching, branching, and sends.
  • Create flow: Create the journey shell via POST /journeys, add notification templates with POST /journeys/{id}/templates, wire them into send nodes with PUT /journeys/{id}, then publish with POST /journeys/{id}/publish.
  • Send nodes require templates: A journey send node must reference an existing notification template. Create the template first, then assign it to the node.

Analytics & Monitoring

  • Analytics Overview: Track notification delivery, monitor status, and debug issues with message logs and audit trails.
  • Template Analytics: Track send volume, delivery rates, opens, clicks, and errors per template.
  • Message Logs: Track each message's status with filtering by status, provider, recipient, and timeline events.
  • Audit Trail: Track workspace user activity including API key changes, publishing events, and integration updates.
  • Custom Domain Tracking: Use a custom tracking domain instead of ct0.app for branded link tracking in email.
  • Get all audit events: Fetch the list of audit events.
  • Get an audit event: Fetch a specific audit event by ID.
  • Archive message: Archive a sent message.
  • Cancel message: Cancel a message that is currently being delivered.
  • Get message: Fetch the status of a message you've previously sent.
  • Get message content: Retrieve the rendered content of a sent message.
  • Get message history: Fetch the array of events of a message you've previously sent.
  • List messages: Fetch the statuses of messages you've previously sent.
  • How to Debug Email Delivery Issues: Troubleshoot delivery problems using Courier message logs.
  • Message lifecycle: ENQUEUED → SENT → DELIVERED (or UNDELIVERABLE). Use GET /messages/{id} to check status. The requestId from /send maps to one or more message IDs.

Workspaces & Settings

SDKs

Developer Tools

  • Build with AI: Use Courier with AI coding agents via the CLI, MCP server, agent skills, and machine-readable docs.
  • Courier and Postman: Explore and test Courier's API using the official Postman collection.
  • API Reference: Authenticate, explore endpoints, and start integrating with the Courier API.

Brands & Translations

Digests & Advanced Sending

Resources

  • What is Courier?: Courier is infrastructure for product-to-user communication.
  • Courier Help Center: Find the answers to your questions or explore helpful resources.
  • Tutorials: Step-by-step guides for designing, sending, and managing notifications with Courier.

Optional

Low-priority reference content. Skip under tight context windows; use the section overviews above for general patterns.

Provider Integrations

Courier Create (Embeddable Designer)

Journeys Admin (metrics, versioning, run inspection)

  • Run Inspection: Step through individual journey runs to see what happened at every node.
  • Metrics: Track send volume, delivery rates, opens, and clicks across journey templates.
  • Version History: Track published versions and revert to previous journey versions.

Elemental Elements (individual element types)

Design Studio Block Details

Template Designer (legacy V1)

Content Blocks (V2 individual block types)

V2 Template Recipe (full JSON bodies)

Complete request bodies for the 5-step V2 notification template workflow.

Step 1 — Create template (required: name, content)

POST /notifications
{
  "notification": {
    "name": "Order Shipped",
    "tags": ["transactional"],
    "brand": null,
    "subscription": null,
    "routing": null,
    "content": {
      "version": "2022-01-01",
      "elements": [
        {
          "type": "channel",
          "channel": "email",
          "elements": [
            { "type": "meta", "title": "Your order shipped" },
            { "type": "text", "content": "Hi {{data.name}}, your order {{data.order_id}} is on its way." }
          ]
        }
      ]
    }
  },
  "state": "DRAFT"
}

Response includes id (e.g. nt_01abc123). Pass "state": "PUBLISHED" to skip steps 2–4.

Step 2 — Update content (optional)

PUT /notifications/{id}/content
{
  "content": {
    "version": "2022-01-01",
    "elements": [
      {
        "type": "channel",
        "channel": "email",
        "elements": [
          { "type": "meta", "title": "Updated Subject" },
          { "type": "text", "content": "Updated body text." }
        ]
      }
    ]
  },
  "state": "DRAFT"
}

Step 3 — Create routing strategy (required: name, routing)

POST /routing-strategies
{
  "name": "Email Only",
  "routing": {
    "method": "single",
    "channels": ["email"]
  }
}

Response includes id (e.g. rs_01xyz). Associate with template via PUT /notifications/{id} with "routing": { "strategy_id": "rs_01xyz" }.

Step 4 — Publish

POST /notifications/{id}/publish
{}

Empty body publishes the current draft. Returns 204.

Step 5 — Send

POST /send
{
  "message": {
    "to": { "user_id": "user-123" },
    "template": "nt_01abc123",
    "data": { "name": "Alice", "order_id": "ORD-456" }
  }
}

Migration Guides

Other Optional

API Reference

  • API Reference: Full REST API documentation with request/response schemas for all endpoints.
Related

Workflow automation software for everyone. Automate your work across 7,000+ app integrations—no developers, no IT tickets, no delays.

/llms.txt
27,156 tokens
/llms-full.txt
529,536 tokens
SaaS & Products

Dub.co is the open-source link management platform for modern marketing teams to create marketing campaigns, link sharing features, and referral programs.

/llms.txt
5,889 tokens
/llms-full.txt
216,953 tokens
SaaS & Products

Campsite is designed for distributed teams to cut through the noise of daily work — move faster with more transparent, organized, and thoughtful conversations.

/llms.txt
481 tokens
SaaS & Products

We help modern software companies drive more up-sells, cross-sells and renewals through industry leading product onboarding, engagement, and adoption.

/llms.txt
4,213 tokens
/llms-full.txt
82,141 tokens
SaaS & Products

Respond to customers on any channel, sync with your entire team and turn support conversations into product strategy.

/llms.txt
7,036 tokens
/llms-full.txt
111,729 tokens
SaaS & Products

Platform for businesses to send gifts to customers/employees.

/llms.txt
4,241 tokens
/llms-full.txt
55,038 tokens
SaaS & Products

Loops makes email marketing for modern SaaS companies easy. It's the best way to create, send and track beautiful email campaigns.

/llms.txt
6,337 tokens
/llms-full.txt
277,564 tokens
SaaS & Products

Drive pipeline with 10+ intent data sources, AI, and automation. Scale prospecting, personalization, engagement in one unified workflow.

/llms.txt
4,295 tokens
/llms-full.txt
88,159 tokens
SaaS & Products