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

# Plans and limits

> What a plan actually controls, what a trial allows, and how to read your own limits from the API.

The API refers to "your plan" in a few places — a `402`, a trial quota, a number limit. This page says what a plan actually controls and how to see your own figures without asking anyone.

<Note>
  A plan controls **three** things and nothing else: how many numbers you may connect, how many messages a trial may send in total, and how many requests a minute you may make. Every message type, every field and every endpoint on this site is available on every plan.
</Note>

## What a plan controls

| What it sets | What happens at the edge | Where to read yours |
| - | - | - |
| How many numbers you may connect | `403 instance_limit_reached` on [`POST /v1/instances`](/api-reference/instances/create) | `data.slots` on [`GET /v1/instances`](/api-reference/instances/list) |
| A total message allowance, on a trial only | `403 trial_quota_exceeded` on any send | `details.trial_message_limit` on that error |
| How many requests a minute you may send | `429 rate_limit_exceeded` | The `X-RateLimit-*` headers on every response |

<Note>
  **This page does not list the figures for each plan, on purpose.** They are configured per plan and can change without this site being rebuilt, so anything printed here could quietly stop being true. Your own current figures are always in the API and on the portal — see [Reading your own limits](#reading-your-own-limits) — and those are the numbers that actually govern your account.
</Note>

Prices are not published here either, for the same reason. The current plans, what each one includes and what it costs are on the [pricing page](https://bulkneo.com/pricing), which reads them live from this API rather than repeating them — so it cannot go stale the way this page would. To move to a different plan, [talk to us](https://bulkneo.com/contact).

### If you bought through a provider

If your account came from a reseller rather than directly from us, you are not on one of our plans at all. Your provider sets two things on your account instead:

* **how many numbers you may connect**, and
* **how long your access runs for**.

There is no total message cap on that kind of account, and the per-minute rate limit works the same way. When you hit the number limit you get `instance_limit_reached` with `details.limit_source: "account"` — that means "ask your provider", not "upgrade a plan". See [Telling the two number limits apart](/errors#telling-the-two-number-limits-apart).

## The number limit

The cap counts the numbers on your account that have not been deleted, whether they are connected or not. Deleting a number frees its slot immediately.

Going over it gives `403 instance_limit_reached`, carrying the cap in `details.instance_limit` and where it came from in `details.limit_source`. You will see it in two places: when you [add a number](/api-reference/instances/create), and when you ask for a **new QR** for a number that is outside the cap.

<Tip>
  Disconnecting a number does **not** free its slot — the instance still exists. [Delete](/api-reference/instances/delete) it if you want the slot back.
</Tip>

### If your allowance goes down

Moving to a plan with fewer numbers does not disconnect anything. Numbers that are connected stay connected and keep sending.

What changes is that the cap counts your numbers **oldest first**, so a reduced allowance costs your **newest** numbers their slot — and those numbers will be refused a new QR the next time they need to reconnect. The ones you have been using longest are unaffected.

You can see which is which before it happens: every entry in [`GET /v1/instances`](/api-reference/instances/list) carries **`within_limit`**. `false` means that number is outside the current allowance and will not be issued a new QR.

<Check>
  Nothing is ever disconnected for being over the cap. To bring a number back inside the allowance, delete one you no longer use — that frees the slot for the next one in line — or move to a plan with more numbers.
</Check>

## The trial message cap

A trial allows a fixed number of messages **in total** — not per day, and not per number. Every message type counts against it equally: an image costs the same one message as a text.

* Only **sent** messages count. A send that failed does not.
* A [number check](/api-reference/numbers/check) is **not** a message and does not count.
* When it is used up, every send returns `403 trial_quota_exceeded` with the allowance in `details.trial_message_limit`.

Paid plans have no message cap at all — the rate limit is the only thing pacing you.

## The rate limit

Per minute, per API key, and split across **two separate budgets**:

| Scope | Covers | Allowance |
| - | - | - |
| `messages` | `/v1/messages/*` and `/v1/numbers/check`, sharing one budget | Set by your plan — read the header |
| `instances` | `/v1/instances/*` | 120 a minute, on every plan |

The instance budget is deliberately generous so that polling a QR while somebody scans can never eat into your sending allowance. Full detail, including the headers, is on the [Errors](/errors#rate-limits) page.

## Reading your own limits

Nothing here needs to be hardcoded, and nothing should be. Every figure that applies to you is in the API or on the portal:

<CardGroup cols={2}>
  <Card title="Your number limit" icon="mobile">
    [`GET /v1/instances`](/api-reference/instances/list) returns `data.slots` — `used` and `limit`, straight from whatever cap applies to your account. `limit` is `null` when there is no fixed cap.
  </Card>

  <Card title="Your rate limit" icon="gauge-high">
    Every response carries `X-RateLimit-Limit` and `X-RateLimit-Remaining` for the scope named in `X-RateLimit-Scope`. Read the header rather than assuming a number.
  </Card>

  <Card title="Your trial allowance" icon="hourglass-half">
    `details.trial_message_limit` on the `403 trial_quota_exceeded` you get when it runs out. Usage so far is on your portal dashboard.
  </Card>

  <Card title="Everything else" icon="table-columns">
    Your plan, your renewal date and your usage are on the **portal**. That is the authoritative view of your own account.
  </Card>
</CardGroup>

```bash Your current number allowance theme={null}
curl https://api.bulkneo.com/v1/instances \
  -H "apikey: YOUR_API_KEY"
```

```json theme={null}
{
  "success": true,
  "data": {
    "slots": { "kind": "direct", "used": 2, "limit": 3, "billed": false },
    "instances": [ "…" ]
  },
  "request_id": "b1f2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d"
}
```

## What a plan does not change

No plan unlocks a capability. Every endpoint, every message type and every field on this site is available on all of them — and so is every limitation:

* **You cannot receive messages.** There are no incoming messages, no webhooks and no delivery receipts on any plan. See [What is not available yet](/guides/not-available-yet).
* **Media is sent from a public link you host.** There is no upload endpoint. See [Sending media](/guides/sending-media).
* **Buttons and lists are best-effort.** Many WhatsApp clients no longer render them and may show plain text instead. A successful response means the message was accepted, not that the buttons appeared.
* **Poll results and button taps cannot be read back.** The response goes to the phone, not to your system.
* **There is no bulk send and no scheduling.** One request sends one message to one recipient.

Paying more gives you more numbers and a higher allowance. It does not give you a different API.

## Field limits, which are not a plan thing

Message field sizes — 4,096 characters of text, 1,024 of caption, 3 buttons, 50 numbers per check — are the same on every plan and are documented on each endpoint page. They come from what WhatsApp itself will carry, not from what you pay.

## When access stops

| What you see | What happened | What fixes it |
| - | - | - |
| `402 no_active_subscription` | No usable plan on the account. | Activate one in the portal. |
| `402 subscription_expired` | The plan ran out. Nothing is deleted — your numbers, keys and `instance_id`s are all still there. | Renew it. |
| `403 access_expired` | An account with a validity period reached the end of it. | Ask your provider to extend it. |
| `403 account_suspended` | The account is suspended. | [Get in touch](https://bulkneo.com/contact). |

<Check>
  Nothing is destroyed when a plan lapses. You can still list, inspect, re-scan and delete your existing numbers. What stops is **sending** and **adding a new number** — [`POST /v1/instances`](/api-reference/instances/create) is the one instance endpoint that needs an active plan.
</Check>


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