PluginBench
Skill
Pass
Audit score 90

sent-routing-strategist

sentdm/sent-plugin

Understand Sent message routing: automatic vs. pinned channels, fallback behavior, and status interpretation.

What is sent-routing-strategist?

This skill explains how Sent decides which channel (SMS, WhatsApp, RCS) delivers a message, the difference between broadcast arrays and automatic fallback, and how to read routing outcomes from message status and activity logs. Use it when configuring the channel field, debugging unexpected routes or duplicate charges, or interpreting FAILED, FILTERED, BLOCKED, or 'auto' statuses.

  • Clarifies that channel arrays broadcast (not fallback), and automatic routing is the actual fallback mechanism
  • Guides channel field selection: omit it for automatic routing, pin a single channel for compliance constraints, or broadcast to multiple channels intentionally
  • Explains how to read routing truth from message.routed events, GET /v3/messages/{id}, and activity logs rather than the initial response
  • Interprets terminal statuses (FAILED, FILTERED, BLOCKED, SCHEDULED) and what 'auto' channel means
  • Documents reroute behavior: up to three distinct channel-and-provider pairs, same message_id, consent re-evaluation, and WhatsApp-to-SMS fallback mechanics
  • Covers route selection ordering: exact-recipient rules, account-scoped vs. global, specificity, priority, prefix length, and rule age

How to install sent-routing-strategist

npx skills add https://github.com/sentdm/sent-plugin --skill sent-routing-strategist
Claude Code
Cursor
Windsurf
Cline

How to use sent-routing-strategist

  1. 1.Decide your routing intent: automatic (omit channel or use ['sent']), pinned (use ['sms'], ['whatsapp'], or ['rcs']), or broadcast (use ['whatsapp', 'sms'])
  2. 2.If expecting fallback behavior (e.g., RCS → SMS), use automatic routing; do not use an ordered array
  3. 3.After sending, resolve the actual route from message.routed event or GET /v3/messages/{id}, not the initial response
  4. 4.Check message status and activities (GET /v3/messages/{id}/activities) to understand why a message ended FAILED, FILTERED, BLOCKED, or with channel 'auto'
  5. 5.For multi-channel sends, calculate total message count (recipients × channels) and review spend before executing

Use cases

Good for
  • Choosing whether to omit channel (automatic routing), pin one channel (compliance), or broadcast to multiple channels (intentional multi-channel delivery)
  • Debugging why a message took an unexpected route or why charges appeared for multiple channels when only one was intended
  • Understanding why a WhatsApp message failed and then succeeded via SMS on retry (automatic reroute with recipient-scoped learning)
  • Interpreting a message with status FAILED, FILTERED, or BLOCKED and deciding whether to retry or fix an account precondition
  • Estimating cost and volume impact of multi-channel broadcasts before sending to large recipient lists
Who it's for
  • Backend engineers integrating Sent messaging APIs and configuring routing logic
  • Product managers or compliance officers deciding channel constraints for specific message types
  • Support engineers diagnosing unexpected delivery routes or duplicate charges
  • Anyone building multi-channel messaging flows who needs to avoid the broadcast-vs.-fallback misconception

sent-routing-strategist FAQ

Does the channel array work as an ordered fallback list?

No. The channel array is a broadcast list. ['whatsapp', 'sms'] sends one message per channel per recipient, creating duplicate charges. Automatic routing (omit channel or use ['sent']) is the actual fallback mechanism.

Why did my message end with channel 'auto' instead of a resolved channel?

Channel 'auto' means the message ended before any route was attempted. Causes include no matching route, invalid template parameters, a consent block, or an account precondition (balance, quota, unapproved template). Check the status and activity history to diagnose.

How do I enable WhatsApp-to-SMS fallback?

Use automatic routing (omit the channel field or send ['sent']). A failed WhatsApp attempt reroutes to SMS and records a recipient-scoped rule. Pinned WhatsApp sends cannot produce this behavior.

What does status FAILED mean, and should I retry?

FAILED means a route attempt failed, but automatic routing may still enqueue another attempt. Inspect the latest message state and activities before treating it as final. Do not retry FILTERED (consent block) or BLOCKED (account precondition) without fixing the underlying issue.

How many times will a message reroute?

Up to three distinct channel-and-provider pairs across the initial send and all reroutes, using the same message_id. Reroute only occurs for route or carrier problems; other failures stay FAILED.

Full instructions (SKILL.md)

Source of truth, from sentdm/sent-plugin.


name: sent-routing-strategist description: Decides how a Sent message should reach the recipient — automatic routing versus a pinned channel, what the channel array actually does, how fallback and reroute work, and why a message ended as FAILED, FILTERED, BLOCKED, or channel "auto". Use when choosing the channel field, expecting WhatsApp-to-SMS fallback, debugging an unexpected route or duplicate charges from multiple channels, or interpreting message status and activity evidence.

Sent Routing Strategist

