
Most teams can't answer a basic question about their own product: what notifications are you sending, and are they working?
This post walks through a full audit using Courier's CLI and MCP server from inside your coding environment. You'll need a free Courier API key. Every CLI command below also works as a typed MCP tool call in Cursor, Claude Code, or any agent that supports Courier's AI tooling.
npm install -g @trycourier/cli
export COURIER_API_KEY="your-api-key"courier notifications list --format jsonThis returns every template, its ID, and its state (published vs. draft). If you expected 15 and there are 40, the audit was overdue.
Having a template doesn't mean it's firing. Check what's actually going out:
courier messages list --format json
# Count by delivery status
courier messages list --format json \
--transform "results.#.status" | sort | uniq -c| Status | What it means |
|---|---|
| DELIVERED | Reached the device or inbox |
| SENT | Handed to provider, not yet confirmed |
| UNDELIVERABLE | Provider rejected it (bad address, bounce, block) |
| UNROUTABLE | No valid channel found for this user |
UNDELIVERABLE and UNROUTABLE are your red flags. A handful is normal. A pattern means something is broken.
Pick a message and walk its lifecycle:
# Status overview
courier messages retrieve --message-id "1-abc123" --format pretty
# Full event timeline: enqueued, sent, delivered, opened, clicked
courier messages history --message-id "1-abc123" --format pretty
# What was actually rendered and sent
courier messages output --message-id "1-abc123" --format prettyDo this for a sample of each notification type. You're looking for where things fail (provider rejection? routing skip? preference block?) and whether the rendered content still makes sense. Stale copy, broken template variables, subject lines from 2024 -- this is where you find them.
For template-level inspection before data gets injected:
courier notifications content --notification-id "TEMPLATE_ID" --format json
courier notifications draft-content --notification-id "TEMPLATE_ID" --format jsonIf the published and draft versions have diverged, someone started editing and never shipped it.
Every notification depends on data. Cross-reference what a template expects with what's actually being passed:
# Data payload from a specific send
courier messages retrieve --message-id "1-abc123" --format json
# What's on the user's profile
courier profiles retrieve --user-id "user-123" --format jsonBuild a simple map per notification type: what data it needs, where that data comes from, and whether it's consistently present. This is where you find silent failures -- the notification "works" but renders with blank fields because an upstream service isn't passing everything.
For B2B products, notification health varies by customer org. list_messages accepts a tenant_id filter directly:
courier tenants list --format json
courier messages list --format json --tenant-id "acme-corp"
courier tenants retrieve --tenant-id "acme-corp" --format jsonLook for tenants with outdated brand configs, concentrated delivery failures, or notification setups that haven't been touched since onboarding.
Notifications users can't opt out of are a churn risk.
courier preferences retrieve --user-id "user-123" --format prettyCross-reference with your template inventory. Every non-transactional notification should have a preference topic. If your marketing digest doesn't have a toggle, you're one annoyed user away from a full unsubscribe.
Based on everything you've pulled, flag every notification that fits:
Kill it: UNDELIVERABLE/UNROUTABLE rate >10%. Zero engagement over 30 days. References features that no longer exist.
Revise it: Template variables rendering blank. Published/draft versions diverged. No preference topic assigned. Sent to channels without consent.
Batch or digest it: High volume, low urgency. Same notification type firing multiple times in minutes. Higher opt-out rates than other categories.
Investigate: Delivery rates that vary by tenant. No clear owner. Template untouched for 12+ months but still actively sending.
Take this list back to your team. The data backs up every recommendation.

What Siri AI means for your email, SMS, and push
Siri AI shipped with iOS 27 and changes what happens to a message after it's delivered. It reads urgent notifications aloud, searches Apple Mail and Messages, can delete or unsubscribe from your email on request, and will soon answer "where's my order?" through apps. Here's what each change means for your email, SMS, and push, and what to do now.

Catch broken lifecycle journeys with synthetic users and AI
Paste one prompt into a coding agent and get a local test of your onboarding journey: synthetic users, real timing, and every send explained. Catch stale reminders before your customers do.

Test Courier emails end to end with your AI agent
Give your coding agent an AgentMail inbox, and it can test your Courier emails the way a user would: send the change, check what arrives, review how it renders, and fix what it finds before the change reaches Production.