Skip to content
Agentmart
Submit a tool

courier

Use when building notifications with Courier across email, SMS, push, in-app inbox, Slack, Teams, and WhatsApp: sends, templates, translations, email client…

Skill by trycourier

IndexedMIT★ 15
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/trycourier-courier

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Use when building notifications with Courier across email, SMS, push, in-app inbox, Slack, Teams, and WhatsApp: sends, templates, translations, email client previews, Elemental, journeys, preferences, routing, CLI and MCP.

Use cases: productivity, agent-building

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md and code. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/courier

What's inside

Skill name
courier
Description
Use when building notifications with Courier across email, SMS, push, in-app inbox, Slack, Teams, and WhatsApp: sends, templates, translations, email client previews, Elemental, journeys, preferences, routing, CLI and MCP.
License
MIT
Instructions
244 lines in SKILL.md · view on GitHub

Files (42)

  • SKILL.md
  • email.md · references/channels/
  • inbox.md · references/channels/
  • ms-teams.md · references/channels/
  • push.md · references/channels/
  • slack.md · references/channels/
  • sms.md · references/channels/
  • whatsapp.md · references/channels/
  • audiences.md · references/guides/
  • batching.md · references/guides/
  • brands.md · references/guides/
  • bulk.md · references/guides/
  • cli.md · references/guides/
  • device-preview.md · references/guides/
  • digests.md · references/guides/
  • elemental.md · references/guides/
  • journeys.md · references/guides/
  • localization.md · references/guides/
  • mcp.md · references/guides/
  • metrics.md · references/guides/
  • multi-channel.md · references/guides/
  • patterns.md · references/guides/
  • preferences.md · references/guides/
  • providers.md · references/guides/
  • quickstart.md · references/guides/
  • reliability.md · references/guides/
  • routing-strategies.md · references/guides/
  • scheduling.md · references/guides/
  • templates-as-code.md · references/guides/
  • templates.md · references/guides/
  • tenants.md · references/guides/
  • throttling.md · references/guides/
  • webhooks.md · references/guides/
  • auth.md · references/inbox/
  • legacy-v7.md · references/inbox/
  • react-native.md · references/inbox/
  • react.md · references/inbox/
  • rendering.md · references/inbox/
  • web-components.md · references/inbox/
  • lifecycle-marketing.md · references/
  • sdk-reference.md · references/
  • transactional.md · references/

SKILL.md (first lines)

# Courier

Integrate Courier, add notification features, and debug delivery problems across email, SMS, push, in-app inbox, Slack, Teams, and WhatsApp.

## The Model

One `send` call does the whole job. You address a **user** (or list, audience, or tenant), content comes from a **template** or inline, **routing** picks the channels, and **preferences** gate delivery. Courier renders, routes, and delivers; your app supplies the trigger and the data.

Multi-step flows (anything with a delay, a branch, or aggregation) are **journeys**, defined as JSON and invoked by API.

## How to Use This Skill

