{"name":"TableScout","description":"TableScout — find and book restaurants. Give a city or coordinates and optionally a cuisine; get ranked restaurants with address, phone, website, hours, rating and whether they take reservations (Google Places, OpenStreetMap fallback). Books on venue APIs we hold or returns the booking URL and pre-filled form, free and keyless. Phone booking by an AI voice assistant: 1 USD per booking (x402, Solana); partners use a bearer. Never invents availability.","url":"https://dining.agent.meshkore.com","version":"0.1.0","protocolVersion":"0.3.0","capabilities":{"streaming":false},"defaultInputModes":["application/json"],"defaultOutputModes":["application/json"],"skills":[{"id":"search-restaurants","name":"Search restaurants","description":"Find restaurants in a city (or around coordinates), optionally filtered by cuisine, name keyword or open-now. Rows carry address, phone, website, opening hours and dietary flags, each linking its source. The top rows also carry `booking`: `{engine, url}` — the reservation link we found on the restaurant's own site — or `{phone_only: true}`; pick a row with a link and pass it to `book`. No `booking` means not checked.","tags":["restaurants","restaurantes","dining","food","comer","cuisine","where-to-eat","openstreetmap","discovery","booking","reservas"],"pricing":{"unit":"request","amount":0,"currency":"free"},"security":[],"examples":["restaurante italiano en Madrid","sushi near Barcelona city centre","{\"city\":\"Valencia\",\"cuisine\":\"tapas\",\"limit\":5}","{\"lat\":40.4168,\"lon\":-3.7038,\"radius_m\":1500,\"open_now\":true}"]},{"id":"book","name":"Book a table","description":"Book a table at a restaurant found by search. Where the restaurant gave us access to its booking engine (CoverManager, Zenchef, SevenRooms) we book it ourselves: CONFIRMED_API with the reservation id. When the venue needs a decision we ask: NEEDS_INPUT (e.g. the free times when yours is taken) or USER_CONFIRMATION_REQUIRED (a deposit or fee) — re-send the booking with each question's `field` set. Otherwise DELEGATE_TO_CLIENT with a `handoff` object: TableScout cannot book this restaurant itself (it never submits web forms or automates sites), so your agent should — `handoff` carries the reason, tier, engine, booking URL, phone, form fields and the exact client action; with execution \"unattended\" a dialable venue also gets `next`, the paid book-by-phone step. Where the engine allows it the URL already carries date, time and guests (`bookingUrlPrefilled` lists which). After booking on that page, please POST /v1/book/outcome {\"booking_ref\": <bookingRef>, \"outcome\": \"booked\"|\"no_availability\"|\"failed\"|\"abandoned\"} — no personal data, it only lets us count. If that booking URL did not work, re-send with `\"refresh\": true` and we look at the restaurant's site again. Never invents availability.","tags":["restaurants","restaurantes","dining","food","comer","cuisine","where-to-eat","openstreetmap","discovery","booking","reservas","booking","reservation","reservar"],"pricing":{"unit":"request","amount":0,"currency":"free"},"security":[],"examples":["{\"restaurant\":{\"id\":\"osm:node/123\",\"name\":\"Casa Pepe\",\"phone\":\"+34910000000\",\"website\":\"https://casapepe.example\"},\"date\":\"2026-09-27\",\"time\":\"21:00\",\"party_size\":4,\"customer_name\":\"R. J.\",\"customer_phone\":\"+34600000000\"}"]},{"id":"book-by-phone","name":"Book a table by phone","description":"An AI voice assistant phones the restaurant and asks for the table, on behalf of `principal`. Paid: 1 USD in SOL per booking (x402; the follow-up call is included, no free calls). Without a payment the POST answers 402 with the nonce, amount and wallet; pay with the nonce as memo and resend with x-payment-proof + x-payment-nonce; the 202 carries `jobToken` for polling (Bearer). Charged only when the job is created: a 4xx before dialing leaves the payment usable. Partner clients use their bearer and pay nothing. Asynchronous: answers PENDING_CALL with a `jobId` at once (a call starts in 1-60 s and takes a few minutes). Poll GET /v1/jobs/<jobId> (same auth, owner only) or pass `notifyUrl` (https) to receive the job as a POST signed with our MeshKore-Sig on every status change. Contract v2: the request carries the mandate and we never decide a tolerance for you. Required decisions: time (`when.exact`: true or a window `when.earliest`/`latest`), date (`when.dates`, [] = that day only), `seating.any` or must/avoid, `constraints.maxPenalty` (+ `paymentVia` if > 0), `constraints.minTableMinutes` (or \"never\"), `negotiation.outsideMandate` (defer | decline) and, unless decline, `followUp.callback` + `followUp.requestHoldMinutes`; for party_size > 6 also `seating.split.allow`, `party.min`, `constraints.setMenuPerPerson`. A request missing any is answered 422 {\"status\":\"NEEDS_MANDATE\",\"questions\":[{id (= the field path), text, choices, default_suggestion}]} with no call placed: resend it with the fields set. Unknown fields are a 400. If the restaurant raises something the mandate does not cover and outsideMandate is defer, the assistant asks for a hold, promises a call back and the job goes to NEEDS_INPUT with `result.questions` and `result.answerBy`; POST /v1/jobs/<jobId>/answers {\"answers\":[{\"id\":\"q1\",\"choice\":\"accept\"}]} (or {\"cancel\":true}) and a second call settles it. Final status: CONFIRMED_PHONE (unverified: no reservation id; `result.actionRequired` when a payment link is pending), NO_AVAILABILITY, DELEGATE_TO_CLIENT (reason) or FAILED. The assistant always says it is an AI and never gives card details. One request key never places two calls; a second job for the same restaurant, date and name while one is open is a 409 duplicate_risk; numbers that refuse AI calls are never phoned again.","tags":["booking","reservation","reservar","phone","voice","llamada"],"examples":["{\"restaurant\":{\"name\":\"Casa Pepe\",\"phone\":\"+34910000000\"},\"date\":\"2026-11-20\",\"time\":\"21:00\",\"party_size\":2,\"principal\":\"Ricart\",\"when\":{\"exact\":true,\"dates\":[]},\"seating\":{\"any\":true},\"constraints\":{\"maxPenalty\":0,\"minTableMinutes\":90},\"negotiation\":{\"outsideMandate\":\"defer\"},\"followUp\":{\"callback\":true,\"requestHoldMinutes\":60}}","{\"restaurant\":{\"name\":\"Casa Pepe\",\"phone\":\"+34910000000\"},\"date\":\"2026-11-20\",\"time\":\"21:00\",\"party_size\":2,\"principal\":\"Ricart\",\"when\":{\"earliest\":\"20:30\",\"latest\":\"22:00\",\"dates\":[]},\"seating\":{\"must\":[\"indoor\"]},\"constraints\":{\"maxPenalty\":40,\"paymentVia\":[\"link\"],\"minTableMinutes\":90},\"negotiation\":{\"outsideMandate\":\"decline\"},\"callbackPhone\":\"+34600000000\",\"idempotency_key\":\"order-123\"}"],"pricing":{"unit":"booking","amount":12300000,"currency":"lamports","network":"solana","est_usd":1,"scheme":"x402"},"probe":false,"security":[{"bearer":[]},{"meshkoreSig":[]},{"x402":[]}]},{"id":"cancel-by-phone","name":"Cancel a restaurant booking by phone","description":"An AI voice assistant phones the restaurant and cancels ONE booking on behalf of `principal`. Same access and price as book-by-phone: 1 USD in SOL per cancellation (x402: 402 challenge, pay with the nonce as memo, resend with x-payment-proof + x-payment-nonce; the 202 carries `jobToken`), free for partner clients with their bearer. Send either {\"bookingJobId\"} — a CONFIRMED_PHONE book-by-phone job of yours (a paid job also needs its jobToken as Bearer) — or the booking: restaurant {name, phone E.164, timezone?}, date, time, party_size, bookingName. Optional: confirmationCode, principal, persona, locale.lang (es|en), notifyUrl, idempotency_key, context. Unknown fields are a 400. Asynchronous: 202 PENDING_CALL + jobId; poll GET /v1/jobs/<jobId> or pass notifyUrl. One call, no follow-up. The assistant says it is an AI, asks to cancel, and reads back what was cancelled; it never rebooks, never changes the booking, never cancels a different one and never agrees to a fee. Final status: CANCELLED_PHONE (result.cancelled, unverified: no reference), NOT_FOUND (after one clarification, or only another booking was there), DELEGATE_TO_CLIENT (a fee or penalty was raised, they refused, no answer… with their words) or FAILED (retryable). POST /v1/cancel-by-phone/dry-run runs every check and dials nothing.","tags":["booking","cancel","cancellation","cancelar","anular","phone","voice","llamada"],"examples":["{\"bookingJobId\":\"job_0123456789abcdef01234567\"}","{\"restaurant\":{\"name\":\"Casa Pepe\",\"phone\":\"+34910000000\"},\"date\":\"2026-11-20\",\"time\":\"21:00\",\"party_size\":2,\"bookingName\":\"Ricart\",\"confirmationCode\":\"X7K2\",\"idempotency_key\":\"cancel-123\"}"],"pricing":{"unit":"cancellation","amount":12300000,"currency":"lamports","network":"solana","est_usd":1,"scheme":"x402"},"probe":false,"security":[{"bearer":[]},{"meshkoreSig":[]},{"x402":[]}]}],"pricing":{"unit":"request","amount":0,"currency":"free"},"payment":{"modes":["x402"],"network":"solana","wallet":"EHazqemLMqT4A1oEBVpKoWjb2cgjdLE2ajxzezcwCuHD","skills":{"book-by-phone":{"unit":"booking","amount":12300000,"currency":"lamports","network":"solana","est_usd":1,"scheme":"x402"},"cancel-by-phone":{"unit":"cancellation","amount":12300000,"currency":"lamports","network":"solana","est_usd":1,"scheme":"x402"}},"partners":"Partner clients send Authorization: Bearer <client token>: every skill free, phone included."},"payment_address":"EHazqemLMqT4A1oEBVpKoWjb2cgjdLE2ajxzezcwCuHD","access":{"mode":"tiered","free_tier":true,"tiers":{"public":{"skills":["search-restaurants","book"],"price":"free","auth":"none","rate_limit_per_minute":30,"keyed_by":"ip, or MeshKore-Sig identity when signed"},"paid":{"skills":["book-by-phone","cancel-by-phone"],"price":{"usd":1,"lamports":12300000,"per":"booking (follow-up call included) or cancellation"},"auth":"x402: POST without payment returns 402; pay, then resend with x-payment-proof + x-payment-nonce","free_calls":0},"partner":{"skills":"all, phone included, free","auth":["Authorization: Bearer <client token>","MeshKore-Sig (trusted identity)"],"contact":"contact@meshkore.com"}},"public":["/.well-known/agent.json","/health","/"]},"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"Partner client token issued by MeshKore: every skill free, phone included."},"meshkoreSig":{"type":"apiKey","in":"header","name":"MeshKore-Sig","description":"MeshKore-Sig. From a trusted identity it is a partner credential; any other signature only keys the public rate limit."},"x402":{"type":"apiKey","in":"header","name":"x-payment-proof","description":"x402 Solana payment (+ x-payment-nonce): 1 USD per phone booking; POST without it returns the 402 challenge."}},"protocols":["http","a2a"],"availability":{"now":true,"phone_booking":{"available":true,"start_seconds":"1-60","mode":"async"}}}