sendblue-api

Send and receive iMessage, SMS, and RCS from application code via the Sendblue HTTP API — text, media, group messages, send styles, reactions, typing indicators, status callbacks, and inbound webhooks.

5 stars

Best use case

sendblue-api is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Send and receive iMessage, SMS, and RCS from application code via the Sendblue HTTP API — text, media, group messages, send styles, reactions, typing indicators, status callbacks, and inbound webhooks.

Teams using sendblue-api should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/sendblue-api/SKILL.md --create-dirs "https://raw.githubusercontent.com/FrancoStino/opencode-skills-collection/main/bundled-skills/sendblue/sendblue-api/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/sendblue-api/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How sendblue-api Compares

Feature / Agentsendblue-apiStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Send and receive iMessage, SMS, and RCS from application code via the Sendblue HTTP API — text, media, group messages, send styles, reactions, typing indicators, status callbacks, and inbound webhooks.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# Sendblue API

## Overview

Sendblue is a REST API that sends iMessage (blue bubbles), SMS, and RCS from a provisioned phone number. Everything is plain JSON over HTTPS — no SDK is required. The API covers outbound 1:1 and group sends, iMessage effects, reactions, typing indicators, status callbacks, and inbound webhooks.

## When to Use This Skill

- Use when writing application code (server, worker, function) that sends Sendblue messages as part of a long-running service.
- Use when receiving inbound messages via webhooks.
- Use when you need features the CLI does not expose: send styles, reactions, group messages, typing indicators, status callbacks, media uploads, or the contacts API beyond basic CRUD.
- Reach for [[sendblue-cli]] instead for shell-context outbound: one-shot scripts, cron jobs, agent hooks, "ping me when X" workflows.

## How It Works

### Step 1: Authenticate

```
https://api.sendblue.com
```

Every request needs two headers:

```
sb-api-key-id: <YOUR_API_KEY_ID>
sb-api-secret-key: <YOUR_API_SECRET>
Content-Type: application/json
```

Keep both values server-side — never ship them to a browser or mobile client.

### Step 2: Send a message

```bash
curl -X POST https://api.sendblue.com/api/send-message \
  -H "sb-api-key-id: $KEY_ID" \
  -H "sb-api-secret-key: $SECRET" \
  -H 'Content-Type: application/json' \
  -d '{
    "number": "+15551234567",
    "from_number": "+1YOUR_SENDBLUE_NUMBER",
    "content": "Hello from the API!"
  }'
```

Phone numbers must be E.164. `from_number` must be a line you own — list yours with `GET /api/lines`.

### Step 3: Track delivery

The synchronous response includes a `message_handle` (Apple GUID — persist this; you need it for reactions and replies) and a `status` from `REGISTERED`, `PENDING`, `QUEUED`, `ACCEPTED`, `SENT`, `DELIVERED`, `DECLINED`, `ERROR`. Only `DELIVERED` means it landed. Use `status_callback` instead of polling `/api/status`.

### Step 4: Receive inbound

Configure webhook URLs in the dashboard or via `POST /api/account/webhooks`. Sendblue POSTs JSON to your endpoint. Respond with 2xx promptly — non-2xx triggers retries and duplicate deliveries. Event types: `receive`, `outbound`, `typing_indicator`, `call_log`, `line_blocked`, `line_assigned`, `contact_created`.

## Core Endpoints

| Method | Path | Purpose |
|--------|------|---------|
| POST | `/api/send-message` | Send a 1:1 message (text and/or media) |
| POST | `/api/send-group-message` | Send to multiple recipients |
| POST | `/api/create-group` | Create a named group thread |
| POST | `/api/send-reaction` | Send a tapback (love/like/dislike/laugh/emphasize/question) |
| POST | `/api/send-typing-indicator` | Show "typing…" in the recipient's thread |
| POST | `/api/mark-read` | Send a read receipt |
| POST | `/api/upload-file` / `/api/upload-media-object` | Upload media (direct or from URL) |
| GET | `/api/status` | Poll a message's delivery status |
| GET | `/api/evaluate-service` | Check whether a number is on iMessage |
| GET | `/api/v2/messages` / `/api/v2/messages/:id` | Read message history |
| GET / POST / PUT / DELETE | `/api/v2/contacts[...]` | Manage contacts |
| GET | `/api/lines` | List your Sendblue phone numbers |
| POST | `/api/account/webhooks` | CRUD webhook subscriptions |

