How we compare SMS providers: the method behind the matrix

Comparison matrices only help if every cell is traceable. This page explains how we build the published-rate matrix: what each cell means, which sources we accept, what we refuse to invent, and how a reader can reproduce the exercise with a small test plan of their own.

Direct routeyour appgatewaydest. networkhandsetMulti-hop routeyour appgatewaytransit hoptransit hophandset?every extra hop is a point where a delivery report can be acknowledged without terminal proof

What each cell in the matrix means

Every non-empty cell in a published-rate matrix on this site quotes a figure or claim that appears on the provider’s own public page at the time we retrieved it. The cell is not an estimate, a partner quote, or a blended internal cost. It is a citation: the provider said X, on page Y, as of retrieval date Z.

Where a provider publishes a floor rate, a destination band, or a unit price schedule, we record the value exactly as shown and attach the source URL and the retrieval date. If the page lists multiple tiers, we note which tier the cell refers to (for example signup tier versus volume tier) so the reader is not comparing a public floor against a private contract rate. If the page is ambiguous, the cell stays blank or carries a short note rather than a guessed number.

Link trust rules are simple. We prefer primary pages under the provider’s own domain: pricing, SMS API docs, coverage, or signup. We do not treat marketplace listings, affiliate blogs, or undated screenshots as sources. If a page requires login to see any price, we do not scrape past the gate; the matrix either marks the rate as account-gated or leaves the cell empty. Archived copies may support a correction dispute, but the live page at retrieval time is the authority for the published snapshot.

Rates move. A matrix is a dated snapshot, not a live feed. When we refresh a row, we update the retrieval date with the cell. Readers comparing two providers should check that the dates are close enough for their decision; a cell from last quarter and a cell from this week are not the same kind of evidence.

SMSRoute's comparison matrix links every cell to its source with a retrieval date.

What we compare and what we refuse to compare

We compare three classes of public material. First, published rates: per-message or per-segment prices, destination rules, and any stated floor the provider puts on a public page. Second, published claims: stated channel support (HTTP API, SMPP), documented features such as delivery report callbacks, and signup or settlement constraints the provider describes in plain language. Third, signup requirements: whether self-serve registration is offered, what identity or billing steps the public flow shows, and whether the provider documents email-only signup or crypto settlement when those options appear on their own pages.

We refuse categories that need measurement we have not performed or numbers we would have to invent. We do not rank delivery quality, inbox placement, or filter traversal from marketing copy. We do not publish market share. We do not fill gaps with industry averages, inferred margins, or “typical” failure rates. If a provider’s page omits a destination, that cell is omitted or marked unavailable in public materials—not completed from another vendor’s schedule.

Segment math, when we mention it, follows the public SMS encoding rules readers already use: GSM-7 bodies up to 160 characters single-part and 153 per part when concatenated; UCS-2 bodies up to 70 single-part and 67 per part when concatenated. Address fields are discussed in E.164 terms, with the usual maximum of 15 digits excluding presentation characters. Those figures are specification anchors, not performance promises. HTTP response codes we reference in methodology are the ordinary ones developers already handle—200 for success paths, 429 for rate limit responses, 500 for server-side failure—and SMPP session behaviour is discussed only in terms of documented state machinery, not as a claim that any given route is healthy.

SMSRoute’s own position on the comparison pages is narrow and intentional. We compete on published floor rates, email-only signup, and crypto settlement. The pages say only what the cited sources support. They do not claim superiority on unmeasured axes, and they do not dress a floor rate up as an all-in landed cost for every route.

Why route-level claims need tests, not brochure pages

A published rate tells you what you will be billed if the message is accepted under that tariff. It does not tell you whether a delivery report is honest, whether the sender identifier you submitted is the one the handset displays, or whether the message that left your API is the message that arrived. Those are route-level behaviours. Marketing pages collapse them into adjectives. Engineering work has to split them into checks.

Delivery report honesty is the first split. A provider may emit a delivery receipt or callback that reflects an upstream accept, a handset-level event, or only an internal queue state. Public docs sometimes describe the callback schema without binding each status to a real-world milestone. Until you submit controlled traffic and reconcile callbacks against independent confirmation, you are reading a vocabulary, not a measurement. Latency summaries, when you compute them yourself, should be stated as your own p50 and p95 over a defined sample—not as a vendor’s slogan reused without a window or a population.

Sender-ID preservation is the second split. Replacement, shared outbound identities, or country-specific overrides can be legitimate network policy and still break the product assumption that the from-field you sent is the from-field the user saw. Brochure language about “branding” does not substitute for a side-by-side of request payload and handset display.

