--- title: Chat SDK adapter | Sendblue Docs description: Connect Vercel Chat SDK bots to iMessage, SMS, and RCS through Sendblue. --- The Sendblue Chat SDK adapter connects [Chat SDK](https://chat-sdk.dev) bots to iMessage, SMS, and RCS. Use it when you want one bot implementation to handle Sendblue conversations alongside Slack, Teams, Discord, Telegram, email, or other Chat SDK adapters. Sendblue is committed to maintaining the Chat SDK adapter integration path as Chat SDK and the Sendblue API evolve. For adapter issues, open an issue in the adapter repository. For Sendblue account, delivery, or credential support, email . ## Install Install Chat SDK, the Sendblue adapter, and an in-memory state adapter for local development: Terminal window ``` npm install chat chat-adapter-sendblue @chat-adapter/state-memory ``` The Sendblue adapter uses the official Sendblue TypeScript SDK under the hood. For production, use a persistent state adapter such as `@chat-adapter/state-redis` instead of in-memory state. ## Environment Variables The factory reads credentials from environment variables by default: | Variable | Required | Description | | ------------------------------ | -------- | -------------------------------------------------------- | | `SENDBLUE_API_KEY` | Yes | Your Sendblue API key ID | | `SENDBLUE_API_SECRET` | Yes | Your Sendblue API secret key | | `SENDBLUE_FROM_NUMBER` | Yes | Your Sendblue number in E.164 format | | `SENDBLUE_WEBHOOK_SECRET` | No | Shared secret for webhook verification | | `SENDBLUE_STATUS_CALLBACK_URL` | No | Status callback URL for outbound message delivery events | You can find your API credentials and assigned Sendblue numbers in the [dashboard](https://dashboard.sendblue.com), or with the CLI: Terminal window ``` npm install -g @sendblue/cli sendblue setup sendblue show-keys sendblue lines ``` ## Create a Bot ``` import { Chat } from "chat"; import { createSendblueAdapter } from "chat-adapter-sendblue"; import { createMemoryState } from "@chat-adapter/state-memory"; const chat = new Chat({ userName: "imessage-bot", adapters: { sendblue: createSendblueAdapter(), }, state: createMemoryState(), }); chat.onDirectMessage(async (thread, message) => { await thread.post(`Got it: ${message.text}`); }); ``` You can also pass credentials explicitly: ``` import { createSendblueAdapter } from "chat-adapter-sendblue"; const sendblue = createSendblueAdapter({ apiKey: process.env.SENDBLUE_API_KEY, apiSecret: process.env.SENDBLUE_API_SECRET, defaultFromNumber: "+15551234567", webhookSecret: process.env.SENDBLUE_WEBHOOK_SECRET, }); ``` ## Handle Webhooks Create a webhook endpoint in your application and route incoming Sendblue webhook requests to Chat SDK: app/api/webhooks/sendblue/route.ts ``` import { chat } from "@/lib/chat"; export async function POST(request: Request) { await chat.initialize(); return chat.webhooks.sendblue(request); } ``` Then configure your Sendblue receive webhook to point at that endpoint: ``` https://your-app.com/api/webhooks/sendblue ``` If you set `SENDBLUE_WEBHOOK_SECRET`, Sendblue should send the same secret with webhook requests. The adapter verifies the `sb-signing-secret` header by default. You can override the header name: ``` createSendblueAdapter({ webhookSecret: process.env.SENDBLUE_WEBHOOK_SECRET, webhookSecretHeader: "x-custom-header", }); ``` ## Send Messages Use normal Chat SDK thread methods: ``` await thread.post("Hello from Sendblue via Chat SDK."); ``` The adapter sends outbound messages through Sendblue with iMessage-first delivery and automatic SMS/RCS fallback where available. ## Use Sendblue Features Directly For Sendblue APIs that are outside the standard Chat SDK adapter interface, access the underlying Sendblue SDK: ``` import type { SendblueAdapter } from "chat-adapter-sendblue"; const adapter = chat.getAdapter("sendblue") as SendblueAdapter; const sdk = adapter.getSdk(); await sdk.messages.send({ number: "+15551234567", from_number: process.env.SENDBLUE_FROM_NUMBER!, content: "Here is a photo.", media_url: "https://example.com/photo.jpg", }); ``` This is useful for media messages, contact operations, webhook management, groups, and any new Sendblue API feature before it has a first-class Chat SDK abstraction. ## Supported Features | Feature | Support | | ---------------------------------------- | ---------------------------------------------------------------------------- | | Inbound messages | Yes | | Outbound messages | Yes | | iMessage, SMS, and RCS service filtering | Yes | | Delivery status callbacks | Yes | | Typing indicators | Yes for 1:1 conversations | | Tapback reactions | Add reactions only | | Message history | Yes, with cursor pagination | | Media attachments | Inbound media parsing; outbound media through direct SDK access | | Message editing | Not supported by iMessage via API | | Unsend/delete | No recipient-side unsend; `deleteMessage` does not remove delivered messages | ## Accept SMS and RCS By default, process only iMessage traffic. To also accept SMS and RCS inbound messages: ``` createSendblueAdapter({ allowedServices: ["iMessage", "SMS", "RCS"], }); ``` ## Production Notes - Use a persistent Chat SDK state adapter in production so subscribed threads and conversation state survive deploys. - Store Sendblue API keys in environment variables or your host’s secret manager. - Persist inbound media URLs if you need long-term access. Sendblue media URLs can expire. - Keep your `from_number` stable per contact so end users always see the same Sendblue line. - Use the [Lookup API](/guides/check-imessage-support/index.md) before high-volume sends if you need to know whether a recipient supports iMessage. ## Related Resources - [Send messages](/getting-started/sending-messages/index.md) - [Receive messages](/getting-started/receiving-messages/index.md) - [Webhooks](/getting-started/webhooks/index.md) - [Typing indicators](/guides/typing-indicator/index.md) - [Client packages](/getting-started/client-packages/index.md)