Kyle Seyler
December 10, 2025

Twilio owns some of the most critical infrastructure in the notification space. Their SMS API handles billions of messages. SendGrid processes email at scale. Segment aggregates customer data across your entire stack. But using these tools together? That's where things get complicated.
This guide covers how to integrate all three Twilio products through Courier, turning what would normally be months of integration work into something you can ship this week. For a full list of supported channels and providers, see Courier's integrations page.
Before diving into setup, here's what each piece brings to the table:
Twilio SMS handles programmable messaging across SMS, MMS, WhatsApp, and RCS. They've got phone number inventory across 180+ countries and 99.95% monthly uptime. For time-sensitive notifications like OTP codes, delivery updates, and appointment reminders, SMS still beats every other channel for reliability.
SendGrid (acquired by Twilio in 2019) processes billions of emails monthly and has become the default for teams that need high deliverability without managing mail servers. They offer dynamic templating, analytics, and a unified platform for both transactional and marketing messages.
Segment (acquired by Twilio in 2020) is the customer data platform that collects user events and pipes them to your analytics, marketing, and product tools. Instead of building direct integrations with every destination, you instrument once and route everywhere.
The catch: managing these integrations separately means maintaining three different APIs, three sets of credentials, three templating systems, and zero coordination between channels. That's the problem Courier solves.
Twilio knows this better than anyone. When they needed to unify notifications for their own platform serving 10+ million developers, they chose Courier. As Raghav Katyal, Technical Lead at Twilio, put it: "We chose Courier because the depth of the inbox and multi-channel integrations allowed us to choose one notification platform for all products and teams at Twilio." They now use Courier to sync SendGrid email with their in-app notification center, managing everything from onboarding flows to marketplace transactions through a single system.
Start by connecting your Twilio account to Courier. You'll need three things from your Twilio console (see the full Twilio integration docs for detailed setup):
In Courier, navigate to Integrations, find Twilio under SMS providers, and paste in these credentials.
If you don't already have an SMS-enabled number, grab one from the Twilio console:
Next, create a Messaging Service to link your number:
Copy the Service SID and add it to your Courier Twilio configuration. Done.
Once configured, sending an SMS through Courier looks like this (see SDK documentation for all supported languages):
Copied!
const { CourierClient } = require("@trycourier/courier");const courier = CourierClient({ authorizationToken: "YOUR_AUTH_TOKEN" });await courier.send({message: {to: {user_id: "user_123",phone_number: "+15555555555"},content: {body: "Your order #{{order_id}} has shipped. Track it here: {{tracking_url}}"},routing: {method: "single",channels: ["sms"]}}});
The phone_number field in the recipient profile tells Courier where to deliver (see user management docs for all profile options). Variables wrapped in double curly braces get populated from your data payload.
Need to pass specific parameters directly to the Twilio API? Use overrides. Note that using overrides bypasses Courier's status polling, so use them only when necessary:
Copied!
await courier.send({message: {to: {user_id: "user_123",phone_number: "+15555555555"},content: {body: "Your verification code is {{code}}"},routing: {method: "single",channels: ["sms"]},providers: {twilio: {override: {body: {statusCallback: "https://yourapp.com/webhooks/sms-status",validityPeriod: 300}}}}}});
This sends status callbacks to your webhook and sets a 5-minute validity window for the message.
SendGrid integration follows a similar pattern. From your SendGrid console (see full SendGrid integration docs):
In Courier, find SendGrid under Email providers in your Channels configuration and enter:
If you've already built templates in SendGrid, you don't have to recreate them. Courier can import your SendGrid Dynamic Templates directly from the Courier SendGrid configuration page:
This preserves your existing work while giving you Courier's orchestration on top.
Copied!
await courier.send({message: {to: {user_id: "user_123",email: "customer@example.com"},template: "ORDER_CONFIRMATION",data: {customer_name: "Alex",order_id: "ORD-78912",order_total: "$149.99",items: [{ name: "Widget Pro", qty: 2 },{ name: "Gadget Max", qty: 1 }]}}});
Courier routes this to SendGrid automatically based on your channel configuration. If you want to send through SendGrid specifically (useful if you have multiple email providers configured), add explicit routing:
Copied!
routing: {method: "single",channels: ["email"],providers: ["sendgrid"]}
To get delivery events back from SendGrid into Courier (see full setup guide):
This lets you see delivered, opened, clicked, and bounced events in your Courier logs.
Segment changes how you think about triggering notifications. Instead of calling Courier's send API from your application code every time something happens, you instrument events in Segment and let those events flow to Courier automatically. See the full Segment integration docs for details.
Once connected, three types of Segment events flow into Courier:
Identify calls update Courier recipient profiles. When a user's email or phone number changes in Segment, it automatically syncs to Courier.
Copied!
analytics.identify('user_123', {email: 'alex@example.com',phone: '+15555555555',name: 'Alex Chen',plan: 'pro'});
Track calls record user actions that can trigger automations. These appear in Courier with a track/ prefix.
Copied!
analytics.track('Order Completed', {order_id: 'ORD-78912',total: 149.99,items: ['Widget Pro', 'Gadget Max']});
Group calls associate users with organizations, useful for B2B notification logic and tenant-based routing.
Here's where it gets powerful. In Courier, you can create automations that fire when specific Segment events arrive:
track/Order Completed)Now every time that event fires in Segment, Courier sends the notification. No additional code in your app.
Example automation flow:
Copied!
Trigger: track/Order Completed↓Wait: 2 hours↓Condition: order.total > 100↓Send: "Thanks for your order" (Email via SendGrid)↓Send: "Your order confirmation" (SMS via Twilio)
This sends a follow-up email 2 hours after high-value orders, with an SMS confirmation. All orchestrated from a single Segment event.
The integration works both directions. Courier can send delivery events back to Segment as a Source (see Courier as a Segment Source docs):