1. **Route first.** [Where to Look](#where-to-look) picks the 1–2 files for the task. Don't read the tree.
2. **Ask when the request is ambiguous.** Channel? Transactional or lifecycle? New code or existing? Which language? Skip the questions when the request is already specific.
3. **Verify shapes against a [live source](#verifying-against-live-sources)** rather than memory. The installed SDK's own types are ground truth.
4. **Apply the rules.** [Universal Rules](#universal-rules) and each file's Quick Reference are constraints, not suggestions. (`sdk-reference.md` is a lookup table and has none.)

If the project already has `@trycourier/courier` or `trycourier` installed, skip quickstart's install steps and assume `client` exists.

## Addressing a Send

`message.to` accepts one of:

| Form | Sends to |
|---|---|
| `{ user_id: "user-123" }` | A stored user profile. The usual case |
| `{ email: "…" }` / `{ phone_number: "…" }` | An inline recipient, no profile required |
| `{ list_id: "…" }` | Every subscriber of a list |
| `{ list_pattern: "eng.*" }` | Every list matching the pattern |
| `{ audience_id: "…" }` | A filter whose membership Courier stores and keeps current |
| An array of the above | Multiple recipients in one call, with a **hard cap of 500** |

Above 500 ad-hoc recipients, a `to` array returns `400 message.to has N recipients. Max is 500`.
Use a list, an audience, or a [Bulk API job](./references/guides/bulk.md) instead.

Multi-tenant sends carry the tenant as `tenant_id`, either on the recipient (`to.tenant_id`) or in `message.context.tenant_id`. Both load that tenant's brand and preference defaults; pick one and use it consistently.

## Canonical SDK Shape

Ground every Courier code path in this shape. Where a resource file disagrees, this block wins. Confirm against a [live source](#verifying-against-live-sources).

**Node.js (`@trycourier/courier`):**

```typescript
import Courier from "@trycourier/courier";

// Reads process.env.COURIER_API_KEY by default
const client = new Courier();

await client.send.message({
  message: {
    to: { user_id: "user-123" },           // or { email }, { phone_number }, { list_id }, { audience_id }, etc.
    template: "nt_01kmrbq6ypf25tsge12qek41r0", // OR content: { title, body } / { version, elements }
    data: { /* merge variables */ },
  },
  "Idempotency-Key": "order-confirmation-12345",
});
```

**Python (`trycourier`):**

```python
from courier import Courier

# Reads COURIER_API_KEY from env by default
client = Courier()

client.send.message(
    message={
        "to": {"user_id": "user-123"},
        "template": "nt_01kmrbq6ypf25tsge12qek41r0",
        "data": {},
    },
    idempotency_key="order-confirmation-12345",
)
```

Full method-name lookup for both SDKs: **[sdk-reference.md](./references/sdk-reference.md)**.

**The 23 namespaces are the complete SDK surface.** If an operation isn't here, it isn't in the SDK:

```
audiences  auditEvents  auth      automations  brands
broadcasts  bulk        digests   inbound      journeys
lists      messages     notifications  previews  profiles
providers  requests     routingStrategies  send  tenants
translations  users     workspacePreferences
```

Sub-namespaces: `automations.invoke`, `automations.runs`, `digests.schedules`, `journeys.runs`, `journeys.templates`, `lists.subscriptions`, `notifications.checks`, `notifications.previews`, `notifications.previews.runs`, `profiles.lists`, `providers.catalog`, `tenants.preferences`, `tenants.preferences.items`, `tenants.templates`, `tenants.templates.versions`, `users.preferences`, `users.tenants`, `users.tokens`, `workspacePreferences.topics`.

`auditEvents` and `inbound` (`inbound.trackEvent`) have no dedicated guide; use MCP or the CLI. `requests.archive` is in [inbox.md](./references/channels/inbox.md).

### Common operations

| Operation | Method |
|---|---|
| Archive a sent message | `client.requests.archive(requestId)` |
| Delete a provider | `client.providers.delete(id)` |
| Change one provider setting, the title, or the alias | `client.providers.patch(id, { settings: { … } })` |
| Replace a provider's whole config (full PUT) | `client.providers.update(id, …)` |
| Subscribe a user to a list | `client.lists.subscriptions.subscribeUser(userId, { list_id })` |
| Set a user's topic preference | `client.users.preferences.updateOrCreateTopic(topicId, { user_id, topic })` |
| Configure a provider | `client.providers.*` · type catalog at `client.providers.catalog.*` |

### Writing a user profile

| Call | HTTP | Behavior |
|---|---|---|
| `client.profiles.create(id, { profile })` | POST | Deep-merge, the everyday write |
| `client.profiles.update(id, { patch: [...] })` | PATCH | JSON Patch (RFC 6902) |
| `client.profiles.replace(id, { profile })` | PUT | Full overwrite; omitted fields are removed |

## Universal Rules

- Use idempotency keys for sends where duplicates would be harmful (payments, security alerts, OTPs)
- Use E.164 format for phone numbers
- Only send to channels the user has asked for or that make sense for the use case. Don't blast every channel by default
- For template sends, pass the Courier-generated `nt_...` ID or a template alias as `template`; treat IDs as opaque, workspace-specific values

From trycourier/courier-skills, MIT.

Signals

Stars
15
Forks
3
Open issues
0
Last commit (this folder)
Oct 22, 2026 (8 days ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from trycourier

Cite this page

courier skill. Agent Mart. https://agentmart.dev/skills/trycourier-courier (last updated 2026-10-24)