Skip to content

Numbers

A number is a registered thing, not just a row that connects. Its SIM, owner, handset and purpose are recorded before anything is paired.

Six states, six different actions#

state is the field to branch on. It is deliberately not the same as connected.

StateMeaningWhat to do
provisionedRegistered, never scannedScan it with the recorded handset
activePaired and workingNothing
droppedMomentarily offlineNothing — the supervisor handles it
needs_pairingUnlinked from the handsetA human with that phone must re-scan
restrictedAccepting messages, delivering noneRest it. Switchboard pulls it from the pool automatically
bannedWhatsApp has banned itRe-scanning cannot help. Source a new SIM
retiredDeliberately out of serviceNothing

banned and needs_pairing demand opposite responses

They used to be indistinguishable, and the failure mode was someone re-scanning a dead number for an hour. A ban is recorded from WhatsApp’s own TemporaryBan / ConnectFailure events as the engine forwards them.

The silent one#

A restricted number does not fail. WhatsApp accepts the message, returns a message id, and never delivers it — so send errors, connection state and ban webhooks all stay clean while every message spent on that number is lost.

Delivery receipts are the only honest evidence. Switchboard measures the share of each number’s recent messages that actually arrived and pulls one from the pool when that collapses, then puts it back when it recovers.

A ratio, not a count

A number that fails to deliver three messages might be talking to three people who blocked it. One that fails to deliver ninety of its last hundred is restricted. Messages younger than the grace period are not counted at all — a message sent ten seconds ago has not failed to arrive, it has not arrived yet.

Caps and warm-up#

Every number has a daily cap, and a new one is narrowed further by a warm-up ramp over its first week. Sending at full volume from a fresh SIM is the most reliable way to lose it, and a banned number does not come back.

The costs are asymmetric: too low delays a day, too high costs the number permanently along with every conversation on it.

shell
# raise a cap once a number has a history
curl -X PATCH https://switchboard.atrix.dev/v1/instances/<id>/number \
  -H "apikey: <projectKey>" \
  -H 'content-type: application/json' -d '{"dailyCap":200}'

Retire, don’t delete#

When a client leaves, retire keeps the identity, usage and audit trail that answer “whose number was that, and what did it send”. Deleting removes the instance from the engine and can answer nothing afterwards.