<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: BookingTruth</title>
    <description>The latest articles on DEV Community by BookingTruth (@bookingtruth).</description>
    <link>https://dev.to/bookingtruth</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4145630%2F7e8e63de-9f2e-4e51-af81-b33fb2ff0c5d.png</url>
      <title>DEV Community: BookingTruth</title>
      <link>https://dev.to/bookingtruth</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bookingtruth"/>
    <language>en</language>
    <item>
      <title>How to verify a booking made by an AI agent (claim vs. proof)</title>
      <dc:creator>BookingTruth</dc:creator>
      <pubDate>Sun, 27 Sep 2026 23:06:59 +0000</pubDate>
      <link>https://dev.to/bookingtruth/how-to-verify-a-booking-made-by-an-ai-agent-claim-vs-proof-4n8m</link>
      <guid>https://dev.to/bookingtruth/how-to-verify-a-booking-made-by-an-ai-agent-claim-vs-proof-4n8m</guid>
      <description>&lt;p&gt;When an AI agent says "your flight is booked," that sentence is a claim. The agent's tool returned something that looked like success, and the agent relayed it. Whether a reservation actually exists in the supplier's system of record is a different question - and nobody in the loop asks it by default.&lt;/p&gt;

&lt;p&gt;This post is about the gap between the two, and how to close it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Confirmation numbers are claims, not proof
&lt;/h2&gt;

&lt;p&gt;A booking flow usually ends with the agent holding a confirmation number or PNR from a tool call. That string proves a tool returned a string. It does not prove:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the PNR exists in the supplier's system&lt;/li&gt;
&lt;li&gt;the ticket was actually issued (confirmation != ticket)&lt;/li&gt;
&lt;li&gt;the reservation wasn't cancelled or dropped after issuance&lt;/li&gt;
&lt;li&gt;the seats, rooms, or dates match what was paid for&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Production failure modes we've seen: booking APIs that return 200 while the supplier never creates a record; tickets stuck in "pending issuance" that silently fail hours later; OTA confirmations that reference reservations the hotel can't see.&lt;/p&gt;

&lt;h2&gt;
  
  
  What proof looks like
&lt;/h2&gt;

&lt;p&gt;The only evidence that settles it is supplier-authoritative: the airline's own record, the hotel chain's central reservation system, the GDS. Anything else is a copy of a copy.&lt;/p&gt;

&lt;p&gt;A rough evidence ladder, weakest to strongest:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The agent's own summary (worthless as evidence)&lt;/li&gt;
&lt;li&gt;The booking tool's response body&lt;/li&gt;
&lt;li&gt;A confirmation email (often sent before ticketing completes, and stale the moment anything changes)&lt;/li&gt;
&lt;li&gt;The OTA or aggregator's itinerary page&lt;/li&gt;
&lt;li&gt;Supplier-authoritative record: the PNR or ticket status read from the airline, hotel chain, or GDS directly&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If your agent hasn't checked #5, the honest status is UNKNOWN, not CONFIRMED.&lt;/p&gt;

&lt;h2&gt;
  
  
  A practical verification loop
&lt;/h2&gt;

&lt;p&gt;For an agent that just made a booking:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Capture the claim: PNR or confirmation number, supplier, dates, traveler.&lt;/li&gt;
&lt;li&gt;Wait out the supplier's latency window (30-180 seconds is normal; ticket issuance can lag longer).&lt;/li&gt;
&lt;li&gt;Query the supplier-authoritative source for the record.&lt;/li&gt;
&lt;li&gt;Only then mark the booking confirmed. If the record isn't there, retry with backoff, then fail loudly - never silently downgrade to "probably fine."&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is also the right gate before anything irreversible downstream: releasing escrowed funds, reporting the trip as booked to a user, or making the next booking that depends on the first one.&lt;/p&gt;

&lt;h2&gt;
  
  
  We built an API for the check
&lt;/h2&gt;

