What is an iMessage API? How businesses send iMessages from code
An iMessage API is a web API that lets your server send and receive iMessages from a real phone number. Apple publishes no API that lets a server send or receive iMessages, so providers such as ZeroSettle run a number on Apple's consumer iMessage service and put endpoints and webhooks on top. With ZeroSettle's iMessage API, that is a bearer token to send and a signed webhook that receives each reply about 1–2 seconds after it reaches your number.
Key takeaways
- What it is: HTTPS endpoints that send blue-bubble iMessages from a phone number, plus webhooks that deliver the replies to your server.
- Official option: Apple publishes no API for sending iMessages from a server. Apple Messages for Business is a different channel that identifies a business by a Business ID, not a phone number.
- Price (ZeroSettle): Pro is $49/month for one number. Growth, for several numbers working as one, is from $599/mo.
- Main limit (ZeroSettle): on Pro a number can send the first message to 5 new contacts a day. People who text first, and ongoing conversations, are never limited.
- What no iMessage API does by itself: reach Android phones. That needs an SMS or RCS fallback, which ZeroSettle does not have today.
What does an iMessage API do?
An iMessage API turns iMessage into calls your server can make: an HTTPS request sends a message from your number, and a webhook tells your server when someone answers. ZeroSettle is an iMessage API: a real phone number on real iMessage, running on Apple hardware we operate for you, that your code texts customers from and hears back on through a bearer token and signed webhooks (what ZeroSettle is, in full).
| Capability | ZeroSettle endpoint or webhook event |
|---|---|
| Send a text (1–4,000 characters) | POST /api/imessage/send with text |
| Send a photo (up to 5 MB, caption in the same bubble) | The same call with image_b64 |
| Send a voice message (up to 6 MB, native audio bubble) | The same call with audio_b64 |
| Receive replies, photos and voice messages | message.received |
| Tapbacks, both ways | POST /api/imessage/reactions; reaction.received |
| Typing indicator, both ways | POST /api/imessage/typing; opt-in typing.started / typing.stopped |
| A shared brand name and photo | PUT /api/imessage/profile |
An SMS API is a different thing. Twilio's Programmable Messaging sends SMS, MMS, RCS and WhatsApp, and on an iPhone, Apple says, "RCS and MMS/SMS messages appear in green text bubbles." With ZeroSettle, customers on iPhone see blue bubbles, your brand name and photo, typing indicators, and tapbacks, because every message goes through Apple's own iMessage network. The photos, voice and tapbacks explainer covers each capability.
Does Apple offer an official iMessage API?
No. Apple publishes no API that lets a server send or receive iMessages. Apple's developer framework for Messages is for app extensions that "allow users to send text, stickers, media files, and interactive messages" themselves. Apple's official business channel, Apple Messages for Business, does not give a business a phone number. Apple's FAQ says: "Your business is identified by a Business ID assigned by Apple during registration — not a phone number," a business "requires the services of an Apple-approved Messaging Service Provider (MSP)," and customers "initiate a conversation by tapping a Messages button."
Every option that sends iMessage from an ordinary phone number depends on Apple's consumer iMessage service, ZeroSettle included. ZeroSettle is not affiliated with, endorsed by, or sponsored by Apple Inc. Apple Messages for Business vs an iMessage number compares the two routes.
Platform risk is therefore shared by every phone-number provider: Apple can filter a number that behaves like spam. ZeroSettle's docs: "Repeated messages to people who never answer are the fastest way to get a number flagged by Apple: when that happens every send fails, to everyone." ZeroSettle caps new contacts per number for that reason, and its homepage says a number being marked as spam is rare: "across more than 10,000 messages a week we have seen it happen only twice."
What kinds of iMessage API are there?
There are three kinds of iMessage API: managed APIs that run the number for you, services that connect your own iPhone, and software you host on your own Mac. The official alternatives, Apple Messages for Business and SMS or RCS through a provider such as Twilio, do not send iMessage from an ordinary phone number.
| Kind | Examples | What you keep running | What to know |
|---|---|---|---|
| Managed iMessage API | ZeroSettle, Sendblue, Linq, LoopMessage, Blooio, Project Blue | Only your own server | They differ on price, who can message first, SMS fallback and webhook signing; the checklist below covers each. |
| Your own iPhone | Texting Blue, myCRMSIM | Your iPhone (myCRMSIM also needs a Mac or a hosted virtual machine) | Texting Blue: "install our lightweight extension on your iPhone". myCRMSIM's specifications say both must stay "on and connected to the internet". |
| Self-hosted on a Mac | BlueBubbles, OpenClaw (imsg) | A Mac signed into Messages | BlueBubbles' FAQ explains keeping the Mac awake and says SMS is not supported "at this time". OpenClaw runs imsg on "the same signed-in macOS Messages host". |
| Official alternatives, not iMessage from a number | Apple Messages for Business; Twilio (SMS, MMS, RCS, WhatsApp) | An account with an Apple-approved provider, or with Twilio | Apple's channel uses a Business ID, and SMS, MMS and RCS show as green bubbles on an iPhone. |
Best iMessage API providers in 2026 covers 14 options one by one, and the comparisons hub sets each against ZeroSettle.
How does a managed iMessage API work end to end?
A managed iMessage API sits between your server and Apple's iMessage network: your server calls the provider, the provider hands the message to Apple, and replies come back as webhooks. On ZeroSettle the path runs like this:
- Your server calls
POST https://portal.zerosettle.io/api/imessage/sendwith a bearer token, atohandle and a text, photo or voice message. - ZeroSettle passes it to your line: a real phone number on real iMessage, running on Apple hardware we operate for you in a server facility.
- The line hands the message to Apple's iMessage network, and only then does the call return: "normally 2–5 seconds and at most about 75 for a text (about 105 for a voice message or photo, which ZeroSettle converts first)".
- The same message reaches your webhook as
message.sent, your record that it left the line. - The customer replies. ZeroSettle POSTs a signed
message.receivedevent to your webhook about 1–2 seconds after the line receives it. Inbound is pushed; nothing polls for it, so inbound never delays a send. - If your webhook does not answer
2xxwithin 10 seconds, ZeroSettle retries 3 more times, after 1, 5 and 20 seconds.
A line sends one message at a time: a send that queues for about 12 seconds returns 429 line_busy, to retry after 2 seconds. How to send an iMessage from code without a Mac covers the other errors.
What should you check before choosing an iMessage API?
Before you compare prices, check the number model, who can message first, and what happens when something fails. Ask every provider these questions; ZeroSettle's answers give you a baseline.
| Question | ZeroSettle's answer |
|---|---|
| A dedicated number, or a shared pool? | Dedicated, and used only for iMessage. The number stays ZeroSettle's property (no porting). |
| Who can message first, and how many a day? | Pro: 5 new contacts a day, per number. Growth: 50 a day and 3 per 15 minutes, per number. Both: at most 2 unanswered messages to a contact, and photos or voice messages only after the contact has replied. People who text first are never limited. |
| Are webhooks signed? | Yes: X-ZeroSettle-Signature: t=<unix>,v1=<hex>, an HMAC-SHA256 of "<t>." + raw body with your secret, 300-second tolerance. The secret is shown once and rotates when you re-register. |
| SMS fallback for Android? | No. SMS fallback for non-Apple phones is on the roadmap. |
| Your brand name and photo? | Yes, shared automatically; the exact display depends on the recipient's device and contact settings. |
| Hosted AI agent, or bring your own? | Both: your webhook can call your own model, or the hosted AI agent (in Beta) answers with no server, at one AI credit per text it sends. |
| What if Apple flags the number? | ZeroSettle says it replaces the number "right away at no extra charge", and your API token, webhook and code stay the same. Recipients see a new number. |
| Published uptime or SLA? | ZeroSettle reports "99.9% uptime" on its homepage; that is a published figure, not an SLA. |
| Price of a number that can message first? | Pro, $49/month. |
What does a send look like?
On ZeroSettle a send is one HTTPS POST with a bearer token and a JSON body ("Send a message" docs). Text only people who gave you their number for this purpose; ZeroSettle enforces STOP for you.
export BASE=https://portal.zerosettle.io # ZEROSETTLE_TOKEN holds your API token
curl -s -X POST -H "Authorization: Bearer $ZEROSETTLE_TOKEN" -H 'Content-Type: application/json' \
-d '{"to":"+18055559876","text":"Hi Sam, this is Spoke & Chain. Your bike is ready for pickup today until 6 PM. Reply if you want us to hold it."}' \
$BASE/api/imessage/send
A 200 response carries "status": "message_sent" and the message id. When Sam answers, your webhook receives compact JSON with sorted keys:
POST https://your-server.example.com/webhook
Content-Type: application/json
User-Agent: ZeroSettle-iMessage/1
X-ZeroSettle-Event: message.received
X-ZeroSettle-Signature: t=1757400012,v1=3f0c…(64 hex chars)
{"event":"message.received","message":{"direction":"in","guid":"5A6F…","handle":"+18055559876","id":44,"status":"received","text":"Can you hold it until tomorrow?","ts_ms":1757400012000}}
Verify the signature over the raw bytes before parsing, compare it in constant time, and reject a t more than 300 seconds from now; the webhook docs have ready-made Python and Node verifiers, and how to receive iMessages with a webhook covers retries and dedupe. The other events are message.sent, message.failed, reaction.received, reaction.sent / reaction.failed, and the opt-in typing.started / typing.stopped. Act only on message.received in an auto-responder, because your own sends echo back as message.sent.
- Today 10:02 AM
- Business: Hi Sam, this is Spoke & Chain. Your bike is ready for pickup today until 6 PM. Reply if you want us to hold it.
- Customer: Can you hold it until tomorrow?
- Business: Done. It is held for you until 6 PM tomorrow.❤️
- Customer is typing
message.sent; the first is the curl call above. Sam's reply is message.received, the heart is reaction.received, and the typing bubble is typing.started if you opt in.What can't any iMessage API do?
No iMessage API can reach Android phones over iMessage, make a link tappable in a cold first text, or guarantee that a particular message is delivered. These limits come from iMessage, iOS and Apple's control of the network, so they apply to every provider.
- Reach Android without a fallback. Apple lists "The person that you sent the message to doesn't have an Apple device" as a reason a message goes as RCS or SMS instead. Providers that reach Android fall back. As of October 2026, per their own sites, Sendblue's FAQ says it falls back to SMS "at no extra cost", and Linq and Blooio advertise RCS with automatic SMS fallback. ZeroSettle has none today ("there is no SMS or email fallback"; SMS fallback is on the roadmap), so keep email or chat for Android customers.
- Make a link tappable in a cold first text. ZeroSettle's docs: "An iPhone won't open links from an unknown sender. Until the recipient replies to your number or saves it as a contact, a link in your text shows as plain text they can't tap. The recipient's phone does this, so no sender can avoid it." ZeroSettle still sends the message and returns
warning.code: "link_not_tappable". See why links in a first iMessage aren't tappable. - Guarantee delivery. Every phone-number provider depends on Apple's service. ZeroSettle's terms say the services "depend on third-party platforms, including Apple's iMessage service, that may change without notice, and delivery of any particular message or feature is not guaranteed". On ZeroSettle,
message.sentmeans the message left the line, and the API has no delivered or read event.
Where ZeroSettle stops short
Some gaps are ZeroSettle's own: no group chats yet, no video or file attachments, 5 new contacts a day per number on Pro, no contractual SLA, and no protected health information without a signed Business Associate Agreement.
What does ZeroSettle's iMessage API cost?
ZeroSettle's Pro plan is $49 a month for one number, and Growth is from $599/mo for several numbers that work as one. Neither plan meters messages in or out; what is capped is new contacts per number per day, and only texts the hosted AI agent writes use AI credits.
| Plan | Price | Includes |
|---|---|---|
| Pro | $49/month | One number to start, 5 new contacts a day, unlimited messages with people who message you first, 1,000 AI credits a month, self-serve. No setup fee; cancel anytime. |
| Growth | From $599/mo | 3+ phone numbers, 50 new contacts a day per number, 5,000 AI credits a month, set up by ZeroSettle (book a demo). |
Both have a 30-day money-back guarantee and no free trial. ZeroSettle's homepage also lists an Enterprise tier with custom pricing, "For high volume and compliance needs". Numbers can sell out, with a waitlist when they do. Start from Get started or through ZeroSettle's MCP connector. The plans on zerosettle.io and ZeroSettle pricing have the details, and the How it works hub lists every explainer.
Frequently asked questions
Is using an iMessage API allowed by Apple?
Apple does not approve phone-number iMessage providers; its approved-provider program covers Apple Messages for Business, a different channel. ZeroSettle is not affiliated with Apple, and its terms make "no representation that any use of the Services complies with any Apple agreement, policy, or guideline." ZeroSettle also suspends lines used for unsolicited messaging.
Do I need an SDK to use ZeroSettle's iMessage API?
No. ZeroSettle is plain HTTPS and JSON, so any language that can make an HTTPS request works. The docs' examples use curl, Python requests and httpx, Node fetch and Swift URLSession.
Can I check if someone has iMessage before texting?
Yes. ZeroSettle checks every first message to a new contact with Apple: if the number or email address isn't on iMessage, the API answers 422 not_on_imessage, nothing is sent and no new-contact slot is used.
Can I send to an email address instead of a phone number?
Yes, if that address is registered with iMessage. ZeroSettle's to field takes a phone number or an iMessage email address, and a phone number without a country code is treated as a US number.
Sources
- Why are my iPhone messages green?, Apple Support. Checked October 8, 2026.
- Messages, Apple Developer Documentation. Checked October 8, 2026.
- Apple Messages for Business FAQ, Apple, version 3.1. Last updated July 21, 2026; checked October 8, 2026.
- Programmable Messaging, Twilio Docs. Checked October 8, 2026.
- FAQ, Sendblue Docs. Checked October 8, 2026.
- iMessage API, Linq. Checked October 8, 2026.
- LoopMessage home page, LoopMessage. Checked October 8, 2026.
- Blooio home page, Blooio. Checked October 8, 2026.
- Project Blue developer resources, Project Blue. Checked October 8, 2026.
- Texting Blue home page, Texting Blue. Checked October 8, 2026.
- iMessage specifications, myCRMSIM Support. Checked October 8, 2026.
- FAQ, BlueBubbles. Checked October 8, 2026.
- iMessage channel, OpenClaw Docs. Checked October 8, 2026.
- ZeroSettle iMessage API docs: "Send a message", "Webhooks, step by step" and "Errors, limits, and compliance". Checked October 12, 2026.
- ZeroSettle iMessage API Terms of Service, sections 2 and 5. Last modified September 28, 2026.