## Examples

### Example 1: Send with media, effects, and a status callback

```json
POST /api/send-message
{
  "number": "+15551234567",
  "from_number": "+1YOUR_SENDBLUE_NUMBER",
  "content": "Optional text",
  "media_url": "https://example.com/img.jpg",
  "send_style": "celebration",
  "status_callback": "https://yourapp.com/sendblue/status"
}
```

`content` and/or `media_url` is required. `send_style` is iMessage-only — valid values: `celebration`, `shooting_star`, `fireworks`, `lasers`, `love`, `confetti`, `balloons`, `spotlight`, `echo`, `invisible`, `gentle`, `loud`, `slam`. Ignored on SMS. Text up to 18,996 chars; media up to 100 MB on iMessage, 5 MB on SMS.

### Example 2: Group message

```json
POST /api/send-group-message
{
  "numbers": ["+15551234567", "+15557654321"],
  "from_number": "+1YOUR_SENDBLUE_NUMBER",
  "content": "Hey team"
}
```

The response returns a `group_id` — persist it to send follow-ups into the same thread instead of creating a new one each time.

### Example 3: React to a message

```json
POST /api/send-reaction
{
  "from_number": "+1YOUR_SENDBLUE_NUMBER",
  "message_handle": "<message_handle from prior send>",
  "reaction": "love"
}
```

Reactions only work on iMessage and need the original message's `message_handle`. Valid values: `love`, `like`, `dislike`, `laugh`, `emphasize`, `question`.

### Example 4: Inbound webhook payload (`receive`)

```json
{
  "accountEmail": "you@example.com",
  "content": "Reply text",
  "media_url": "https://...",
  "is_outbound": false,
  "number": "+15551234567",
  "from_number": "+1YOUR_SENDBLUE_NUMBER",
  "service": "iMessage",
  "group_id": "...",
  "date_sent": "2024-01-01T12:00:00Z"
}
```

Status callback payloads (`outbound`) mirror the send-message response and update as the message moves through `SENT` → `DELIVERED` (or `ERROR`).

## Best Practices

- ✅ **Persist `message_handle` on every send.** You need it for reactions, replies, and correlating status callbacks.
- ✅ **Use `status_callback` over polling.** It's lower-cost and more accurate than `GET /api/status`.
- ✅ **Return 2xx fast from your webhook**, then process async. Non-2xx triggers duplicate deliveries.
- ✅ **Check service with `/api/evaluate-service`** before relying on iMessage-only features for a recipient.
- ✅ **Rehost inbound media on receipt** — media URLs expire in ~30 days.
- ❌ **Don't ship `sb-api-key-id` / `sb-api-secret-key` to a client.** They are server-side credentials.
- ❌ **Don't treat a 200 on `/api/send-message` as delivery.** It only means "accepted".

## Limitations

- Synchronous send responses only report acceptance, not delivery. Final state arrives via `status_callback` or `GET /api/status`.
- `send_style` silently no-ops on SMS (green-bubble recipients).
- Inbound media URLs expire in ~30 days.
- Per-line rate limits apply; bursting many sends from one number can trip Apple's spam heuristics — pace them or split across lines.
- Reactions and effects are iMessage-only.

## Security & Safety Notes

- Keep `sb-api-key-id` and `sb-api-secret-key` server-side. They are not safe in browser, mobile, or CI logs.
- Treat every outbound send, contact/webhook mutation, read receipt, reaction, or typing indicator as state-changing. Preview the recipient, sender line, content, and callback/webhook changes, then wait for explicit user confirmation before sending.
- Webhook endpoints should be on HTTPS and idempotent — same `message_handle` may arrive more than once.
- Sensitive data in message content is visible in lock-screen previews on the recipient's device. Don't embed secrets, tokens, or full PII — link to an authenticated dashboard or shortened payload instead.
- Rotate API keys from the Sendblue dashboard if either value is exposed; the old pair is invalidated on rotation.

