Products

Ships to

Developer guideiMessage API8 min read

iMessage API rate limits and sending rules

iMessage API limits explained with Flow: request rate limits, reply windows, new-contact budgets and pacing.

The short answer

An iMessage API has two kinds of limits. Request limits protect the API and are easy to read from headers. Sending rules protect the line: who you can message, how many new contacts a day, and how fast. The second kind decides whether your agent works at scale, and providers set them very differently.

Building on the iMessage API? Build on iMessage with Flow: one agent for iMessage, WhatsApp and Telegram. New to it? Read the iMessage API guide.

Two kinds of limits

When people ask about iMessage API limits, they usually mean one of two things.

  • Request limits. How many API calls your key can make. These protect the provider’s servers.
  • Sending rules. Who you can message, how many new conversations a line can start and how fast it can send. These protect the line from being flagged for unwanted messages.

Request limits are a nuisance. Sending rules are a design constraint. The iMessage API guide covers why a line needs protecting.

Request limits

On Flow, requests are limited per API key and every answer says where you stand:

RateLimit-Limit: 100
RateLimit-Remaining: 97
RateLimit-Reset: 12

Over the limit, the API answers 429 with type rate_limited, a Retry-After header and error.retry_after in seconds. Wait that long and retry with the same idempotency key. The TypeScript SDK retries 429 and 5xx answers for you, twice by default, and honours Retry-After. Use webhooks or the live stream instead of polling GET /v1/events in a tight loop. This is from Flow’s rate limits docs.

Flow’s sending rules

Every send on Flow passes one send gate, which applies each channel’s rules before anything leaves Flow. On an iMessage line:

  • Replies are not limited. Replies to a customer who wrote in the last 24 hours go straight out.
  • Plans cap people, not messages. The free shared line covers up to 25 people a month, the $30 shared line fits roughly 200 to 300, and dedicated lines start at $100. A person is anyone who messaged the line, or was messaged by it, in the calendar month.
  • Writing first is paced. It needs the outbound add-on on a dedicated line, and new conversations ramp up over about three weeks, from a few a day to 40 a day.
  • A first message has to say who is writing and why, and offer a way to opt out, such as reply STOP.
  • Flow looks after line health. If a line sees blocks or failed deliveries, Flow pauses cold sends before the number is at risk, and replies still go.

The same send gate applies other channels’ rules. On WhatsApp, free-form messages are allowed for 24 hours after the contact’s last message and then only an approved template, and a Telegram bot is allowed 20 messages a second, in bursts of 40. A send over a rate is refused with 429 rate_limited, and at most one message per conversation is in flight, in the order you sent them.

Flow on iMessage: features, pricing and limits lists the plans and limits in one place.

Design around Flow’s limits

Flow makes the limits visible in the API and applies channel rules before a message leaves the line. That lets your agent decide whether to reply, wait for the customer, retry later or ask them to opt in. For the full plan breakdown, see Flow on iMessage: features, pricing and limits.

Design an agent that respects limits

  • Reply, do not broadcast. Agents that answer people who wrote first never meet the new-contact budget or the abuse rules.
  • Check before you send. GET /v1/capabilities?conversation=conv_... returns whether the window is open and what each content type would do.
  • Retry only what clears. rate_limited and sender_throttled carry retry_after. outside_window will not clear until the person writes again.
  • Use the event ID as the idempotency key, so a retry never sends twice. See idempotency keys.
  • Watch sender.status_changed. It is the early warning before a channel acts against a number.
  • Get people to write first. An opt-in link opens Messages with the line and a prefilled text, and every Flow line comes with one.

Frequently asked questions

What are the iMessage API rate limits?

Flow has two kinds of limits: request limits per API key, with a 429 answer and retry time, and sending rules that protect each line. On iMessage, the plan caps people per month, replies are not limited within the reply window, and writing first is paced.

What happens when I hit a rate limit?

On Flow the API answers 429 with a Retry-After header and a retry_after value in seconds. Wait that long, then retry with the same idempotency key. The TypeScript SDK retries 429 and 5xx answers for you, twice by default.

Is there a limit on messages per second?

Each Flow sender has a sending rate. A Telegram bot, for example, sends 20 messages a second with bursts of 40. A send over the rate is refused with 429 rate_limited.

Why can a line be throttled?

Flow paces every line automatically to keep it healthy. If a line sees blocks or failed deliveries, Flow pauses cold messages and new conversations, and replies still go.

Do replies count against the new-contact limit?

No. Replies to a customer who wrote in the last 24 hours go straight out with no limit. The limits apply when a business messages people who have not written recently, or writes first.

How do I avoid limits as an AI agent?

Reply to people who wrote first, check what a conversation supports before you send, retry only what clears by itself, and watch sender status events.

Start hereiMessage API: a developer’s guideThe overview of how iMessage APIs work, and what to ask a provider. Developer guideSend iMessage programmaticallycurl, TypeScript and Python: get a key, receive a signed webhook, reply once and handle retries.Developer guideiMessage API without a MacWhy a hosted iMessage API removes the Mac, what the DIY relay costs you, and how to choose.Developer guideiMessage MCP serverTwo things people mean by it: a messaging MCP for your coding agent, and your product as an MCP server.Developer guideiMessage API for Node.js and TypeScriptInstall the SDK, stream inbound messages, verify signed webhooks in Express and reply safely.Developer guideiMessage API for PythonStream inbound events, verify signed webhooks in FastAPI and reply with idempotency keys.Developer guideiMessage API for GoPoll events, reply and verify signed webhooks with the standard library, no SDK needed.

All posts: the Flow blog. The Flow docs have the reference.

From reading to building

Your agent, on iMessage and everywhere else.

Flow gives your agent an iMessage line, and the same code answers on WhatsApp and Telegram and works as an MCP server and CLI. See how it works on iMessage.

Build on iMessage with Flow