Channel readiness
The same readiness report narrowed to SMS or RCS: the channel's own setup steps, the countries a sender still ought to be registered for, and the countries it can actually send to right now.
The project report answers "is this project set up". This one answers the two questions you actually ask before sending on a channel: what is still missing here, and who can I reach right now.
It returns the same object, with scope: "channel", and fills in the two fields the project scope always leaves empty: warnings and reach.
What it does not answer is what a carrier or a regulator did to a registration you already submitted. That moved out on 2026-09-05 — see What moved to the attention endpoint.
Setup steps, the recommended-registrations warning and real send reach for one channel.
channel is sms or rcs. Any other value returns 404 — it is a route constraint, not a validation error, so don't expect a field-level message back.
curl "https://api.instasent.com/v1/project/$INSTASENT_PROJECT/readiness/channel/sms" \
-H "Authorization: Bearer $INSTASENT_TOKEN"{
"entity": {
"scope": "channel",
"projectType": "standard",
"channel": "sms",
"percent": 50,
"operational": true,
"steps": [
{ "key": "add-sender", "completed": true, "isBlocker": true, "disabled": false, "skipped": false, "skippable": true },
{ "key": "send-first-sms-campaign", "completed": false, "isBlocker": false, "disabled": false, "skipped": false, "skippable": true }
],
"warnings": [
{
"key": "recommended-registrations",
"severity": "error",
"count": 2,
"rows": [
{ "channel": "sms", "senderId": "5f3a9b2c4d1e0f00112233ab", "senderName": "MYBRAND", "country": "ES", "source": "regulation", "urgency": "urgent", "audienceCount": null },
{ "channel": "sms", "senderId": "5f3a9b2c4d1e0f00112233ab", "senderName": "MYBRAND", "country": "FR", "source": "audience", "urgency": null, "audienceCount": 412 }
]
}
],
"reach": {
"reachableCountries": ["PT"],
"senders": { "MYBRAND": ["PT"] },
"senderCount": 1,
"defaultSender": "MYBRAND"
},
"computedAt": "2026-09-04T16:20:31Z"
}
}Steps
Same step object as the project report — stable key, no copy — with a set that depends on the channel and the project type:
projectType | channel | Steps, in order |
|---|---|---|
standard | sms | add-sender, send-first-sms-campaign |
standard | rcs | add-agent, register-country, send-first-rcs-campaign |
api_sms | sms | add-sender, send-sms-recent |
api_sms | rcs | add-agent, register-countries, send-rcs-recent |
The first step of each list is the blocker; the rest are disabled until it is done. register-country / register-countries completes as soon as one RCS registration has been submitted — submitted, not approved, because approval is the carrier's and the regulator's timeline, not a step the customer can complete. The *-recent steps look at the last 30 days, so they re-open on a quiet integration.
SMS has no per-country step. Registration exists on SMS too, but it is not something the customer starts by hand, so it never becomes a checklist item. What it does produce is the warning below.
Warnings
Steps are what the customer can complete. A warning is what the customer should act on but cannot tick off — a country a sender ought to be registered for and is not. It appears only once the channel has an active sender: before that there is nothing to recommend registering.
One key:
key | severity | What it means |
|---|---|---|
recommended-registrations | error | Countries a sender should be registered for and is not. count is the total and may exceed rows, which is capped at 8. |
warnings stays an array discriminated by key even with a single member, so narrowing on the key is still the right thing to write: the next warning to arrive inherits that shape instead of adding nullable fields to this one.
Every warning carries key, severity, count and rows. rows is discriminated by the parent's key, never by which fields came back null.
Rows of recommended-registrations describe a registration that does not exist, so they carry no status. Instead they say why the country is recommended:
channelstringsms or rcs.
senderIdstringThe sender the recommendation is for.
senderNamestringIts alias — the SMS from, or the RCS agent name.
countrystringISO 3166-1 alpha-2.
sourcestringregulation — a regulator requires it; audience — you hold contacts there; org — it is the organization's own country.
urgencystring | nullurgent, upcoming or far. How close the regulator's deadline is; null unless source is regulation.
audienceCountinteger | nullReachable contacts in that country; null unless source is audience.
A country already covered by a non-archived registration on that sender never appears here, whatever its status.
What moved to the attention endpoint
Until 2026-09-05 this array carried two more keys, and if you integrated before that date they are what you are missing:
| Old warning key | Where it lives now |
|---|---|
pending-review | GET /project/{project}/attention, same key |
rejected-registration | GET /project/{project}/attention, same key |
The key names survived the move, so the switch you already wrote still matches; what changed is the endpoint it reads from and the shape around it — an attention item is one occurrence with entities and data, not a warning with rows.
The reason is the boundary the two engines are built on: readiness answers what is left to configure, attention answers what has broken. A registration a carrier is still reviewing, or one a regulator turned down, is something that happened to a registration the customer already submitted — an event, not a configuration gap. recommended-registrations stayed because it is the opposite: a registration that does not exist yet.
Reach
reach is the positive counterpart of the warnings: the countries this channel can send to right now.
reachableCountriesstring[]The union across the channel's active senders, ISO 3166-1 alpha-2, deduplicated and sorted.
sendersobjectPer-sender breakdown, keyed by alias. A sender that reaches no country is omitted, so this map can be shorter than the sender list — and it may arrive as [] rather than {} when it is empty. Normalise both to an empty map before you index it.
senderCountintegerHow many active senders the channel has, including those that reach nothing. This is not the size of senders, and the gap is the interesting part: an RCS agent with no accepted registration counts here and is absent there.
defaultSenderstring | nullThe project's default sender, when it is one of the active ones. It matters because a send that names no sender uses it — so the union above can promise more than a single send would actually reach. Always null on api_sms projects, where nothing picks a default.
Reach is registration-aware: a country drops out when a registration is required and missing, still pending, gated by an enforced regulation, or rejected or revoked. The two channels start from opposite defaults, which is why the same project can look very different on each:
- SMS allows by default over the operator catalogue — the same set as the sender's
acceptedCountries— and subtracts what regulation blocks. - RCS is registration-driven, so it can be stricter than the agent's
acceptedCountries, which reflects carrier support only.
operational on a channel
On this scope operational asks for more than the project one does: no incomplete blocker step and at least one reachable country.
That second clause is not redundant. Holding a sender is not the same as being able to deliver with it: an RCS agent with no accepted registration completes add-agent and still reaches nobody. operational claims capability, so it answers to reach.