Handset confirmation is the third split. Acceptance at an API gateway (for example an HTTP 200 on submit) is not arrival. Neither is an SMPP submit_sm_resp that only proves the SMSC took custody under a given message state path. Confirmation means a device or subscriber-controlled endpoint you trust recorded the body, the displayed sender, and the time. That work is slow and destination-specific; it is also the only way to attach meaning to route-level claims. This methodology page stops at sourcing rules for published matrices. The testing cluster covers how we design those checks when we run them—without treating an untested cell as a green result.

The SMSRoute corrections log records every published error and its fix - the same policy applies to these comparison pages.

Run your own comparison with a small test matrix

A reader does not need a large program to pressure-check a shortlist. Build a sheet with one row per provider under consideration and a small set of columns you can actually fill. Suggested columns: public floor or band for each destination you care about; retrieval date and source URL; signup path as documented; settlement methods as documented; API surface you will use (HTTP, SMPP, or both); whether delivery callbacks are documented; and three empty result columns reserved for your own tests—submit acceptance, callback status observed, handset-confirmed arrival.

Keep the first pass to published facts only. Fill rates and claims from primary pages on the same day so timestamps align. Where a price is account-gated, mark it gated rather than pasting a number from memory or from a sales chat. Where a destination is absent, leave it blank. Resist the urge to compute a winner from incomplete columns; the point of the sheet is to show which decisions rest on citations and which rest on work you still owe yourself.

For the test columns, pick a minimal traffic shape: a handful of destinations that matter to your product, both GSM-7 and UCS-2 bodies if you send both, and bodies near the segment boundaries (160/153 and 70/67) if concatenation matters to billing. Record request identifiers, timestamps, HTTP statuses or SMPP responses, callback payloads, and handset observations in the same row. If you summarize latency, publish p50 and p95 for your sample and state the sample size in plain language (count of messages), not as a universal route grade.

Interpret gaps as gaps. A provider with a clear public floor and sparse route proof is a different risk profile from a provider with no public floor and glowing adjectives. Your matrix should make that difference visible without inventing fill values. If you later sign a contract rate, keep the public floor row for reference so you can see what changed between the open page and the agreement.

ColumnWhat belongs in it
Published rateFloor or band from the provider’s own page, copied verbatim
Source and datePrimary URL plus retrieval date for that cell
Signup and settlementOnly steps and methods the public flow or docs describe
Your submit checkAcceptance outcome you observed (for example HTTP 200 vs 429/500)
Your DLR checkCallback or receipt fields you received, mapped to your definitions
Handset confirmationBody, displayed sender, and time you independently observed

Corrections policy and how SMSRoute appears in the matrix

Providers and readers will find cells that are stale, mis-scoped, or plain wrong. Send corrections to ops@smsroute.cc with the matrix name, the cell coordinates or provider row, the URL you believe is authoritative, the text or figure as you read it, and the date you retrieved it. If you are the provider, a pointer to the pricing or docs page that supersedes our snapshot is enough; you do not need marketing narrative.

We review corrections against the same sourcing rules used to build the matrix: primary public pages win over secondary commentary. When we change a cell, we update the retrieval date and record the edit in a public corrections log so readers can see what shifted and why. Disputes that ask us to publish an unpublished contract rate, a private SLA, or a delivery quality score we have not measured will be declined; those requests ask for a different artefact than a published-rate matrix.

SMSRoute is listed under the same constraints as everyone else. Our comparison surfaces cite published floor rates and the public facts we choose to compete on—email-only signup and crypto settlement—when those facts appear in our own materials. We do not pad SMSRoute rows with unmeasured delivery claims, and we do not omit another provider’s public floor to make a contrast look sharper. If a cell cannot be sourced, it stays empty. Empty is more honest than a decorative number.

The method behind the matrix is deliberately boring: quote primary pages, date the quote, separate tariff from route behaviour, and leave unmeasured qualities unmarked. Boring is what makes the grid usable for developers who have to defend a vendor choice with links rather than adjectives.

Frequently asked

How do you source the rates in the SMS provider comparison matrix?
Each rate cell cites the provider’s own public page, with the source URL and a retrieval date. We use primary pricing or docs pages, not affiliate roundups. If a price is behind login or absent, we mark it gated or leave the cell empty rather than invent a figure.
Why don’t you rank SMS providers by delivery quality?
Delivery quality needs controlled submit checks, delivery-report reconciliation, and handset confirmation. Marketing pages do not supply that evidence. The published-rate matrix sticks to published rates, published claims, and documented signup requirements; route behaviour belongs in separate testing, not in an unsourced score.
How can I correct an error in the comparison matrix?
Email ops@smsroute.cc with the matrix and cell, the authoritative URL, what the page shows, and your retrieval date. We apply the same primary-source rules and, when we change a cell, update the retrieval date and note the edit in the public corrections log.

Related