An unset product is a supported state that sends for free
Leavingproduct off a credential is legal configuration. It matches product:isNull: in the
routing table and it is priced only by rate rules that themselves carry no product.
That last clause is the whole trap. A rule with no product applies to every product, but a
message with no product sees only the rules that have none. They are not two spellings of “any”.
Two settings close it, both off by default:
Least-cost routing deliberately still tolerates a vendor with no cost rate — that is a different
question from whether the customer can be billed, and turning a forgotten vendor rate line into an
outage would be worse than the thing it prevents.
Why the check is membership, not non-emptiness
system_type on an SMPP bind overrides the credential’s product, and it is free text validated
nowhere else.
So a customer who binds prem when the product is premium passes any non-empty test perfectly, and
lands in exactly the unrated state above. Only checking the name against the catalogue catches it —
which is what conf.product.required does, and why it is not simply “product must be set”.
HTTP has no bind and therefore no override: there the credential’s product is the only source.
Before switching either on, read the pre-flight report on the panel’s Servers page: it lists the
logins that would stop connecting. Note what it cannot see — for an SMPP login it checks the
credential’s fallback, so a customer binding a mistyped system_type will not appear there.
The Pricing page carries the other pre-flight: the traffic of the last 24 hours that carried no
price, named by account and product. That is precisely what smsg.rating.unrated.refuse would begin
refusing. It counts messages whose CDR has no price_rule_id, so a rule deliberately set to 0 is
not in it — a free route stays free and keeps sending.
The catalogue row
Exempting a product from whitelisting
- An exempt product overrides the account. An account set to
ENFORCEstill sends freely under an exempt product. - No product is not exempt. Traffic naming no product at all is checked. Otherwise the way out of
a whitelist would be to stop sending a
system_type. - An unknown product is not exempt. A name with no row in
app_productis checked. It is a typo in a credential far more often than an intention.
enabled = false) also ends its exemption: exempt products are read as
enabled AND NOT whitelist_enabled. That direction is the safe one — traffic starts being checked
rather than stopping — but it can begin refusing sender IDs nobody has approved, so unlist an exempt
product deliberately rather than as tidying.
Naming a product on a REST send
A REST caller may sendproduct on /secure/send, /secure/sendbatch and /secure/rate, and it is
accepted only from a login whose allowedProducts names it.
An allow list rather than a plain field for the same reason as everything else on this page: the
product selects the rate, so a caller free to name their own product is free to pick their own price.
How pricing works
Where each side is priced, and what an unknown amount means.
Rolling whitelisting out
The four switches, and the order they apply in.