DEV Community

BookingTruth
BookingTruth

Posted on

Your agent's "booking confirmed" is probably a guess. We built an evidence gate.

Ask an AI agent to check whether a flight is actually ticketed and it will happily read the OTA email, see "You're all set!", and tell you you're confirmed. Sometimes that's true. Sometimes the airline never ticketed anything. The agent can't tell the difference, because an email that says confirmed is not evidence that a supplier recorded confirmed.

We kept hitting this building travel agents, so we built BookingTruth: a booking-assurance API (and remote MCP server) that parses booking confirmation emails and receipts, grades what each document actually proves, reconciles contradictions across documents, and returns a verdict with a citable proof packet.

The rule that does the work

Every claim a parser extracts carries an evidence tier (0-6) - a measure of how authoritative the signal is, not how confident a model feels:

  • Tier 5-6: supplier-authoritative. An authenticated supplier lookup, or a supplier-issued receipt carrying an issuance artifact - a 13-digit eTicket number is the classic example.
  • Tier 3: OTA confirmation. Expedia says your rental car is confirmed. Useful, but it's the middleman's word.
  • Tier 0: LLM output. It can never decide a verdict. Ever.

CONFIRMED only comes back on tier 5-6. Everything below returns an honest UNKNOWN with an indicated_state (what the documents suggest) and needs_primary_check: true. An OTA "confirmed" email is not ticketing. "We're processing your request" is not ticketing. An issued eTicket number is.

Dogfooding it on real receipts

We ran the live API against actual booking receipts this morning:

United, booking confirmation + eTicket receipt (a real pair): CONFIRMED, tier 5, via the rule united.eticket_implies_ticketed. The engine even logged the confirmation email's "processing" prose as a first-class conflict against the issued eTicket - then higher-class evidence won. Exactly the contradiction that fools a chat agent.

Expedia car rental confirmation: UNKNOWN with indicated_state: confirmed, tier 3, needs_primary_check: true. Expedia said "confirmed", but Expedia isn't the supplier, so the API refused to rubber-stamp it. This case is also the roadmap: tier-6 authenticated supplier lookups (PNR pulls) will let these resolve to real verdicts.

A hotel stay reminder from a chain we don't cover: clean UNKNOWN, supplier: unknown. No invented answer.

Try it - free sandbox, no signup

The round trip is two curls. Demo fixtures (synthetic) included:

# list the demo documents
curl https://api.bookingtruth.com/v1/demo/fixtures

# run a check - any Bearer key starting with sb_ works
curl -X POST https://api.bookingtruth.com/v1/check \
  -H "Authorization: Bearer sb_demo" \
  -H "Content-Type: application/json" \
  -d '{"documents": [{"filename": "doc.txt", "content": "<raw email text>"}]}'
Enter fullscreen mode Exit fullscreen mode

Every verdict links a proof packet: the claims, their tiers, the rule trace, and source hashes behind the decision.

Use it from your agent (MCP)

It's a remote streamable-HTTP MCP server - no install:

{
  "mcpServers": {
    "bookingtruth": {
      "type": "url",
      "url": "https://api.bookingtruth.com/mcp"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Two tools: booking_check (documents in, verdicts + proof packets out) and supplier_coverage (live seeded/planned parser matrix). Seeded today: United, Expedia, Disney.

What's next

  • Tier-6 live supplier lookups - authenticated PNR retrieval so OTA UNKNOWNs become real verdicts. That's the North Star.
  • More parsers. Which suppliers should we add? Comments welcome.

Source (MIT, stdlib-only Python): https://github.com/bookingtruth/bookingtruth-mcp - the repo has the full architecture docs, the API spec, and the test suite over the contradiction cases.

Top comments (1)

Collapse
 
bookingtruth profile image
BookingTruth •

Question for the agents and builders reading this: would you actually use an evidence gate like this in your stack - why or why not? We are collecting objections as eagerly as praise. If it would not survive contact with your workflow, tell us exactly where it breaks. Free sandbox key on the site if you want to poke at the API first.