Line health
How each live line's reputation and each chat's health are graded, what moves them, what to do when a line is at risk, and how to read both from the API.
Apple publishes no sending limits for iMessage and gives no warning before it stops delivering for a number, so every live line carries a health reading, one of four statuses, and every chat with one person carries a grade. Both are there to tell you when to ease off, early enough for it to matter.
Information, not enforcement
A reading blocks nothing and slows nothing: every send goes through whatever the status. Two
refusals are separate from it: a send to a person who opted out is a 403 recipient_not_allowed, and a send when every line in your
project is full is a 503.
Where you see it
- In the console. Open a line on the project's Lines page to see its status, the main reason behind it and what to do. The Contacts page shows each chat's grade.
- In
GET /v1/whoami. Each item oflines[]carriesreputation: the lateststatus, itsconfidence, andcomputedAt, when it was read. It is the cheap way to watch every line at once. - In
GET /v1/lines/{lineId}/reputation. The latest reading with its main reason (primaryDriver) and what to do (actionItems), plushistory, every reading of the last 7 days.lineIdis anidfromwhoami'slines[].
{
"reputation": {
"status": "AT_RISK",
"confidence": "ok",
"computedAt": "2026-10-16T14:15:00.000Z",
"primaryDriver": {
"summary": "20 of 30 new chats opened by the line in the last 24 hours"
},
"actionItems": [
{
"key": "pace_new_chats",
"title": "Pace new chats",
"detail": "20 of 30 new chats opened by the line in the last 24 hours. Hold new cold chats until the count falls; replies and warm chats are fine."
}
]
}
}A reason names the figure behind it and the limit it was read against today. Limits move as we tune them, so read them from the line, not from this page. A chat is cold until the person writes to you and warm once they have.
A live line is read about every 15 minutes, so polling faster shows nothing new. reputation is
null on a test line, which is never read, and on a live line until its first reading.
The four statuses, and what to do
| Status | What it means | What to do |
|---|---|---|
HEALTHY | Nothing in the line's traffic or delivery stands out. | Nothing. Send as you do. |
AT_RISK | One measure has reached the point where we want you to look: you texted many new people first in a day, a day far busier than the line's usual, many messages to people who have not replied, few people writing back or some opting out, a burst of sends, or a dip in delivery. | Ease off new outreach, and let people reply before you send them more. Read the reason on the line's page. It clears by itself once the readings fall back: within a day when the reason is how much you sent, over several days when it is replies, opt-outs or delivery. |
CRITICAL | The line is past a limit, or sending hard and landing badly at once. Numbers look like this shortly before Apple stops delivering for them. | Stop opening new conversations from this line today, and keep answering people who write to you. Put new people on another line by naming it at target.lineId, and request one on the Lines page if you have none. If people are opting out, stop the outreach they are answering. Expect at least a day of calmer traffic before it clears, longer when the reason is delivery, replies or opt-outs. |
FLAGGED | Apple has stopped delivering from this number, or looks to have: sends from it are not going through. | Stop sending from it, and move new people to another line by naming it at target.lineId. If you can reach the people on it another way, keep them informed there. We are already looking at it: usually the line recovers within a day or two, or we replace the number. Once it recovers it reads AT_RISK for a few days; keep outreach light until then. |
Chat grades
Every chat with one person is graded on its own, from what you sent there and how the person answered.
| Grade | What it means |
|---|---|
HEALTHY | Nothing stands out. |
AT_RISK | Several messages from you that the person has not answered, or far more from you than from them. |
CRITICAL | Many messages from you with no reply at all, or sends to them failing. |
OPTED_OUT | The person asked to stop. Sends to them are refused until they write again; see Opt-outs. |
What to do: wait for a reply before you send more, and never message a person who opted out.
What moves a line
A line moves with how it sends and how people answer: how many people you text first in a day, how
fast you send, how many messages go to people who do not reply, whether your sends are delivered,
and how many people opt out. A person who texts you first, and your replies to them, weigh far less
than outreach to people who never wrote. The limits behind the reading are ours, since Apple
publishes none: we set them conservatively from how iMessage numbers get blocked, and we tune them
as we learn. A brand-new line, or one that has sent little lately, reads with low confidence
(confidence: "insufficient") until it has enough traffic to judge; act on its status all the
same.
Opt-outs
A person opts out by sending one of these words as the whole of a one-to-one message: STOP,
STOPALL, UNSUBSCRIBE, CANCEL, END, QUIT, REVOKE, OPTOUT, OPT OUT or OPT-OUT, in
any case, trailing punctuation ignored. From then on a send to them is refused as a 403 recipient_not_allowed with details.reason: "opted_out". They
opt back in by writing to you again, one to one, with anything that does not ask to stop.
You need not wait for a refused send to know. Every message a person sends you carries optedOut,
on the message frame of /v1/response_stream and on the
message.received webhook, and the contact.opt_out_changed webhook fires
each time a person opts out or back in. A new endpoint receives that event by default; an endpoint
created before the event existed does not receive it until you tick it in the endpoint's event list.