## Common Pitfalls

- **E.164 only.** `5551234567` or `(555) 123-4567` will fail — always send `+15551234567`.
- **`from_number` must be one of your lines.** A spoofed or unprovisioned number returns an error.
- **`send_style` silently no-ops on SMS.** If the recipient is green-bubble, effects don't render — check service first with `/api/evaluate-service` if it matters.
- **Store `message_handle`.** You need it for reactions, replies, and correlating status callbacks back to your records.
- **Media URLs expire in ~30 days.** If you need durable media from inbound webhooks, download and re-host on receipt.
- **Status is async.** A 200 on `/api/send-message` means accepted, not delivered. Use `status_callback` rather than blocking on the synchronous response.
- **Webhook retries on non-2xx.** Return 200 even when you've decided to ignore the event; otherwise expect duplicate deliveries.
- **Rate limits apply per line.** Bursting many sends from one number trips Apple's spam heuristics — pace them or split across lines.

## Related Skills

- `@sendblue-cli` — Shell wrapper for shell-context outbound (scripts, cron, agent hooks). Use it when you don't need a full HTTP integration.
- `@sendblue-notify` — Patterns and copy rules for outbound "text me when X is done" notifications layered on top of the API or CLI.

## Links

- Full reference: <https://docs.sendblue.com/>
- Sendblue: <https://sendblue.com>
- Useful undocumented-here features: carousels (`/api/send-carousel`), FaceTime/contact-card sharing, advanced webhook filtering, contacts API beyond basic CRUD — see the docs site.

Related Skills

sendblue-notify

5
from FrancoStino/opencode-skills-collection

Text the user's phone when a long-running task, agent turn, or scheduled job finishes — via @sendblue/cli for outbound, optionally wired to a Claude Code Stop hook for automatic fire.

sendblue-cli

5
from FrancoStino/opencode-skills-collection

Send iMessage and SMS from the shell via the @sendblue/cli npm package — outbound sends, contact management, and account setup with no API client or webhook server required.

zustand-store-ts

5
from FrancoStino/opencode-skills-collection

Create Zustand stores following established patterns with proper TypeScript types and middleware.

zoom-automation

5
from FrancoStino/opencode-skills-collection

Automate Zoom meeting creation, management, recordings, webinars, and participant tracking via Rube MCP (Composio). Always search tools first for current schemas.

zoho-crm-automation

5
from FrancoStino/opencode-skills-collection

Automate Zoho CRM tasks via Rube MCP (Composio): create/update records, search contacts, manage leads, and convert leads. Always search tools first for current schemas.

zod-validation-expert

5
from FrancoStino/opencode-skills-collection

Expert in Zod — TypeScript-first schema validation. Covers parsing, custom errors, refinements, type inference, and integration with React Hook Form, Next.js, and tRPC.

zipai-optimizer

5
from FrancoStino/opencode-skills-collection

Ultra-dense token optimizer skill for prompt caching, log pruning, AST-based inspection, and minified JSON payloads.

zeroize-audit

5
from FrancoStino/opencode-skills-collection

Detects missing zeroization of sensitive data in source code and identifies zeroization removed by compiler optimizations, with assembly-level analysis, and control-flow verification. Use for auditing C/C++/Rust code handling secrets, keys, passwords, or other sensitive data.

zendesk-automation

5
from FrancoStino/opencode-skills-collection

Automate Zendesk tasks via Rube MCP (Composio): tickets, users, organizations, replies. Always search tools first for current schemas.

zapier-make-patterns

5
from FrancoStino/opencode-skills-collection

No-code automation democratizes workflow building. Zapier and Make (formerly Integromat) let non-developers automate business processes without writing code. But no-code doesn't mean no-complexity - these platforms have their own patterns, pitfalls, and breaking points.

youtube-summarizer

5
from FrancoStino/opencode-skills-collection

Extract transcripts from YouTube videos and generate comprehensive, detailed summaries using intelligent analysis frameworks

youtube-full

5
from FrancoStino/opencode-skills-collection

Fetch YouTube transcripts, search videos, browse channels, and extract playlists via TranscriptAPI — no yt-dlp, no Google API key, works from any cloud server.