Skip to content

Sending

Two ways out, and most projects want the first. Hand the message over and Switchboard decides which number sends it, when, and how often to retry.

The send queue#

typescript
const { id } = await wa.outbound.send({
  to: "+971500000001",
  message: { text: "hello" },
})

const { state } = await wa.outbound.status(id)
// queued → sent → delivered → read

You name no number. Switchboard chooses one of yours when the message is actually due, paces it, retries it, and records what happened to it.

202, not 200

send() resolves when the message is accepted, not sent — the server answers 202 for exactly that reason. Use status(id) for what actually happened.
What it buys youInstead of
A cap is not an errordaily_cap_reached used to be yours to handle. Now the message is queued until tomorrow.
You cannot burstThe queue decides when each message leaves, so a loop calling send() 500 times does not become 500 messages in a minute.
A ban doesn’t strand workThe number is chosen when the message is due, so one banned in the meantime is skipped.
SchedulingsendAfter: new Date(...) — one field.

Do not build your own send queue on top of this one

Pooling, pacing, retries, cap-awareness and scheduling are the queue’s job, and every one of them is subtle in a way that costs a SIM to learn. If you find yourself writing a worker that picks a number and sleeps between sends, you are rebuilding this — and your copy will diverge from the caps and warm-up state the service holds authoritatively.

When nothing is going out#

Ask the pool rather than reading individual errors.

typescript
const pool = await wa.outbound.pool()

// pool.numbers[].reason — one of:
//   "daily cap reached"  "pacing"  "banned"
//   "restricted"  "offline"  "never paired"

Every number is reported, including the ones that cannot send, each with its own reason. No number is named as “next”: selection happens again when a message is actually due, so naming a winner would be a lie.

The direct path#

Still there, unchanged, for when you want one specific number and an immediate answer.

typescript
await wa.line(instanceToken).sendText("+971500000001", "hello")

Errors you can act on#

HelperStatusMeans
isRateLimited429Your project’s rate limit, or a number’s daily cap. retryAfter is set for the first.
isUnavailable503A number is momentarily moving between replicas. The one error worth retrying.
isUnauthorized401Bad key — or a suspended project. Check before assuming.
isGone410A dead letter’s payload was redacted past its retention. Replay will never work.