Skip to main content

smsg.money.scale applies to totals, not to rates

Above 4 is refused, because amounts are stored as ten-thousandths. Per-message rates and CSV exports always keep four places regardless of this setting. 0.0450 shown as 0.05 is 11% out on every message — fine for a balance, ruinous for a tariff.

smsg.cdr.deadline.hours is capped by the correlation window

Capped by smsg.dlr.correlation.days, which is 46 hours at its default. Past the correlation window a receipt can no longer be matched to its submission, so waiting longer only delays the same answer. A deadline above the cap is clamped and logged. See Delivery receipt store.

smsg.balance.block.min.messages is the floor that binds

Credit is reserved in blocks and spent from an in-memory counter, so there is no database write on the message path. This key says how many messages one block must be worth. It replaced a currency-denominated floor as the binding one, because smsg.balance.block.min is an amount and an amount cannot say how many messages it buys. At any realistic price the old default bought one or two, which put an idle account back at the database on its second message and refused it while a refill was in flight.
An actively sending account therefore holds up to 20 × price in reserved that nothing else can spend. Nothing is lost — balance + reserved is conserved — and a clean shutdown returns it. A kill -9 strands it until fireflo credit release runs.

smsg.billing.zone is read from the database only

The one key here read from app_config rather than from smsg.properties or the environment, and deliberately so. The nightly rollup slices usage_daily on it and the control panel slices the live tail of cdr_submit on it; if the two disagree, a sliver of one day is counted twice or not at all. An environment variable on the gateway host is invisible to the panel, so it could not be the shared source.
FIREFLO_BILLING_ZONE is still honoured as a fallback for deployments that set it before the key existed.

What a call record contains

CDRs carry destination and source addresses, because rating and dispute resolution need them, and never carry credentials.
They contain message content only when you switch it on. smsg.cdr.body ships off. Turning it on means message bodies are retained for the retention window and are readable by anyone with panel access or database access. Apply the same policy you apply to the access log.The same applies to smsg.cdr.events.response, which ships off and keeps up to 500 characters of what a customer’s own endpoint wrote back. Usually that is an error message and exactly what you need; an endpoint that echoes the request into its error body would put message content there too.

smsg.cdr.events now defaults to problems

It shipped off and was changed, because these rows are read after something has gone wrong and a level that has to be switched on beforehand is switched on too late every time. problems writes nothing while nothing is failing, so a healthy gateway sees close to no extra rows. Set smsg.cdr.events = off to restore the old silence exactly. Note that only the literal value off does so — an unrecognised value falls back to problems rather than to silence.

Batch billing units

Set to message, a customer sending three-segment messages pays for one and you pay your carrier for three. segment is the default for that reason.
See How pricing works for the model, and Prepaid credit and Postpaid for the two enforcement modes.