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

# Sending rules

> The rules Blujay enforces on every API send, and the exact error each one returns.

Blujay enforces a small set of rules on every message your integration sends. They exist because Apple and the carriers judge a phone number by how people respond to it, and a number that gets filtered stops delivering for everyone it messages. The rules are the same on every plan. The errors are `400` or `403`, never retryable, and nothing is sent when you get one.

This page is the contract. [Sending best practices](/best-practices.md) is the advice that keeps you well inside it.

## Before the contact replies

Until a contact has replied to your phone number, Blujay rejects three kinds of send:

| Rule | Error |
| - | - |
| A link, in a `link` part or in text that contains a web address | `400` [`FIRST_MESSAGE_LINK_NOT_ALLOWED`](/errors/first-message-link-not-allowed) on `POST /v1/chats`, `400` [`PRE_REPLY_CONTENT_BLOCKED`](/errors/pre-reply-content-blocked) on a follow-up |
| A photo, video, file or contact card (`media` or `vcard` part) | `400` [`PRE_REPLY_CONTENT_BLOCKED`](/errors/pre-reply-content-blocked) |
| Text over 300 characters | `400` [`PRE_REPLY_LENGTH_EXCEEDED`](/errors/pre-reply-length-exceeded) |

Blujay treats anything that looks like a domain name as a link, including `example.com` without `https://` and the domain in an email address such as `help@example.com`. Keep those out too.

The rules lift for that contact on that number as soon as they reply. They apply per number: a contact who has replied to your Support number has not replied to your Sales number.

## Texts in a row without a response

Before and after a first reply, Blujay sends at most **6 texts in a row** to a contact without a response from them. The 7th returns `400` [`PRE_REPLY_LIMIT_REACHED`](/errors/pre-reply-limit-reached). The count covers every message the person gets from your workspace, from any of your numbers, the Blujay apps, workflows and the API together. A photo or file with no text counts as one text; a caption and its attachment count as one. The count starts again each time they respond, on any of your numbers.

To send one more text after the limit, for something the person needs, set `pre_reply_override: true` at the top level of the request body. It allows a 7th text and nothing after it until the contact responds. It is not a way around the rule. The override works only when exactly 6 texts are unanswered; a contact with a longer unanswered history (for example 20 texts sent before you turned on the API) is refused with or without it, until they respond.

Every one of these errors carries `details[0]` with `rule` (`link`, `attachment`, `length` or `limit`), `limit` (300 characters for `length`, 6 texts for `limit`, `null` for the others) and `unanswered_count` (for `limit`).

## What counts as a response

* A text from the contact, in the direct chat or in a group chat your number is in.
* A reaction (tapback) from the contact.
* Calls never count. The limits protect the iMessage number, which never sees a call.

A response from the contact lifts the content rules for that number and restarts the 6-text count.

## Group chats

The same rules apply to a group chat, counted for the group:

* Until anyone in the group replies, links, attachments and texts over 300 characters are rejected.
* At most 6 texts go to the group in a row without a response from anyone in it.
* The rules apply to every `POST /v1/chats` that starts or reuses a group, even when some members already have direct chats with you.

## Who you can message

| Plan | Rule | Error |
| - | - | - |
| Free Plan | Only [verified contacts](/plans.md#free-plan): people who texted your Free Plan number first and were verified in Blujay. Up to 10. | `403` [`CONTACT_NOT_VERIFIED`](/errors/contact-not-verified) |
| Free Plan | No group chats. | `400` [`FEATURE_NOT_ENABLED`](/errors/feature-not-enabled) |
| AI Agent | Only people who texted that number first. No group chats. | `403` [`CONTACT_MUST_TEXT_FIRST`](/errors/contact-must-text-first) |
| Every plan | Nobody who has opted out. | `403` [`RECIPIENT_SUPPRESSED`](/errors/recipient-suppressed) |
| Every plan | US phone numbers only. | `400` [`VALIDATION_ERROR`](/errors/validation-error) |

See [Plans](/plans.md) for what each plan can do.

## Limits on each number

These are `429` errors with a `Retry-After` header, and they are retryable. Nothing is sent when you get one.

| Rule | `details[0].limit_type` | Error |
| - | - | - |
| New contacts a day. A Dedicated number can message up to 50 people it has never texted before per day. Replies and follow-ups never count. | `new_contact_daily` | `429` [`RATE_LIMIT_EXCEEDED`](/errors/rate-limit-exceeded) |
| 30 messages a minute to the same person from one number. A guard against runaway loops. | `recipient_loop` | `429` [`RATE_LIMIT_EXCEEDED`](/errors/rate-limit-exceeded) |
| 1,500 messages waiting to send from one number. | `phone_number_queue` | `429` [`QUEUE_FULL`](/errors/queue-full) |

Read the live values from `limits` and `queue` on [`GET /v1/phone-numbers`](/phone-numbers) before a batch. Those fields are the source of truth; the numbers above are today's typical values, and sending limits can change at any time.

## Handle these errors

* Don't retry a `400` or `403` from this page. Wait for the contact to reply, then send the link, file or longer text as a follow-up with a sentence that says what it is.
* On a `429`, wait for `Retry-After`, then retry with the same `Idempotency-Key`, or send from another number.
* To know before you send, read the contact's `opted_out` and `messaging_allowed`, and the number's `outbound_policy.inbound_first`, `send_status`, `limits` and `queue`. There is no field that reports a contact's pre-reply state today; the first text you send tells you.

## Next steps

> **[Sending best practices](/best-practices.md)**
>
> Get replies and keep your numbers healthy.

> **[Phone numbers and limits](/phone-numbers.md)**
>
> Read live limits before you send.

> **[Plans](/plans.md)**
>
> What Free Plan, Dedicated and AI Agent numbers can do.

> **[Errors](/errors.md)**
>
> Every error code and how to fix it.


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