Courier sends these events to Segment:
This closes the loop. Your analytics tools now know not just that you sent a notification, but whether the user engaged with it. You can build cohorts based on notification engagement, trigger follow-ups based on opens, or feed engagement data into your BI stack.
The real value shows up when you combine these integrations. Here's a common pattern using the Courier Send API:
Copied!
await courier.send({message: {to: {user_id: "user_123"},template: "APPOINTMENT_REMINDER",data: {appointment_date: "December 15, 2025",appointment_time: "2:00 PM",location: "123 Main St"},routing: {method: "all",channels: ["email", "sms"]}}});
This sends to both email (via SendGrid) and SMS (via Twilio) in parallel. User profile data determines where messages go: the email field routes to SendGrid, phone_number routes to Twilio.
For priority-based delivery with fallback, use the priority routing method:
Copied!
routing: {method: "priority",channels: ["push", "email", "sms"]}
Courier tries each channel in order until one succeeds. If push fails or the user doesn't have a device token, it falls back to email, then SMS. You can also configure channel priority settings globally in your workspace.
Building direct integrations with Twilio, SendGrid, and Segment yourself isn't impossible. But you end up maintaining three separate codepaths, three sets of error handling, three retry mechanisms, and zero coordination between them.

When you need to add batching (so users don't get 50 separate notifications for 50 events), you build it. When you need scheduling or digest emails, you build it. When you need to honor user preferences across channels, you build that too.
This is exactly why Twilio chose Courier for their own platform. Rather than building custom notification infrastructure on top of their own products, they use Courier to orchestrate it all. See the full Twilio case study for details on how they unified notifications for 10+ million developers.
Courier handles all of this out of the box. You get:
The Twilio ecosystem is powerful. Courier makes it practical to use the whole thing without drowning in integration complexity.
Ready to connect your Twilio stack? Sign up for Courier and send your first notification in under 5 minutes. Free tier includes 10,000 notifications per month.

Cross-Channel Notification State: Why Read Receipts Are Harder Than They Look
When a user opens your email, does your app know? For most products, the answer is no. Each channel tracks its own state. Email has read receipts. Push has delivery confirmation. In-app has its own unread count. They don't talk to each other. Users notice. This guide covers the three approaches to notification state management (channel-first, central-first, event-first), when to use each, and how to implement cross-channel sync without overengineering. Includes state diagrams and practical implementation patterns.
By Kyle Seyler
February 03, 2026

The First 48 Hours: Onboarding Notifications That Keep Users Around
The first 48 hours after signup are when users decide if your product is worth their attention. Every notification you send is an audition. Most teams blow it by sending too much too fast: welcome email, feature announcement, tip, CEO note. Day one and you've already trained users to ignore you. This guide breaks down what to send (and what not to send) in the critical first 48 hours, with timing frameworks, example sequences, and the one metric that matters more than open rate. Includes templates for signup confirmation, activation prompts, and day-two follow-ups.
By Kyle Seyler
February 02, 2026

Terminal-First Development vs. IDE: Building Notification Infrastructure with Claude Code and Cursor
AI coding tools split into two camps: terminal agents (Claude Code) and IDE-augmented editors (Cursor). This guide compares both approaches using Courier's CLI and MCP server as the test case. Covers installation, configuration, and practical workflows for building multi-channel notifications. Includes code examples for user management, bulk operations, and automation triggers. Also explores agent-to-agent communication patterns where AI systems need notification infrastructure to coordinate tasks and escalate to humans.
By Kyle Seyler
January 29, 2026
© 2026 Courier. All rights reserved.