For developers
How do you send an iMessage programmatically?
Through a third-party REST provider, which is the only route that survives production. The alternatives are AppleScript on a Mac you own, a self-hosted bridge such as BlueBubbles, or Apple Messages for Business — which is official but can only answer conversations the customer starts.
The four routes
| Method | Setup | Holds up in production? | Cost |
|---|---|---|---|
| Third-party REST API | About an hour | Yes — this is what the category is for | $20–$250/line/month |
| Self-hosted bridge (BlueBubbles) | An afternoon | Personal projects only | Free, plus your uptime |
| AppleScript on a Mac | Minutes | No — no delivery signal, no replies | Free |
| Apple Messages for Business | Weeks to months | Yes, but inbound-only | Via a CSP contract |
The one-request version
curl --request POST 'https://api.sendblue.co/api/send-message' \\
--header 'sb-api-key-id: YOUR_KEY_ID' \\
--header 'sb-api-secret-key: YOUR_SECRET' \\
--header 'Content-Type: application/json' \\
--data-raw '{
"number": "+19998887777",
"content": "Your 2pm window is confirmed.",
"status_callback": "https://acme.co/webhooks/imessage"
}'Sendblue's documented shape. Every provider differs in field names and matches in structure.
Why AppleScript stops being the answer
It sends from your personal Apple ID, so replies land in your own Messages app and nowhere else. It returns no delivery confirmation. It needs the Mac awake, unlocked and online. And business volume from a personal Apple ID is the fastest route to getting that account restricted — which affects far more than Messages.
The full guide with working code for each route.
Two responses, not one
| Stage | What you get | What it means |
|---|---|---|
| Synchronous | A message handle and a status | The provider accepted it. Nothing has reached a phone. |
| Webhook: sent | Handed to Apple | In flight |
| Webhook: delivered | Apple confirmed the device | This is the one worth counting |
| Webhook: read | Recipient opened it | Only if they have read receipts on — never a reliable metric |
| Webhook: failed | Wrong number, not on iMessage, or line trouble | Alert if the rate moves |
Count delivered, not 200 OK
A throttled line usually still returns 200. Your dashboard stays green while delivery quietly collapses. Track delivered events as a ratio of sends and alert on a floor you pick in advance. What to instrument.
Handling the failures correctly
A 429 or a 5xx will very likely succeed in four seconds. A 422 for a recipient not on iMessage will fail identically forever — retrying it wastes your rate limit and never delivers. Route those to SMS fallback instead. Retry logic that works.
This page also answers
- send imessage api
Further reading
Go deeper
Send an iMessage programmatically
Four ways to send an iMessage from code — AppleScript, a self-hosted bridge, a third-party REST API, and Apple's own channel — with working examples and an honest account of which ones survive production.
10 min readOperationsiMessage from Node.js
A working Node.js integration: a typed client, webhook verification with Express, retries that respect rate limits, and a send queue that will not get your line flagged.
12 min readComparisonsBlueBubbles vs paid APIs
The open-source self-hosted option is real and works. Here is an honest account of what it costs you in time and risk, and the cases where it is the right answer.
7 min read