
This blog is written by AI for SEO
How to Build a Logistics Ontology: Orders, Shipments, Invoices
A logistics ontology is a shared map of your orders, shipments, carriers and invoices, plus the rules that tie them together, so a freight bill can be checked against a delivered shipment and an agreed rate instead of chased by hand. If your orders live in a TMS, your stock in a WMS, your payables in an ERP and your rate cards in a spreadsheet, you already have this map. It sits in a few people's heads and in a lot of VLOOKUPs.
This guide is for ops and freight-audit leads, not database engineers. It covers which things and links belong in the map, how to match the same shipment across systems, which rules are worth enforcing, and how to build it in Helix Foundry from its README and docs.
What a logistics ontology is, and the job it does
A logistics ontology is a written-down model of how your freight business fits together: the kinds of things you track (orders, shipments, carriers, invoices), how they connect, and the rules that must hold between them. In plain words, it answers "what do we mean by a shipment, and which invoice belongs to it?" in a form software can check.
The job is audit and exception handling. Today a freight bill arrives, someone finds the shipment in the TMS, finds the rate in a spreadsheet, compares the three by eye and emails the carrier if something is off. An ontology turns that into a standing check. Every bill is linked to a shipment and a rate when it lands, and the ones that don't fit surface as exceptions with the evidence attached.
It isn't a new TMS and it doesn't replace your ERP. It sits across them. If you want the general version of this idea before the freight specifics, start with how to build an ontology from scattered company data. We also wrote the same exercise for another industry in how to build an insurance ontology.
The core entities and links: shipper, consignee, order, shipment, leg, carrier, invoice, rate, exception
Start with nine things and the links between them. Don't add more until the first rules work.
Shipper and consignee: who sends and who receives. Both are parties, and one company is often both on different loads.
Order: what the customer asked for. One order can split into several shipments.
Shipment: the physical movement. It belongs to an order, has a shipper and consignee, and is made of one or more legs.
Leg: one carrier's stretch of a shipment, such as pickup to port, or port to depot. Each leg has one carrier.
Carrier: the company that moved the leg and bills for it.
Invoice: the carrier's bill, with lines. Each line should point at a leg or shipment.
Rate: the agreed price for a lane, service, weight band or accessorial, with the dates it applies.
Exception: a recorded problem, such as a bill with no delivered shipment, a charge above the agreed rate, or a duplicate.
The links carry the meaning. Order has shipments. Shipment has legs. Leg is moved by a carrier. Invoice line bills a leg. Leg is priced by a rate. Exception is raised about an invoice line. Write these as sentences first. If you can't say the sentence, the link isn't ready to build.
Keep exceptions as entities, not as a colour in a spreadsheet cell. An exception with a reason, an owner and a resolution is something you can count, age and report on.
Matching the same customer and shipment across TMS, WMS, ERP and spreadsheets
The hard part isn't the model. The same customer and the same shipment have different names in every system. The TMS has a load number, the WMS has an outbound reference, the ERP has a sales order and the carrier prints a PRO or bill-of-lading number on the invoice. "Acme Retail Ltd" in the ERP is "ACME RETAIL" in the TMS and "Acme (Leeds DC)" in someone's spreadsheet.
Do the matching in this order, cheapest and most certain first:
Exact keys. Shipment reference, BOL or PRO number, PO number. These resolve most of the volume.
Normalised names and addresses. Case, punctuation, suffixes like Ltd and Inc, and postcode formats.
Combined evidence. Same carrier, same pickup date within a day or two, same origin and destination, same weight. No single field proves it, but together they usually do.
A person, for the rest. Anything below your confidence line goes to a review list, not into the model.
Write down each match with the evidence behind it. When finance asks why invoice 4471 was linked to shipment S-2209, the answer should be the PRO number and the date, not "the system decided." Unmatched items aren't failures to hide. A bill with no shipment is exactly the thing you're trying to catch.
Rules worth enforcing: invoice to delivered shipment to agreed rate, and duplicate or unmatched freight bills
A freight audit is a three-way match: the invoice, the shipment record and the rate agreement. Encode that, plus duplicates, and you've covered most of the money.
Rule 1: every invoice line points at a delivered shipment. If the shipment never shipped, was cancelled, or has no proof of delivery, the line is an exception. Hold it. Don't approve it.
Rule 2: the billed amount fits the agreed rate. Use the rate in force on the ship date, not today's. Check linehaul, fuel and each accessorial. Set a tolerance so a one-cent rounding difference doesn't drown your queue.
Rule 3: no duplicate bills. Check repeated invoice numbers, and also the same shipment or PRO billed twice under different invoice numbers. Spreadsheets miss the second kind.
Rule 4: no unmatched bills. An invoice that can't be linked to any shipment is held and routed to a person. It is never auto-approved.
Rule 5: accessorials need evidence. Detention, liftgate or redelivery charges should be supported by something in the shipment record.
The pattern is the same each time: a rule, a threshold, and a named place for breaks to go. Only approved bills and their supporting data should move on to accounts payable, and the exception reason should stay with the record for disputes.
Build it in Helix Foundry: clone and run, or Helix Cloud, then connect, generate, review rules, load and ask
Helix Foundry connects your databases, tools and documents, drafts one ontology over them and loads it into HelixDB as a connected graph you can explore and question. Foundry is the app, HelixDB is the database it loads into. It's open source under Apache-2.0.
Get it running. Locally, with Docker Compose v2 and ports 3000 and 8333 free:
git clone https://github.com/helixdb/helix-foundry.git
cd helix-foundry
docker compose up -d --wait
Then open http://localhost:3000. The local install is single-user on localhost with no sign-in, so keep it on your own machine and don't expose it. Or use Helix Cloud at foundry.helix-db.com and choose Set up with your agent.
Then follow the flow in the quickstart:
Connect. Add your sources, for example a Postgres copy of your TMS tables, a CSV export of carrier invoices and the rate card sheet. Test each one and sync its tables.
Generate. On the ontology, choose Generate and describe what it should support, such as "match carrier invoices to delivered shipments and agreed rates, and flag duplicates." Foundry drafts types, links, data mappings and rules from your synced tables, API sources and document sets. Contracts and rate agreements can go in as documents.
Review rules. Open Review version and read the Rules tab. Edit or add rules, then create a new version and make it current. Rules 1 to 5 above go here, and a person approves what the draft proposed.
Load. Load the current version. The load's Rule breaks page shows recorded violations, so unmatched and out-of-rate bills appear as a list you can work.
Ask. Put questions in plain language, such as which carrier invoices have no delivered shipment, and explore the graph. Every value traces back to the row or document quote it came from.
Keeping it correct: exceptions, link errors and schema changes as your lanes and data change
A logistics ontology goes stale the moment you add a carrier, a lane or a new accessorial, so plan for change from day one. Three things go wrong.
Wrong links. A shipment matched to the wrong invoice is worse than an unmatched one, because it hides a problem. Review rule breaks instead of silently auto-fixing them, so the evidence stays auditable. Foundry records violations and sends them to a person, which is the behaviour you want.
Exceptions that pile up. Treat the exception list as a work queue with owners. If one carrier generates most of the breaks, that's a rate-card conversation, not a data problem.
Schema drift. A new column in the TMS export, a new service level, or a renamed field will break a mapping. When your data changes, generate a fresh draft, review what changed in the Rules and mappings, make it the current version and load again. Versions let you see what changed and why instead of editing a live model in place.
Review breaks weekly. The model stays correct because people keep deciding the edge cases, and the rules encode those decisions.
Trade-offs: when you need a logistics ontology and when a spreadsheet join is enough
Use a spreadsheet join when you have one carrier, one system and a few hundred bills a month. A VLOOKUP on PRO number plus a rate table does the job, and an ontology is overhead.
Build the ontology when these are true:
Bills, shipments and rates live in three or more systems under different IDs.
You have many carriers with their own formats and accessorial charges.
Duplicates and rate overcharges are slipping through, and you only find them in disputes.
You want an AI agent or workflow to act on this data and need it to get entities right.
Someone has to explain, after the fact, why a bill was paid.
There are costs. You must agree definitions (is a split delivery one shipment or two?), clean your rate cards, and have someone own the review queue. The ontology won't fix bad source data. It will show it to you. That's useful, but budget the time.
For teams comparing options, an open-source alternative to Palantir Foundry for ontologies covers how Foundry differs from the enterprise builders.
FAQ
Common questions on logistics ontologies are answered below.
Start with one lane and one carrier's invoices
Don't model your whole network first. Pick one carrier, export its last three months of invoices, your matching shipments and the rate card, and run the three-way match as rules. The breaks you see in week one will tell you which links and rules to add next. Clone Helix Foundry, run docker compose up, and connect those three files to see which freight bills fail the check.