Skip to content

Freight invoicing has no billing period — it has a window

Why freight bills by grouping window instead of calendar month, and what that does to document numbers, fuel gaps, and issued invoices.

Sonic AI team

Finance operations

8 Sept 20265 min read

Shipment & FreightRate cards, uploads, shippers, and billing movements — not monthly SaaS.

A subscription invoice has a period because the contract has one: January's fee for January's service. A freight invoice does not have a natural period at all. A haul happens on a date. The carrier charged for that date. The only "period" is whatever grouping rule you and the shipper agreed to — and if your billing system does not model that distinction, it invents a fake monthly schedule for something that was never monthly.

That invented schedule is where freight billing quietly breaks: an invoice that groups by calendar month instead of by contract window, a document number that repeats because two different groupings produced the same "March" bucket, a fuel surcharge that goes missing because nobody noticed the rate table had a gap on the 14th.

Rating happens per shipment, grouping happens after

Every haul is rated on its own attributes first — carrier, lane, weight, accessorials, the fuel index in effect on that date. Grouping is a separate, later decision: do these rated shipments become one invoice each, or do they roll up into a window?

That ordering matters. If you group before you rate, a single bad row (missing fuel data, an unmatched shipper) can silently drag down or corrupt an entire month's invoice. Rate first, group second, and one bad shipment stays one bad shipment.

Four grouping shapes, one rule

A shipment contract declares its billing frequency, and that frequency decides the invoice shape:

Frequency What lands on one invoice
None Exactly one shipment
Daily Every shipment for that shipper on that calendar day
Weekly A 7-day window from the contract's start date — not necessarily Monday–Sunday
Monthly A calendar month; the leftover days at the contract's edges become their own stub period

Weekly is the one that trips people up. A weekly window is defined by the contract's own start date, not the calendar week. Two shippers on the same carrier can have windows that don't line up with each other at all, because their contracts started on different days. That is by design — the window belongs to the agreement, not to a shared company calendar.

Document numbers have to survive the grouping

Once you accept that an invoice can represent one shipment or fifty, the numbering scheme has to answer a question subscription billing never asks: what identifies this invoice when there is no single "the shipment" to point to?

The answer splits on cardinality. When exactly one shipment lands on an invoice, the mapped invoice-number column from the carrier's own file can be used directly — the customer already recognizes that number. The moment more than one shipment groups onto a single invoice, that per-shipment number stops meaning anything, and the invoice needs its own identity: shipper, carrier, and the window's start and end date, concatenated into one deterministic string. Two shippers, two carriers, or two different weeks never collide, because the number is built from the thing that actually varies.

Why a rate gap has to stay a gap

Fuel surcharges come from a published rate table, and that table can have holes — a date nobody entered because the update was late. The tempting fix is to fall back to whatever value is nearest, or to the carrier's default table. Sonic doesn't do that. A missing date on the table a carrier is assigned to stays missing; the fuel term either drops out of that shipment's formula or the shipment fails rating visibly, depending on how the formula is written. It never silently borrows a number from a different table.

That is a deliberate trade against convenience. A carrier priced 40 cents higher because someone forgot to publish Thursday's fuel index is an invoice you can explain and correct. A carrier priced correctly because the system guessed is an invoice you cannot explain at all, and you will not know it happened until a shipper's rate auditor finds it first.

What "issued" means when a new shipment shows up late

Carrier files arrive incrementally — this week's export, then next week's, then a correction. If a window's invoice already went out and a new shipment for that same window turns up in a later file, it does not get added to the sent invoice. It starts a new one alongside it. The alternative — quietly reopening a document a customer has already seen — is the same failure mode as adding a line to any sent invoice, just with a shipping manifest instead of a subscription line item. A carrier export that never stops growing is exactly the scenario immutability exists for.

What this replaces

Teams coming off a spreadsheet-and-formulas process for freight are usually simulating all of this by hand: a tab per carrier, a manual VLOOKUP against a fuel table, a running list of "already invoiced" shipment IDs to avoid double billing. The rules above are what that spreadsheet was actually trying to enforce — they just weren't written down anywhere, so the next person who touched the sheet broke one of them without knowing it existed.

Watch out for

  • Weekly windows follow the contract's start date, not the calendar. Two shippers on the same carrier can have out-of-sync weeks by design.
  • A rate gap is a signal, not a bug to route around. Publish the missing date; don't accept a fallback number.
  • Grouped invoice numbers are deterministic, not sequential. They're built from shipper, carrier, and window — not a running counter that can drift.
  • A sent freight invoice is as frozen as a subscription one. Late hauls for an already-invoiced window need their own document.
  • An expired contract term is not a fallback rate source. A haul outside the contract's dates does not get priced against it.

See it on the platform

Everything above describes how Sonic actually runs it — the product pages show the screens.

Related questions

Still have questions?

What's the difference between subscription mode and shipment mode?

Subscription orgs bill from contracts and schedules — phases, seats, usage, activation gates. Shipment orgs bill each movement from a carrier contract and a rate card. Shippers and carriers are separate catalogs. The bill-to on collections, bank rec, and revenue is the shipper.

Who is the bill-to on freight?

The shipper. Not the Customer catalog, and not the carrier. Watchtower, bank rec, and the journal use the shipper as the billed party. The mapped column on the file is always who gets the invoice.

How do diesel / rate-index branches work?

Default is the main published series. A branch is a complete table for listed carriers. A carrier belongs to one branch. A missing date on the chosen series does not fall back to the other table. Issued invoices keep the rate they were billed. The full rules live on the shipment platform page.

See the full FAQ →

Next

See it on your contracts

A walkthrough on the agreements and files you actually bill from — not a slide deck.