The agent API
Search, book and track flights — and buy products on merchant websites — programmatically: x402-paid, wallet-identified, schema at /openapi.json.
API quickstart (agents)
Base URL: https://travel.brij.fi · full schema:
/openapi.json · payments: x402 (USDC on Solana).
Any x402-capable client works; without payment, endpoints reply 402 with the
exact price and payment instructions.
# 1 — search (x402-paid; price is dynamic, quoted in the 402 challenge)
curl -X POST https://travel.brij.fi/air/search \
-H "Content-Type: application/json" \
-d '{"origin_iata":"MAD","destination_iata":"BCN","depart_date":"2026-12-15",
"adults":1,"cabin_class":"economy","cheapest_per_itinerary":true,"limit":20}'
# → offers[], each with an offer_id. status "enriching" + search_id?
# poll POST /air/search-updates {search_id} — free — until "complete".
# 2 — optional: drill into one offer (fare menu, baggage, current price)
curl -X POST https://travel.brij.fi/air/offer-details \
-d '{"offer_id":"trip.com:…"}'
# browser-tier fare rows carry their own bookable offer_id ("…##2") and fare_index.
# 3 — create the intent (0.10 USDC)
curl -X POST https://travel.brij.fi/air/intents \
-d '{"offer_id":"…","funding_wallet":"YOUR_WALLET"}'
# → intent.id, escrow_address, expected_escrow_amount, customer_support_code
# ⚠ SAVE customer_support_code NOW — it is never returned again.
# 4 — fund the escrow: transfer expected_escrow_amount USDC to escrow_address.
# 5 — book (x402 pays the escrow amount if not already funded)
curl -X POST https://travel.brij.fi/air/book \
-d '{"intent_id":"intent_…","passengers":[{"given_name":"…","family_name":"…",
"born_on":"1990-01-01","title":"mr","gender":"m",
"email":"…","phone_number":"+34…"}]}'
# 6 — track: GET /air/intents/{id} (free) until status "booked" / "refunded".
# The PNR: GET /air/orders/{order_id} with X-Customer-Support-Code
# (fastbooking), or the ticket email (browser tier).
intent_id; re-booking a booked intent returns 409. Refused calls
are never charged — a 402 that is not settled costs nothing.Buying a product (shop)
The same escrow, for a product on a merchant's own website: you name it by its URL, the marketplace reads the exact total at the merchant's checkout (shipping and sales tax included), you escrow that total plus the fee, and the merchant's own confirmation email releases the money. V1: one product line (quantity 1–10), US shipping addresses, USD, supported merchants only (a refusal names it, free).
# 1 — quote (0.25 USDC; every refusal is free)
curl -X POST https://travel.brij.fi/shop/quote \
-d '{"product_url":"https://shop.example.com/products/merino-crew-sweater",
"options":{"Size":"M","Color":"Charcoal"},"quantity":2,
"ship_to":{"country":"US","region":"CA","postal_code":"94107"}}'
# → offer_id "shop.example.com:q_…", breakdown (items, shipping, tax,
# merchant_total) and total_amount — ALL-IN: merchant total + 4 USDC + 3 %.
# 422 options_required lists each option's values in stock: ask, retry.
# 202 quote_pending: retry the SAME request after Retry-After (15 s).
# 2 — escrow (0.10 USDC) — same body and answer as /air/intents
curl -X POST https://travel.brij.fi/shop/intents \
-d '{"offer_id":"shop.example.com:q_…","funding_wallet":"YOUR_WALLET"}'
# ⚠ SAVE customer_support_code NOW — it is never returned again.
# 3 — buy: pays the escrow amount and hands over the address
curl -X POST https://travel.brij.fi/shop/buy \
-d '{"intent_id":"intent_…","recipient":{"given":"Ada","surname":"Lovelace",
"phone":"+14155550100"},"ship_to":{"line1":"500 Howard St","city":"San Francisco",
"region":"CA","postal_code":"94107","country":"US"}}'
# region + ZIP must be the quoted ones (409 ship_to_changed, free).
# 4 — track (0.01 USDC): purchasing → ordered → confirmed → shipped (+ tracking)
curl -X POST https://travel.brij.fi/shop/orders \
-H "X-Customer-Support-Code: …" -d '{"intent_id":"intent_…"}'
POST /shop/refund-requests.Buying train tickets (rail)
Same flow as a product, with a search in front: trains have to be found.
# 1 — search (0.25 USDC): station or city names
curl -X POST https://travel.brij.fi/rail/search \
-d '{"origin":"Paris","destination":"Lyon","depart_date":"2026-12-15","depart_after":"08:00","adults":1}'
# → journeys[] cheapest first: journey_id, times, price_from, total_from (all-in)
# 2 — quote one journey (0.25 USDC), optionally a fare ("Standard", "Flexible")
curl -X POST https://travel.brij.fi/rail/quote -d '{"journey_id":"thetrainline.com:d_…#0"}'
# → offer_id, breakdown, total_amount (all-in), expires_at
# 3 — escrow (0.10) then buy (escrow amount) with exactly the searched party
curl -X POST https://travel.brij.fi/rail/intents -d '{"offer_id":"…","funding_wallet":"YOUR_WALLET"}'
curl -X POST https://travel.brij.fi/rail/buy \
-d '{"intent_id":"intent_…","passengers":[{"given_name":"Ada","family_name":"Lovelace","born_on":"1990-01-01"}]}'
# 4 — status (0.01): POST /rail/orders {intent_id} + X-Customer-Support-Code
Endpoints & prices
| Endpoint | Price | What it does |
|---|---|---|
POST /air/search | 0.10 USDC × 1–50 load multiplier | Live two-tier flight search |
POST /air/search-updates | free | Poll a progressive search for late quotes |
POST /air/offer-details | 0.01 (fastbooking) / 0.10 (browser tier) | Refresh one offer; browser-tier fare menu with baggage & conditions |
POST /air/intents | 0.10 USDC | Create the booking intent + on-chain escrow |
POST /air/book | escrow amount | Register passengers, trigger the booking |
GET /air/intents/{id} | free | Booking status (reduced projection) |
GET /air/orders/{id} | 0.01 USDC | Airline order + PNR (needs X-Customer-Support-Code) |
POST /air/refund-requests | 0.10 USDC | File a refund request for human review |
POST /shop/quote | 0.25 USDC | Exact all-in price of one product at a merchant's checkout |
POST /shop/intents | 0.10 USDC | Create the purchase intent + on-chain escrow |
POST /shop/buy | escrow amount | Recipient + address, trigger the purchase |
POST /shop/orders | 0.01 USDC | Merchant order number, shipping, tracking (needs X-Customer-Support-Code) |
POST /shop/refund-requests | 0.10 USDC | File a refund request for human review |
POST /rail/search | 0.25 USDC | Search trains on supported rail merchants |
POST /rail/quote | 0.25 USDC | Exact all-in price of one journey |
POST /rail/intents · /rail/buy · /rail/orders · /rail/refund-requests | 0.10 · escrow · 0.01 · 0.10 | Same as their /shop twins |
The flight booking fee is 20 USDC + 2% of the ticket; the
shop fee is 4 USDC + 3% of the merchant total. Both are
included in every price the API returns and in expected_escrow_amount. Every displayed price on the
web app is fee-inclusive; the wallet quote at signing is always the
authority.
The clocks
| Clock | Duration | Meaning |
|---|---|---|
| Offer freshness | ~20–30 min | Offers expire after search; on 404, re-search |
| Lowcost fare menu | ~30 min | A ##n fare books only while its menu is fresh (409 fare_menu_expired) |
| Intent bookability | ~20 min | expires_at: prices move, book promptly or re-create at the current price |
| On-chain escrow lock | sized per tier | Outlives the whole settlement window, so a refund can never race a ticket |
| Lowcost capture hold | 24 h | No ticket email within the hold → automatic refund |
| Shop quote | ~20 min | The quote's expires_at; after it, quote again (409 offer_expired) |
| Shop capture hold | 6 h | No merchant confirmation within the hold → automatic refund |
Refunds & support
- Automatic: booking failure, supplier price change, cancellation, no-ticket timeout — the escrow refunds to the frozen refund wallet and the customer is emailed the refund transaction.
- Requested:
POST /air/refund-requestswithX-Customer-Support-CodeandX-Passenger-Family-Name(lead passenger). This files the request for human review — the refund target is the frozen wallet either way, so even an approved fraudulent request cannot redirect funds. - The support code is returned at intent creation and at
/air/book— persist it then; it cannot be re-read. It gates the PNR and refund requests. Humans: it is also in your emails. - Email: [email protected]
The web app (humans)
app.brij.fi is the same marketplace with a wallet UI: search, compare fee-inclusive fares (browser-tier fare menus load live while you fill the passenger form), pay with your Solana wallet, and receive your ticket by email — PNR, itinerary, and before-you-fly instructions. Saved travellers and memberships (fee waivers by invite code) are optional conveniences; your wallet remains the identity.
© 2026 Brij Digital · Terms · Privacy · [email protected]