Matching EDI 210 Invoices to EDI 204 Loads, Step by Step
Learn how to three-way match EDI 210 freight invoices against EDI 204 tenders and 990 responses, with field mappings and a dispute-handling workflow.
Freight bills don't lie, but they do arrive disconnected from the two documents that would prove whether they're correct. The fix is a configuration problem, not a policy one: if your inbound EDI 210 invoices aren't automatically cross-checked against the EDI 204 load tender you sent and the EDI 990 response the carrier sent back, you're paying freight bills on faith. This walkthrough covers exactly how to wire up an EDI 210 three-way match, field by field, including the discrepancy workflow and the duplicate-invoice failure mode that trips up almost every shipper the first time a carrier resubmits a bill.
What you need before you start
You need an EDI 204/990 flow that's already live and producing clean data, because the 210 match is worthless if the baseline it's matching against is wrong. Specifically:
- SCAC codes mapped per trading partner, consistent across your 204 outbound maps and your 210 inbound maps
- A TMS or freight audit module that can hold contracted rates, accessorial tariffs, and fuel surcharge tables per lane and per carrier
- Inbound EDI 210 connectivity over AS2 or a VAN, already tested with a working 997 functional acknowledgment loop so you know transport-level delivery isn't the problem when something fails downstream
- A load tender ID and PRO/BOL numbering scheme that survives the round trip from your TMS to the carrier's and back
If you haven't built the 204/990 side yet, stop here and do that first. There's no point configuring a match against a document stream you don't fully trust.
Step 1: Map the EDI 210 segments you actually need
You don't need all 74 segments and 504 data elements the X12 210 specification defines — most implementations only touch a handful. Build your inbound map around these:
- B3 (Beginning Segment for Carrier's Invoice): B301 is the shipment method of payment (PP prepaid, CC collect, TP third party), B302 is the PRO/freight bill number that serves as the carrier's invoice number and the primary document reference for disputes, B303 is the freight bill date, and B309 is the net amount due, as BetterEDI documents in its 210 breakdown.
- N9 (Reference Identification): carries PO numbers, BOL numbers, and shipment IDs. This is where your match keys live.
- R3/R4 (Route Information): origin and destination routing detail, useful for validating the invoice against the tendered lane rather than just the total charge.
- L3 (Total Weight and Charges): the invoice total the shipper audits against the agreed rate. A well-structured 210 also carries a line-by-line breakdown of charges, including base line-haul rate, fuel surcharge, and accessorials such as liftgate, detention, and hazmat handling, with charge codes that map to standard NMFC accessorial tariff codes, which is what makes automated audit feasible in the first place.
- B308 correction indicator: map this field explicitly. Carriers use AD for an amendment to a previously submitted invoice and RB for a rebill. If your map silently drops or ignores B308, you will not be able to distinguish a legitimate reissue from a duplicate original, which is exactly the failure mode in Step 5.
Step 2: Establish the match keys back to EDI 204 and 990
The join key is the BOL or PRO number, not the invoice number. Invoice numbers are assigned by the carrier's billing system and have no relationship to your load tender ID. B302 (PRO/freight bill number) and the BOL reference carried in your N9 segments are what trace the bill back to a specific shipment.
- Configure your matching engine to extract the BOL/PRO reference from the inbound 210's N9 loop and query it against your open load tender table, keyed by the same BOL/PRO value you assigned (or received back) on the original EDI 204.
- Pull the accepted rate from the corresponding EDI 990 response for that same shipment ID. The 990 tells you which carrier accepted the tender and at what rate, so it becomes your rate authority rather than whatever number lands on the invoice.
- Confirm the PRO number is the universal key across documents. As BetterEDI notes, the PRO number in B302 is the universal key that links the 210 to the BOL, the 214 status messages, and any claims, and separately that the 210's BOL number and shipment references trace back to the 204, allowing automated matching between what was tendered, what was shipped, and what was billed.
Watch for reference formatting drift. A carrier's TMS might zero-pad a PRO number or drop a leading character compared to what was on the original tender. Normalize both sides (strip leading zeros, trim whitespace, uppercase alpha characters) before the match query runs, or you'll generate false "no match found" exceptions on perfectly good invoices.
Step 3: Configure the three-way match rule set
The three-way match compares the 210's billed amount against the 204's tendered rate and the 990's accepted rate, then routes anything outside tolerance to a human. Define the rule set in layers rather than one blanket threshold:
- Auto-approve tolerance: set a dollar and percentage band, for example auto-approve within a small fixed variance and a 1% variance on total charges, whichever is tighter. Anything inside the band posts straight to accounts payable.
- Accessorial validation: check each accessorial charge code against the carrier contract and NMFC tariff codes referenced in the invoice's L-segment detail. An accessorial that wasn't pre-authorized on the 204, or one billed at a rate that doesn't match the contracted tariff, should fail even if the total invoice amount looks close enough.
- Weight and class checks: flag any invoice where the billed weight or freight class diverges from what was tendered, since this is a common vector for both legitimate reweighs and billing errors.
- Auto-routing: anything that fails tolerance, accessorial validation, or weight checks routes to an exception queue with the specific rule that failed attached, not a generic "discrepancy" flag. Your AP team needs to know whether it's a rate mismatch, an unauthorized accessorial, or a missing reference before they can act on it.
This is the same logic shippers running EDIFACT in Europe apply when matching an INVOIC message against a purchase order and goods receipt. The transaction set names differ, but the audit discipline is identical.
Where you hold the contracted rate matters as much as the rule logic. MercuryGate, Oracle Transportation Management, SAP TM, Blue Yonder, and multi-carrier platforms like Cargoson can all serve as the rate repository the match engine queries against, provided the contract and tariff data inside them is kept current. A three-way match is only as good as the rate table it's comparing to, so whichever platform holds that data becomes a dependency you need to maintain with the same discipline as the EDI maps themselves.
Step 4: Test with a controlled invoice batch
Don't flip the match on for your full carrier base on day one.
- Pick one carrier with high EDI maturity and pull five to ten known-good invoices, ones you've already manually verified as correct.
- Run them through the inbound pipeline and confirm the 997 acknowledgment fires correctly for each before worrying about match logic at all.
- Confirm matched invoices flow through to AP without manual touch and that the variance report only surfaces genuine discrepancies, not formatting noise from reference number mismatches.
- Once that carrier is clean for a full billing cycle, widen the rollout to additional SCACs one at a time rather than in a batch, so if something breaks you know which carrier's data exposed the gap.
You'll know it worked when the exception queue is small and every item in it corresponds to a real billing discrepancy, not a plumbing problem in your own mapping.
Step 5: Handle the most common failure mode — duplicate and ignored invoices
The single most common support ticket you'll get once this is live: a carrier insists they billed you, your system shows no record of payment, and the invoice simply vanished. This happens when a carrier resubmits an invoice without setting the correction indicator correctly.
Here's the documented behavior. IBM's Sterling TMS platform states plainly that a carrier can only submit one original carrier invoice as an EDI 210 transaction, and if the carrier submits another invoice marked as the original, the system ignores the second invoice and records an "Inbound Freight Invoice Ignored" entry in notes/history. The carrier's remittance team sees nothing come back, assumes a system glitch, and escalates. Your match engine did exactly what it was supposed to do: it correctly rejected a duplicate rather than double-paying.
- Check the ignored-invoice log first whenever a carrier reports a "missing" payment. The entry will show the original invoice already on file under the same B302 reference.
- Tell the carrier to resend with the correct correction indicator set in B308: AD for an amendment to charges on the existing invoice, or RB for a full rebill. If the carrier wants to submit an additional carrier invoice, the carrier must include the proper correction indicator in the EDI 210 transaction.
- Subscribe carrier-side EDI contacts to error notifications where that option exists, so a resubmission failure surfaces as an automated email rather than a phone call to your support desk. The email states that the original invoice was ignored because an invoice already exists, which is usually enough for a competent carrier EDI team to self-correct without opening a ticket with you.
Document this behavior in your trading partner onboarding packet. Most carrier billing teams have never been told that resubmitting an unmodified B3 segment does nothing, and it saves both sides a recurring argument.
Step 6: Roll out to the rest of your carrier base
Sequence the rollout by invoice volume, not alphabetically or by contract renewal date.
- Start with your top five carriers by invoice count. They generate the bulk of your freight audit workload, so getting them onto automated matching first delivers the fastest payback.
- Update your EDI trading partner agreement to specify the 210 as mandatory for freight billing, with the correction indicator requirement spelled out explicitly rather than assumed.
- Set a cutover date after which PDF and carrier-portal invoices are rejected for any carrier that's EDI-capable. Give at least one full billing cycle of overlap so carriers can fix mapping issues before the old channel closes.
On the vendor side, you have real choices for both the EDI layer and the TMS layer, and they don't have to be the same vendor. SPS Commerce, TrueCommerce, and Cleo handle the EDI translation and connectivity piece for a lot of shippers. On the TMS side, MercuryGate, Descartes, Oracle TM, and Cargoson are all platforms capable of holding the rate data your match engine needs. None of them is a drop-in fix for a three-way match that isn't configured correctly at the field level, which is the whole point of this walkthrough.
Common questions and troubleshooting recap
How is the EDI 210 different from the 110 or 410? They're mode-specific siblings in the same X12 family. The 210 covers motor carrier freight details and invoicing, the 110 is Air Freight Details and Invoice, and the 410 is Rail Carrier Freight Details and Invoice, so if you're adding ocean, air, or rail modes to the same audit discipline, you'll need separate maps and separate rate tables per transaction set.
What if the rate confirmation isn't digitized yet? You can still build the match, but your 990 rate becomes unreliable, which pushes more invoices into the exception queue than it should. Prioritize digitizing rate confirmation ahead of or alongside the 210 match rollout rather than after.
How long does this take? Expect a real EDI rollout, from initial field mapping through a staged carrier cutover, to run in the range other B2B transportation integrations typically take, which industry implementation guides put at roughly six to ten weeks depending on carrier count and how clean your existing 204/990 data already is.
The next concrete step: pull your last full billing cycle of 210 invoices, run them manually against the three checks above, and see how many would have auto-approved versus landed in an exception queue. That number tells you exactly how much manual freight audit work this configuration will take off your team's plate before you touch a single production map.