> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ibubbl.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Limits and queues

> The exact send limits on every iBubbl line, what happens when you reach them, and how fast a line can send.

Every iBubbl line is a real phone number on a real Mac. Carriers and Apple flag numbers that message too many strangers too quickly, so iBubbl enforces a few limits per line. They protect your number. This page gives the exact numbers.

Two kinds of limit apply:

* **Holds.** The send is accepted (`202`) and waits as `pending` until it can go. You don't need to do anything.
* **Refusals.** The send is rejected with a `422` and nothing is created. You need to wait for the limit to reset, or stop messaging that contact.

## The four limits

These limits apply to every line, as of 2026-11-10.

| Limit | Per line | What counts | Over the limit |
| - | - | - | - |
| **New contacts per day** | **50**, resetting at midnight America/New\_York | Each [new contact](#what-counts-as-a-new-contact) once a day, however many messages you send them | The 51st new contact gets `422 cold_cap_exhausted`. More messages to the 50 already counted today still go out. |
| **New contacts per hour** | **30** in any rolling 60 minutes | New contacts, counted when the message goes out | A hold, not a refusal: the message stays `pending` with `held_reason: "hourly_limit"`. A slot frees 60 minutes after each send, and the message goes out by itself. |
| **Messages per day** | **1,000**, resetting at midnight America/New\_York | Every outbound message: new contacts, replies, follow-ups, group messages, messages still waiting, and messages that failed. Not `cancelled` or `expired` ones. | The 1,001st message gets `422 daily_cap_exhausted`. |
| **Unanswered in a row** | **6** to one contact who has never replied | Messages to that contact, including ones still waiting to go out (`pending` or `queued`) | The 7th gets `422 unresponsive_contact`. The limit lifts for good as soon as the contact replies; waiting doesn't reset it. |

A refused send creates no message, so its `idempotency_key` stays unused. Codes and retry advice: [Errors](https://docs.ibubbl.com/errors.md).

> [!NOTE]
>
> iBubbl can temporarily set a line's limits lower than these, for example while a new line builds its reputation. These numbers are never exceeded. To discuss your limits, email [support@ibubbl.com](mailto:support@ibubbl.com).

### What counts as a new contact

A contact is **new** if your account has no history with them:

* they have never texted, called or booked with you, on any of your lines, and
* no one-to-one message to them has gone out.

Once one message to them goes out, they stop being new, and replies and follow-ups to them never count toward the new-contact limits. Only the 1,000-a-day limit counts those.

* **A new group** counts as one new contact, whoever is in it. Sending into an existing group counts as none.
* **A message iMessage refused** (`failed` with an `imessage_*` reason, such as `imessage_undeliverable`) uses no new-contact slot, and the contact stays new. It still counts toward the 1,000 a day.

## Holds, queues and refusals

| What you see | Why | What happens next |
| - | - | - |
| `202`, `status: "pending"`, `held_reason: "working_hours"` | Outside the contact's [sending hours](https://docs.ibubbl.com/concepts/working-hours.md) | Goes out when the window opens |
| `202`, `status: "pending"`, `held_reason: "hourly_limit"` | The line has messaged 30 new contacts in the last 60 minutes | Goes out when a slot frees |
| `202`, `status: "queued"` | Your line's Mac is offline (`line_offline` in the [`message.queued`](https://docs.ibubbl.com/webhooks/events) webhook) | Goes out when the Mac reconnects, or [expires](#offline-lines) after an hour |
| `422 cold_cap_exhausted` | 50 new contacts today | Send to new contacts again after midnight ET |
| `422 daily_cap_exhausted` | 1,000 messages today | Send again after midnight ET |
| `422 unresponsive_contact` | 6 unanswered messages to this contact | Wait for the contact to reply |

`held_reason` and `held_until` appear on [`GET /v1/messages/{id}`](https://docs.ibubbl.com/api-reference/messages/retrieve) within about 10 seconds of acceptance. See [Message lifecycle](https://docs.ibubbl.com/concepts/message-lifecycle.md#held-messages).

## Offline lines

Your line sends from a Mac. If that Mac hasn't checked in for 2 minutes, it counts as offline:

* **A contact your line has messaged before** is accepted as `202` with `status: "queued"`. It goes out when the Mac is back. A message still `queued` 60–65 minutes after it was accepted becomes `expired`, and [`message.failed`](https://docs.ibubbl.com/webhooks/events#message-failed) fires with `status: "expired"` and `failed_reason: "queue_expired"`. Send it again if it still matters: its `idempotency_key` is released.
* **A contact with no line yet** (someone your account has never messaged) gets `422 no_eligible_line`, because iBubbl only gives new contacts to a line whose Mac is online. Nothing is created. Send again once the line is back.

A message that is already `pending` when the Mac goes offline waits for it. If the Mac stays offline for more than an hour, the message becomes `failed` with `failed_reason: "agent_offline"`, and `message.failed` fires.

## Rate limits

* **`POST /v1/messages` has no HTTP rate limit.** A text send never gets a `429`. The one exception is rare: a send with `attachments` gets `429 rate_limited` with `Retry-After: 5` when iBubbl is already downloading as many attachment sends as it can and no slot frees within 10 seconds. Wait, then send the same request with the same `idempotency_key`.
* **Attachments:** up to 10 files and 86 MB per message; images and GIFs 25 MiB each, video 50 MiB, PDF 10 MB, audio 25 MiB. See [Send attachments](https://docs.ibubbl.com/guides/attachments.md#supported-files-and-limits).
* **List endpoints** ([List messages](https://docs.ibubbl.com/api-reference/messages/list.md), `GET /v1/messages`, and [List contacts](https://docs.ibubbl.com/api-reference/contacts/list.md), `GET /v1/contacts`) allow **120 requests per 60 seconds per account**. The window slides: each request counts for 60 seconds after it's made. All your API keys and all list endpoints share that one budget. Over it, the answer is `429 rate_limited` with a `Retry-After` header: wait that many seconds, then send the same request again. A refused request doesn't count. At 100 items a page, that's up to 12,000 items a minute, so a loop that reads one page after another rarely reaches it; [Pagination](https://docs.ibubbl.com/concepts/pagination.md#read-every-page) shows a loop that handles `429`. Other reads, such as retrieving one message, aren't limited.
* **Conversation actions** ([Add](https://docs.ibubbl.com/api-reference/messages/react.md) and [remove](https://docs.ibubbl.com/api-reference/messages/remove-reaction.md) a tapback, [Mark a conversation read](https://docs.ibubbl.com/api-reference/conversations/mark-read.md), [Start](https://docs.ibubbl.com/api-reference/conversations/start-typing.md) and [stop](https://docs.ibubbl.com/api-reference/conversations/stop-typing.md) typing) allow **300 requests per 60 seconds per account**, shared by all your API keys and all five endpoints. It's a budget of its own: it never uses up the list budget, nor the other way round. The window slides the same way, and over it the answer is `429 rate_limited` with a `Retry-After` header. A typing refresh every 5 seconds is 12 a minute per conversation, so about 20 conversations can show typing at once. See [Tapbacks, read receipts and typing](https://docs.ibubbl.com/guides/reactions-read-receipts-typing.md#rate-limits).
* **`POST /v1/events/{token}`** accepts up to 60 events per 60 seconds for each secret-URL [inbound event source](https://docs.ibubbl.com/inbound-events/overview.md). Over that, it answers `429 rate_limited` while a workflow listens to that source. If no workflow listens, it answers `200` with `runs_started: 0` and the event is dropped. Signed sources, such as Recharge, have no limit.

## Throughput and pacing

No rate limit on text sends doesn't mean unlimited speed. Each line is one Mac, and it sends **one message at a time**:

* The Mac checks for new messages every 2 seconds, then sends them in order with a 1-second pause after each one. So one line sends **at most about one message per second**.
* Before the first text to a new US or Canadian number, the Mac asks Apple whether the number uses iMessage (see [Lines and routing](https://docs.ibubbl.com/concepts/lines-and-routing.md)). These checks are spaced 5 to 10 seconds apart.
* The hourly and daily limits above apply on top.

So a burst gains nothing. If you send 500 messages in one second, iBubbl accepts them all quickly, and then they wait as `pending` in your line's queue and go out one by one. New contacts past 30 wait an hour or more, and past 50 or 1,000 the sends are refused with `422`.

**How to pace your sends:**

* **Send one message at a time per line**, or keep only a few requests in flight. Faster sending only builds a longer queue.
* **For outreach to new contacts, plan for 30 an hour and 50 a day per line.** One new contact every 2 minutes, spread over the contact's sending hours, stays inside both limits.
* **Stop on a cap.** After `cold_cap_exhausted` or `daily_cap_exhausted`, stop that kind of send until midnight ET, instead of trying every remaining contact.
* **Follow webhooks rather than polling.** If you must poll `GET /v1/messages/{id}`, poll each message at most every 30 seconds. To check many messages at once, page through [`GET /v1/messages`](https://docs.ibubbl.com/api-reference/messages/list) with `created_after` instead of polling each one.

## Duplicates and retries

* **Duplicates count against every limit.** iBubbl doesn't detect identical messages. A send repeated with a new `idempotency_key` is a second real message: it uses a slot in the 1,000 a day, and it counts as another unanswered message to that contact. Reuse the key on retries. See [Message lifecycle](https://docs.ibubbl.com/concepts/message-lifecycle.md#duplicates-and-retries).
* **A retry with the same key never counts twice.** It returns the original message, so it uses no extra slot.
* **Don't retry a cap `422` with a new key.** The answer is the same until the limit resets, and nothing was sent.
* **Don't resend a held or queued message.** It is already waiting and will go out by itself. A second send creates a duplicate.

## Next

* [Message lifecycle](https://docs.ibubbl.com/concepts/message-lifecycle.md): what each status means, and which webhook fires.
* [Lines and routing](https://docs.ibubbl.com/concepts/lines-and-routing.md): how a contact gets a line, and iMessage versus SMS.
* [Errors](https://docs.ibubbl.com/errors.md): every error code and whether to retry it.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.