Inspiration

In June 2022, Congress let US importers file complaints with the Federal Maritime Commission over ocean carrier charges they believe are wrong. In just over 10 months, those complaints got $1,045,953 refunded or waived, mostly detention and demurrage fees that should never have been billed.¹

That only counts the importers who noticed and pushed back. Most small ones can't: in a Freightos survey of 500+ US importers, 42.4% spend over two hours on every shipment (about $100 of labor each, by the survey's estimate), and 47% run it all in spreadsheets.² Nobody has time to check the invoice against what was actually agreed.

And what was agreed is scattered across a quote PDF, an email amendment and a WhatsApp thread. Our real-world example: a $7,500 forwarder invoice against a $6,500 quote. Some of the extra $1,000 was approved in a chat. Some of it nobody agreed to. The bookkeeper has to pay by Thursday.

Freight-audit tools check invoices against one contract or rate card. Small importers don't have one. So we built a tool that rebuilds the real agreement from the messy sources, asks the right person when evidence is missing, and changes its answer when they reply.

Checked before you pay.

¹ Federal Maritime Commission, via The Maritime Executive (May 2023). ² Freightos / Google Surveys, via MH&L (2018).

What it does

CargoOS reads the quote, emails, chats and invoice, and sorts every line into To dispute, Waiting on answers or Cleared, each with a "why" line quoting the exact source text.

In the example, ocean freight is \$300 over the amended rate, and two lines (congestion fee, rush handling) have no evidence either way. CargoOS asks the owner one specific question. He replies:

"approved the $200 congestion fee on WhatsApp, nobody agreed to $400 rush handling"

The congestion fee clears, rush handling moves to dispute, and every screen updates live:

$$ \text{At stake} = \$300 + \$400 = \$700 \;(9.3\%\text{ of the invoice}), \qquad \text{Pay} = \$7{,}500 - \$700 = \$6{,}800 $$

Then segregation of duties, enforced on the server: the bookkeeper requests approval, the requester can never approve their own request, and the owner accepts or rejects with a required reason. After acceptance, CargoOS drafts the dispute letter. Nothing is ever sent or paid automatically. "Not an issue" decisions are remembered per forwarder as a stored rule you can undo.

How it saves money

  • Catches overcharges before payment, when they're easy to dispute, instead of chasing refunds later.
  • Cuts the checking time: no digging through threads; CargoOS shows the line, the source quote and the one question that matters.
  • Illustration, not measured: an importer paying 50 forwarder invoices a year, where one in five looks like our example, would hold back 10 × \$700 = \$7,000 a year in charges nobody agreed to, before counting the hours saved.

How we built it

  • Next.js, TypeScript, Tailwind, shadcn/ui on Vercel.
  • Convex for the database, file storage, reactive queries, mutations and actions. When a reply is processed, every open screen updates by itself.
  • Claude (Anthropic API) for the language work: extracting facts from PDFs, emails, chats and screenshots; deciding when and whom to ask; reading replies (yes, partial, no, ambiguous); wording the letter.
  • A pure TypeScript engine for everything that decides money: rules, reconciliation, revisions, diffs, totals.

The core rule: Claude never computes amounts or decides statuses. Outputs are validated with Zod; every quote must be an exact substring of its source or it's dropped; every number in the letter is inserted by code; on failure we retry once, then mark needs review. Every action is an append-only event, so each decision is traceable.

Challenges we ran into

  • Keeping the LLM honest: an exact-quote check and a retry-then-needs review path instead of trusting output.
  • "It works" vs. "it's live": at 2 AM we found our UI still ran on recorded data. We wired every button to the real backend in under an hour, keeping the recording as an honest fallback.
  • Bugs only integration finds: a reset that skipped the first check, and three live actions silently not calling the backend. Tests caught both before the demo.

Accomplishments that we're proud of

  • A real agent, not a script: a reply the recording never had ("nobody approved either fee") gives $900 at stake on the deployed app, not the scripted $700.
  • Engine eval (Scenario A + 10 variations, answer keys we wrote): 127/127 statuses, 0/110 false positives, 11/11 question decisions, 309/309 valid source quotes, 57/57 totals.
  • 700+ tests in CI, including the full reply → Claude → engine → $700 chain on recorded responses.
  • Honest about what's real: synthetic documents and seeded people; eval on our synthetic set only.

What we learned

  • Use the LLM where language is hard; keep it away from arithmetic and authority.
  • Reactive backends make "the agent changed its mind" visible the moment evidence changes.
  • One honest end-to-end check beats a perfect component in isolation.

What's next for CargoOS

  • Pilots with real importers to measure dollars recovered and hours saved per invoice.
  • Demurrage and detention checks against the FMC billing rule.
  • A running history per forwarder of what was billed, disputed and accepted.
  • Direct intake from email and WhatsApp, so nobody has to upload anything.

Built With

Share this project:

Updates

Submission history