The API call is not the system
Sending an A2P SMS is one HTTP request. Operating A2P SMS is a set of dependencies you do not own: sender registrations per market, provider routes, carrier filtering, handset state and the application flow the message exists to serve.
This guide covers the parts of that system that decide whether the message is useful, and the operational habits that keep them visible.
Sender registration is a market dependency, not a setting
In several markets a sender identity has to be registered before traffic is treated as legitimate. In the US, A2P traffic on long codes is registered through The Campaign Registry (10DLC); brand and campaign details, including the declared use case, affect how traffic is treated. In a number of European and Middle Eastern markets, alphanumeric sender IDs are pre-registered per operator, and the required evidence differs by operator and by provider.
The operational consequences, rather than any specific timeline:
- Changing a sender identity is a dependency on third parties, so it belongs on a project plan rather than in a release checklist. Confirm the current lead time with the provider and operator handling that market, because it changes.
- Adding a second provider for failover usually means repeating registration work for that provider's connections, not just adding credentials.
- Content and template rules attach to the registered identity in some markets, so template changes can require re-approval.
Keep a register of sender identities per market with the registration state, the provider that holds it, and the evidence used. When a route has to change under pressure, that register is the difference between a routing change and a discovery exercise.
Isolate traffic classes
Authentication codes, service notifications and promotional campaigns have different deadlines, different consent requirements and different content review. Sharing one sender identity and one route across them means a campaign's queueing behaviour and a campaign's content review both apply to your authentication traffic.
Separate at four levels:
- Sender identity and registration, so content review of one class cannot affect another.
- Route, so throughput allocation and provider throttling are independent.
- Queue and priority, so a scheduled campaign cannot sit in front of a code the user is waiting for.
- Monitoring baseline and alerting, so a slow campaign does not page the same person as a degraded authentication route.
The related detail is in transactional vs marketing traffic.
Map DLRs and errors into your own vocabulary
Providers report status and error information in their own formats and with their own gaps. Delivery receipts tell you what the network reported about the message, not what the recipient did, and intermediate hops can rewrite or synthesise them.
Do the mapping work once:
- A canonical set of states — accepted, submitted, delivered, failed, expired, unknown — with the provider's raw status and error code retained alongside.
- A canonical set of failure reasons, grouped by who can act on them: your application, the provider, the destination network, or the recipient.
- A recorded rule for statuses you do not trust from a given route, so analysis is not silently distorted.
Without that mapping, adding or replacing a provider changes your reporting rather than your reliability.
Monitor per route, per destination, per class
Aggregate delivery percentages hide the failures worth acting on, because the failure is usually specific: one destination network, one route, one traffic class, one sender identity.
Useful monitoring has:
- Baselines per programme and per route, established from that programme's own recent history rather than from a general target.
- Latency distributions, not averages, from submission to final status.
- Live canaries — a small, continuous stream of real messages to numbers you control on each significant route and market — so degradation is detectable independently of production volume patterns.
- Alerts on movement against the programme's own baseline, with a named owner and a defined action.
Retries, idempotency and deadlines
The hardest case in messaging is an ambiguous submission: the request timed out and the message may or may not exist downstream.
- Give every send an application-generated reference and store it before submission. Treat submission as idempotent against that reference, using a provider idempotency key where one is supported.
- Define a useful deadline per traffic class: the point after which delivery no longer helps the user. Past that, stop rather than retry.
- Never allow a retry or failover to create a second authentication code for the same session. Deduplicate at the state level, not at the message level.
- Decide, per class, whether retrying after an ambiguous timeout is worth the risk of duplication. It is a policy choice, not a default.
Measure the application outcome
Delivery receipts describe the transport. The outcome lives in your application: did the user verify, click, reply, pay, collect. Join them on one identifier carried from the decision to send through every attempt and status, and store it on both sides.
That join is what makes route comparison meaningful. Two routes with similar reported delivery can produce different verification rates, and only the application side shows it. The measurement model is in OTP metrics that reveal delivery and verification failures.
Supply is a separate decision from operations
Flowstates sells and operates messaging routes, supports customers keeping their own provider contracts (BYOV), and supports a hybrid of both. That choice is commercial. The operational layer — registrations, routing, canonical status mapping, monitoring, escalation and reporting — is the same work regardless of who holds the supply contract, and it needs an owner either way.
Operational checklist
- Sender identity register per market, with registration state, holder and evidence.
- Traffic classes separated at sender identity, route, queue priority and alerting.
- Canonical status and error mapping, with raw provider codes retained.
- Per-route, per-destination, per-class baselines from each programme's own history.
- Live canaries on significant routes and markets.
- Application-generated reference on every send, stored before submission.
- Useful deadline per traffic class, with stop conditions instead of unbounded retries.
- Deduplication at state level across retries and failover.
- One correlation identifier joining sends, statuses and application outcomes.
- Named owner and defined action for every alert, and a route change path that does not depend on a single person.