GET /v1/phone-numbers tells you which numbers you have, whether each one can send right now, how full its queue is, and how much of its sending limits it has used. This page also explains the limits themselves: how many new contacts a number can message a day, how big its queue is, and the guard against messaging one person too often.
Request limits on the API itself (reads and writes per minute) are on Rate limits. The rules about what a message can contain before a contact replies are on Sending rules.
List your numbers
GET /v1/phone-numbers returns the active numbers in your workspace, oldest first.
curl
Response (200)
limits and queue values above are illustrative. They differ between numbers and change over time, so read them from your own responses.
To read one number, use GET /v1/phone-numbers/{phone_number_id}. It also returns numbers that are no longer active, with status: "unavailable", so you can still look up a number that older chats used. An unavailable number doesn’t report current health, limits, queue or label.
Understand the fields
Free Plan numbers leave out
health_status, limits, queue and capabilities.voice. A missing field there doesn’t mean the number can’t send; use send_status.
Sending limits
Sending limits protect each number’s reputation, so its messages keep arriving. They apply to each phone number, not to your API key. The values below are today’s typical values; the livelimits and queue fields on your number are the source of truth, and sending limits can change at any time. There is no hourly limit on texts.
New contacts per day
A new contact is someone this number has never texted before. Each Dedicated number can message up to 50 new contacts a day once it is established. A new number, or one that was recently reassigned, may start lower and reaches the full limit over about its first month. A number’s age is counted from the day it was created in Blujay; moving it to another workspace doesn’t reset it.- People who texted you first never count, and neither do follow-ups in a chat you already have.
- In a new group chat, each participant the number hasn’t texted before counts.
- Over the limit, a send returns
429RATE_LIMIT_EXCEEDEDwithlimit_type: new_contact_daily. Nothing is queued.
Queue
Each number’s send queue has room for 1,500 pending messages. When it is full, a send returns429 QUEUE_FULL with limit_type: phone_number_queue. Wait for Retry-After while queued messages go out, then retry with the same Idempotency-Key.
Texts to the same person
Each number can send at most 30 messages a minute to the same person (limit_type: recipient_loop). It’s there to stop a runaway loop in your code from flooding someone, and failed attempts count toward it too. Normal conversations never come close.
Free Plan numbers
A Free Plan number can message only verified contacts: people who texted it first and were verified in the app, up to 10 of them. The new-contact limit never applies to it, andGET /v1/phone-numbers doesn’t report limits or queue for it. Sending to anyone else returns 403 CONTACT_NOT_VERIFIED. The sending rules and the same-person guard still apply.
When limits reset
The new-contact count resets at midnight in your workspace’s time zone. The API doesn’t expose that time zone, so don’t compute the reset yourself: readlimits.new_contacts.reset_at on the number, or error.details[0].reset_at on a 429, and wait until then. The same-person guard and the queue clear on their own within minutes; their reset_at says when.
Texts in a row without a response
A separate rule limits how many texts go to a contact without a response, and what a message can contain before they reply. Those return400 errors, not 429, and aren’t retryable. See Sending rules.
Number health
Your own numbers reporthealth_status: a score from 0 to 100 and a status band.
The score reflects how your conversations go: how often people reply, how long conversations last, how quickly you answer, how many conversations people start with you, how close you run to the recommended daily volume, and whether your messages look templated. See Sending best practices. Read
health_status as part of your preflight check and before a large batch.
Check a number before you send
Before you start a batch, read the number and stop when it has no room. Treat any of these as a stop signal:send_status.allowedisfalse.queue.remainingis0.limits.new_contacts.remaining_todayis0and you’re about to message someone for the first time.
Handle limit errors on sends
When a send would go over a number’s limit,POST /v1/chats and POST /v1/chats/{chat_id}/messages return 429 before anything is queued. Wait for the Retry-After header (also error.retry_after), then retry with the same Idempotency-Key, or send from another number.
Each entry in
details also has scope: "phone_number", the phone_number_id, limit, used, remaining and reset_at:
RATE_LIMIT_EXCEEDED can also mean you’re making API requests too quickly. In that case details[0].limit_type is public_api_read, public_api_write or public_api_media, and scope is api_key. See Rate limits.
Common questions
Is there an hourly limit?
Is there an hourly limit?
No. Numbers have a daily limit on new contacts, a limit on texts in a row without a response, and a per-minute guard on texts to the same person.
How do I send more?
How do I send more?
Spread new conversations over the day and across your numbers. A new number’s new-contact limit grows over about its first month, and people who text you first don’t use it up. For more volume, add numbers.
Do texts I receive count?
Do texts I receive count?
No. Only texts you send count. A reply from the contact restarts the count of texts in a row.
Does a rejected send use up a limit?
Does a rejected send use up a limit?
A
429 or 400 queues nothing and doesn’t use up the new-contact limit. Failed attempts do count toward the same-person guard.Limitations
- A Free Plan number reports no
health_status,limits,queueorcapabilities.voice, and can message only verified contacts (CONTACT_NOT_VERIFIED). - An AI Agent number only replies to people who text it first (
CONTACT_MUST_TEXT_FIRST), and it can’t create group chats or send to them. The phone number object doesn’t say which plan a number is on. See Plans. - A number that was replaced reports
send_status.reason_code: sender_retired; a send from it returnsSENDER_RETIRED. Switch to the new number’sphone_number_id. - There is no webhook when a number’s health changes or it is suspended (
SENDER_SUSPENDED).phone_number.status_updatedfires only when a number is replaced. - The workspace time zone behind
reset_atisn’t exposed.
Next steps
Send messages
Start a chat from one of your numbers.
Sending rules
What a message can contain before and after a reply.
Rate limits
API request limits and how to back off.
iMessage, RCS or SMS
Check whether a number reaches someone over iMessage, RCS or SMS.