{"name":"booking-layer","description":"Non-custodial booking layer for AI agents (MCP) and humans (API). Live: hotels. Coming soon: flights. Submit a signed proposal (intent mandate); search within its scope; book if a match exists. Pay via x402/USDC or a card gateway. One-shot or standing/revocable authorization; non-custodial escrow; signed receipts. No login.","version":"0.4.0","mode":"production","notice":"Live production endpoint. NOTE: bookings cannot currently settle — we are the merchant-of-record (not a marketplace) and have no pre-funded capital to pay suppliers yet, so `book` will not complete. Use the testing sandbox below for the full verify→search→book flow.","testing":{"recommended":true,"restApi":"https://booking-layer.ianb-sia.workers.dev/test/v1","mcp":"https://booking-layer.ianb-sia.workers.dev/test/mcp","install":"https://booking-layer.ianb-sia.workers.dev/install"},"mcp":{"transport":"streamable-http","url":"https://booking-layer.ianb-sia.workers.dev/mcp","config":"https://booking-layer.ianb-sia.workers.dev/mcp.json","sdk":"https://booking-layer.ianb-sia.workers.dev/sdk/booking-layer.mjs"},"kinds":["hotel","flight"],"connectors":{"mcp":"Model Context Protocol server — tools: list_services, search_offers, get_quote, create_signing_link, book","api":"REST — OpenAPI 3.1 at GET /openapi.json; full contract at GET /v1/schema","sdk":"BookingClient (TypeScript) — stateless agent client","discovery":["GET /llms.txt","GET /v1/discovery","GET /v1/schema","GET /openapi.json","GET /.well-known/ucp"]},"standards":{"ap2":{"supported":true,"descriptor":"GET /v1/ap2","note":"Intent/Cart/Payment mandate model + x402 extension (Google/Coinbase → FIDO Alliance)."},"ucp":{"supported":true,"manifest":"GET /.well-known/ucp","note":"Universal Commerce Protocol discovery + checkout-state surface."},"x402":{"supported":true,"note":"HTTP 402 + EIP-3009 USDC settlement; the AP2 x402 extension."}},"catalogue":"GET /v1/catalogue","payment":{"protocol":"x402","scheme":"exact","network":"eip155:84532","asset":"0x036CbD53842c5426634e7929541eC2318f3dCF7e","assetName":"USDC","assetVersion":"2","custody":"third-party: the Coinbase Commerce Payments AuthCaptureEscrow contract holds every budget (never a wallet of ours)","fundingModels":{"self":"agent self-funds: signs an EIP-3009 USDC authorization from its OWN wallet → pulled into the escrow contract via the ERC3009 token collector","pull":"agent pulls from the HUMAN's wallet within a standing allowance the human signed once → the SpendPermission token collector (refunds return to the human)"}},"serviceFees":{"hotel":"2 USDC","flight":"3 USDC"},"authorization":{"scheme":"EIP-712 Intent mandate (AP2-style delegation)","humanSignsOnce":true,"eip712":{"domain":{"name":"BookingLayerMandate","version":"1","chainId":84532,"verifyingContract":"0xBdEA0D1bcC5966192B070Fdf62aB4EF5b4420cff"},"types":{"IntentMandate":[{"name":"principal","type":"address"},{"name":"agent","type":"address"},{"name":"constraints","type":"BookingConstraints"},{"name":"budget","type":"Budget"},{"name":"detailsCommitment","type":"bytes32"},{"name":"nonce","type":"string"},{"name":"expiry","type":"uint256"}],"Budget":[{"name":"items","type":"ItemBudget[]"}],"ItemBudget":[{"name":"kind","type":"string"},{"name":"budgetAtomic","type":"uint256"}],"BookingConstraints":[{"name":"kinds","type":"string[]"},{"name":"where","type":"Place"},{"name":"origin","type":"Place"},{"name":"when","type":"When"},{"name":"party","type":"Party"},{"name":"facets","type":"Facets"}],"Place":[{"name":"continent","type":"string"},{"name":"country","type":"string"},{"name":"region","type":"string"},{"name":"city","type":"string"},{"name":"district","type":"string"},{"name":"postcode","type":"string"},{"name":"venue","type":"string"},{"name":"code","type":"string"}],"When":[{"name":"from","type":"string"},{"name":"to","type":"string"},{"name":"timeFrom","type":"string"},{"name":"timeTo","type":"string"},{"name":"minDurationDays","type":"uint256"},{"name":"maxDurationDays","type":"uint256"},{"name":"daysOfWeek","type":"string[]"}],"Party":[{"name":"maxTravelers","type":"uint256"},{"name":"maxRooms","type":"uint256"}],"Facets":[{"name":"cabinClass","type":"string"},{"name":"nonstopOnly","type":"bool"},{"name":"minStars","type":"uint256"},{"name":"cuisine","type":"string"},{"name":"seating","type":"string"},{"name":"refundableOnly","type":"bool"},{"name":"freeCancellation","type":"bool"},{"name":"board","type":"string"},{"name":"amenities","type":"string[]"},{"name":"propertyType","type":"string"}]},"primaryType":"IntentMandate"},"note":"The human signs ONE Intent mandate: a delegated agent, PER-ITEM budgets (each booking kind has its OWN cap covering the item + add-ons; you deposit the SUM, so one item never starves another), and graduated constraints (kinds; where region→country→city→area→venue; when date/range/duration; party size). The agent books autonomously within it; the layer captures the actual price per item and releases the unused margin."},"escrow":{"model":"non-custodial · third-party only","custody":"the Commerce Payments AuthCaptureEscrow contract (mock mode = in-memory model for dev/tests). We NEVER hold a budget in a wallet of our own.","contract":"0xBdEA0D1bcC5966192B070Fdf62aB4EF5b4420cff","behavior":"capture-to-merchant-on-confirmation / refund-to-payer-on-failure / auto-refund-on-timeout","maxBudgetAtomic":"100000000","maxBudgetUsdc":100},"endpoints":{"schema":"GET /v1/schema  (full agent manual: flow, intent schema + example, error catalog)","catalogue":"GET /v1/catalogue  (all bookable services, fees, required details)","sign":"GET /sign  (human wallet-signing page) · POST /v1/intents/prepare (EIP-712 payload) · POST /v1/intents/signing-link (emailable click-to-sign link; add standing:true for 'always allow')","revoke":"POST /v1/authorizations/revoke (turn off a standing authorization) · GET /v1/authorizations/status","search":"POST /v1/search","quote":"POST /v1/quote","book":"POST /v1/book — draws from your intent's ONE budget escrow. Either { token, quoteToken } (fund once at /v1/verify, then book parts — no per-booking signature), or all-in-one { signedIntent, quoteToken } + X-PAYMENT (opens a one-booking budget, then books).","booking":"GET /v1/bookings/:id","verifyReceipt":"POST /v1/receipts/verify","agentChallenge":"POST /v1/agent/challenge { agent } → { nonce, statement }","agentSession":"POST /v1/agent/session { agent, nonce, signature } → { session } (sign the statement; EIP-191)","agentIntents":"GET /v1/agent/intents (Authorization: Bearer <session>) → YOUR open intents' budget + expiry (no PII)","cancel":"POST /v1/budget/:token/cancel { kind, signature, deadline } (signed by principal or paying agent)"},"plans":{"note":"A multi-item 'plan' is just ONE intent with several per-item budgets: fund the sum at /v1/verify (one signature), then POST /v1/book { token, quoteToken } per part — each draws from its item's budget and the whole thing settles net-once from the single escrow."},"agentIdentity":{"note":"An agent can hold MANY intents (each a token → its own escrow/budget). Intents carry the human's PII, so they are NEVER exposed on a bare wallet address: prove control by signing a one-time challenge, then list YOUR intents (budget, parts, time-to-expiry) — metadata only, no PII.","flow":["POST /v1/agent/challenge { agent }","sign the returned statement (EIP-191)","POST /v1/agent/session { agent, nonce, signature } → { session }","GET /v1/agent/intents with Authorization: Bearer <session>"],"sessionTtlSeconds":3600}}