Routing is where the most expensive Sent misconceptions live. Two facts govern almost every decision:

  1. The channel array is a broadcast list, not a preference order. ["whatsapp", "sms"] with two recipients creates four messages and four charges. There is no fallback field and no ordered-preference syntax.
  2. Automatic routing is the fallback mechanism. Omit channel, or send ["sent"], and the platform selects a route, then reroutes across up to three distinct channel-and-provider pairs when a route-level failure occurs.

Decide the channel value

IntentCorrect valueReason
Reach the recipient however works bestomit channel or ["sent"]Enables route selection and reroute
Guarantee one specific channel["sms"], ["whatsapp"], or ["rcs"]Pinning restricts matching to that channel and never crosses channels
Deliberately deliver the same content on several channels["whatsapp", "sms"]Broadcast; expect one message and one charge per pair
"Try RCS, fall back to SMS"omit channel or ["sent"]An ordered array would broadcast; automatic routing performs the fallback

Any value outside sent, sms, whatsapp, and rcs returns 400. When a user asks for ordered fallback, name the misconception explicitly before writing code, because the failure mode is duplicate delivery and duplicate cost rather than an error.

What a pinned channel gives up

Pinning restricts route matching to the named channel. Rules without a channel constraint still match and resolve to the pinned channel, so pinning does not require channel-specific rules to exist. A pinned send never crosses to a different channel, though same-channel provider hops remain possible when a rule permits them. If no route exists on the pinned channel, the message ends FAILED with no route matched — it does not silently fall back.

Pin when a compliance, contractual, or content constraint requires a specific channel. Otherwise prefer automatic routing.

Reading the outcome

POST /v3/messages returns 202 with per-recipient message_id values. For automatic routing, the echoed per-recipient channel is not a resolved route and is never updated afterward. Resolve the truth from evidence:

QuestionEvidence
Which route was actually attemptedmessage.routed event, or channel on GET /v3/messages/{id} after routing
Did the recipient's device receive itmessage.delivered
What sequence of routes was triedGET /v3/messages/{id}/activities
Why did it stopTerminal status plus channel value

Terminal status interpretation

StatusMeaningCorrect response
FAILEDA route attempt failed; automatic routing may still enqueue another attemptInspect the latest message state and activities before treating it as final
FILTEREDPolicy gate — consent block or route denialNever retry; a consent block is a compliance stop
BLOCKEDAccount precondition — balance, onboarding quota, unapproved templateFix the account condition, then send again
SCHEDULEDParked by quiet-hours policyWait; it re-enters the pipeline automatically

An outcome whose channel is auto means the message ended before any route was attempted. The causes are no matching route, invalid template parameters, a consent block, or an account precondition. Account preconditions do not reject the send request: it is accepted with 202 and the affected messages surface as BLOCKED.

Sent records internal send-time reason codes on the message for these cases, but does not return them in API responses or webhooks, so diagnosis relies on the status-and-channel combination plus the activity history. The mapping from observable evidence to root cause is tabulated in references/routing-diagnosis.md.

Reroute behavior

A failed route is retried only when the terminal failure signals a route or carrier problem another route might overcome: undeliverable by this route, provider service unavailable, provider timeout, or transport error. Every other failure stays FAILED.

Reroute reuses the same message_id and re-runs the pipeline, so message.queued and message.routed fire again, consent gates re-apply on every attempt, and already-attempted routes are excluded. The ceiling is three distinct channel-and-provider pairs across the initial send and all reroutes.

The WhatsApp-to-SMS behavior customers ask about is a specific case of this: a WhatsApp message accepted and then failed for a recipient-side reason reroutes and records a recipient-scoped rule that WhatsApp is not deliverable for that number, so subsequent automatic sends skip WhatsApp for that recipient. It requires automatic routing; a pinned WhatsApp send cannot produce it.

How automatic routing selects a route

Routes come from platform-maintained rules evaluated at send time against recipient attributes (country, number prefix, exact number, carrier, number type, ported state), sender, template attributes, channel, and whether the destination is international. Ordering is: exact-recipient rules first, then account-scoped before global, then match specificity, then rule priority, then longer number prefix, then the older rule. Inactive, deleted, expired, and below-threshold rules are excluded. Candidates whose template has an explicit non-approved review status on that channel are dropped, while a channel with no recorded review is not blocked. The first surviving candidate wins and the rest remain available as fallback routes.

There is no fixed channel preference order, so never promise "RCS first, then WhatsApp, then SMS." Read references/routing-model.md before making any claim about why a specific route was chosen.

Cost and volume consequences

Because broadcast multiplies messages by recipients, review any multi-channel array against expected spend before sending. A 1,000-recipient send with two channels is 2,000 messages. The per-request recipient ceiling is 1,000, and documented pacing pairs full batches with roughly one request per second to stay inside the 200-requests-per-minute budget.

RCS today carries text plus up to four suggestion chips, mapped from template buttons, and every outbound RCS message receives an appended STOP chip. Do not design an RCS-pinned flow that depends on rich cards, carousels, or media.

Boundaries

Use sent-messaging to execute a single send with confirmation, sent-two-way-messaging for consent and inbound keyword semantics, messaging-performance-analyzer for aggregate delivery-rate regressions, and sent-webhook-engineer for receiving and deduplicating the events this skill teaches you to read.