&lt;p&gt;We run BookingTruth, an evidence-gated booking verification API. You POST the booking details and get back a verdict: CONFIRMED only on supplier-authoritative evidence (#5 on the ladder), otherwise UNKNOWN with an indicated_state so the agent can decide what to do next instead of guessing. There's a REST API and an MCP server; the sandbox is free with any &lt;code&gt;sb_&lt;/code&gt; key and there's an llms.txt for agent consumption: &lt;a href="https://bookingtruth.com/llms.txt" rel="noopener noreferrer"&gt;https://bookingtruth.com/llms.txt&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why we built it this way: an agent that can't tell claim from proof will eventually book a phantom trip and learn nothing from it. Verification has to be a first-class step in the loop, not a log line.&lt;/p&gt;

&lt;p&gt;What's your agent's bar for calling a booking "confirmed"? Would you gate it on a supplier-authoritative check - why or why not? We're collecting builder answers, and they directly shape the API.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>security</category>
    </item>
    <item>
      <title>Your agent's "booking confirmed" is probably a guess. We built an evidence gate.</title>
      <dc:creator>BookingTruth</dc:creator>
      <pubDate>Sun, 27 Sep 2026 14:42:41 +0000</pubDate>
      <link>https://dev.to/bookingtruth/your-agents-booking-confirmed-is-probably-a-guess-we-built-an-evidence-gate-1neo</link>
      <guid>https://dev.to/bookingtruth/your-agents-booking-confirmed-is-probably-a-guess-we-built-an-evidence-gate-1neo</guid>
      <description>&lt;p&gt;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 &lt;em&gt;says&lt;/em&gt; confirmed is not evidence that a supplier &lt;em&gt;recorded&lt;/em&gt; confirmed.&lt;/p&gt;

&lt;p&gt;We kept hitting this building travel agents, so we built &lt;strong&gt;BookingTruth&lt;/strong&gt;: 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.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rule that does the work
&lt;/h2&gt;

&lt;p&gt;Every claim a parser extracts carries an &lt;strong&gt;evidence tier (0-6)&lt;/strong&gt; - a measure of how authoritative the signal is, not how confident a model feels:&lt;/p&gt;

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

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

&lt;h2&gt;
  
  
  Dogfooding it on real receipts
&lt;/h2&gt;

&lt;p&gt;We ran the live API against actual booking receipts this morning:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;United, booking confirmation + eTicket receipt (a real pair):&lt;/strong&gt; &lt;code&gt;CONFIRMED&lt;/code&gt;, tier 5, via the rule &lt;code&gt;united.eticket_implies_ticketed&lt;/code&gt;. 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.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Expedia car rental confirmation:&lt;/strong&gt; &lt;code&gt;UNKNOWN&lt;/code&gt; with &lt;code&gt;indicated_state: confirmed&lt;/code&gt;, tier 3, &lt;code&gt;needs_primary_check: true&lt;/code&gt;. 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.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A hotel stay reminder from a chain we don't cover:&lt;/strong&gt; clean &lt;code&gt;UNKNOWN&lt;/code&gt;, &lt;code&gt;supplier: unknown&lt;/code&gt;. No invented answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it - free sandbox, no signup
&lt;/h2&gt;

&lt;p&gt;The round trip is two curls. Demo fixtures (synthetic) included:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# list the demo documents&lt;/span&gt;
curl https://api.bookingtruth.com/v1/demo/fixtures

&lt;span class="c"&gt;# run a check - any Bearer key starting with sb_ works&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.bookingtruth.com/v1/check &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer sb_demo"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"documents": [{"filename": "doc.txt", "content": "&amp;lt;raw email text&amp;gt;"}]}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every verdict links a proof packet: the claims, their tiers, the rule trace, and source hashes behind the decision.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use it from your agent (MCP)
&lt;/h2&gt;

&lt;p&gt;It's a remote streamable-HTTP MCP server - no install:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"bookingtruth"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://api.bookingtruth.com/mcp"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tier-6 live supplier lookups&lt;/strong&gt; - authenticated PNR retrieval so OTA UNKNOWNs become real verdicts. That's the North Star.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;More parsers.&lt;/strong&gt; Which suppliers should we add? Comments welcome.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Source (MIT, stdlib-only Python): &lt;a href="https://github.com/bookingtruth/bookingtruth-mcp" rel="noopener noreferrer"&gt;https://github.com/bookingtruth/bookingtruth-mcp&lt;/a&gt; - the repo has the full architecture docs, the API spec, and the test suite over the contradiction cases.&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>api</category>
      <category>travel</category>
    </item>
  </channel>
</rss>
