AAppoint Dr Watson Suite
Concierge for AAppoint restaurant bookings on minds.aappoint.me. Mints and manages a per-user access token, discovers and books partner restaurants by name or area across Thailand, Hong Kong and Japan, and checks live availability by dining zone and real seat capacity. It quotes no money before a booking exists, then takes a deposit through the payment rails that booking returns, or secures a card guarantee that holds an amount on the guest's card or saves the card, charged only for a no-show or a late cancel. Before any cancel it states what the guest stands to lose: a paid deposit is not refunded automatically, and a card guarantee cancelled after the free-cancellation time will be charged to the card. It also manages a walk-in waitlist. Times and payment deadlines are always the venue's own local time as the API sends it, labelled with the venue's zone, never raw UTC.
Tier C, WRITE, irreversible. Cancels a booking (POST /bookings/{eventid}/cancel); eventid PATH, Bearer access_token; body literal {} (a body-less POST gives 411). Call only at the end of the CANCEL ORDER rule (fetch, TEMPLATE CANCEL CHECKPOINT, then the yes): Consent never precedes the fetch, and a reply of 2 to a payment or card message is never the yes. Reschedule: RESCHEDULE HAS NO TOOL. Returns {booking:{id, status canceled, start_local, end_local, ...}, deposit_outcome}; print from this booking.start_local, else the pre-cancel read. deposit_outcome (AAppoint's contract, not yet seen live) picks the TEMPLATE CANCELLED variant: none or nothing_charged = unpaid, manual_refund = paid deposit, released = card released, forfeited = card forfeited; missing or unlisted = the pre-cancel read (unpaid or paid deposit; an entered card gets the two opening lines only, nothing about money). A job runs the release or the charge every five minutes and a charge can fail (capture-failed): never say either has happened, call it instant or poll for it. Money lines use the stored checkout amount; never quote a refund amount, no endpoint returns one. A free booking's cancel gives 200 with NO refund_note; a paid deposit's cancel gives 200 WITH refund_note (vendor-confirmed 2026-09-14) alongside manual_refund, absent from later fetches. Never print the refund_note: TEMPLATE CANCELLED carries the refund route. This call carries no idempotency_key: after a dropped connection, a timeout or a 5xx, read AAppoint_GetBooking before any second cancel; booking.status canceled means the cancel went through, so send TEMPLATE CANCELLED picked from the pre-cancel read. 409 invalid-state: read AAppoint_GetBooking; canceled gets the same TEMPLATE CANCELLED, anything else means the booking already ended (completed or no-show): say so, never retry. Another user's booking gives 404.
Tier C, WRITE. Leaves the queue (POST /waitlist/entries/{entry_id}/cancel); entry_id is the stored STRING (uuid) PATH parameter from AAppoint_JoinWaitlist, never shown; Bearer access_token; body literal {}. Explicit yes in a separate turn first. Idempotent. Success: tell the guest plainly they left the queue. 409 already-seated (a SEATED entry): never retry or re-POST; read AAppoint_GetWaitlistEntry and, on a live SEATED, say their table is ready. 404 waitlist-entry-not-found = not on THIS user's profile (another user's entry, or none): never confirm or deny it exists elsewhere.
Tier C. Live slot availability (GET /restaurants/{shop_id}/availability); shop_id PATH; service_id, party_size, start_date, end_date query; Bearer access_token. end_date is MANDATORY on every call and is always start_date + 13 days, also for one exact date: vendor-measured 2026-09-12, shop 194 returns 1 day object without it and 14 with it, shop 177 ZERO without and 11 with. An EMPTY end_date behaves exactly as if omitted, and this platform's wrapper emits every declared query parameter on every call, so `end_date=` looks schema-compliant yet reproduces the one-day defect: send a real date. An inverted range gives 400 invalid-date-range. Returns {available_slots:[{date, slots:[{start_sec, start_local, duration_sec, available_zones:[{zone_id, zone_name, available_seats, service_id}]}]}]}. start_local is the slot's venue-local moment (YYYY-MM-DDTHH:MM:SS+HH:MM, never Z), read by position, never by calculation: characters 1-10 the date, 12-16 the printed time, the last 6 the UTC offset (+05:30 prints UTC+5:30). start_sec is UTC epoch seconds: copy it verbatim into AAppoint_CreateBooking, never convert or print it; its one other use is the integer gap between consecutive slots, for row breaks. Run THREE CHECKS BEFORE SENDING ANY TIME, the offset per date (daylight saving can change it within one scan); any failure: print no times at all, never a time from start_sec. No timezone here: take the zone name from the venue row first (THE timezone FIELD NAMES THE ZONE AND NOTHING ELSE). Match a typed time on characters 12-16; keep the picked slot's start_sec and start_local for the booking check. party_size does NOT filter zones server-side: keep zones with available_seats at least party_size; a date with none is not offerable. LEAD TIME: the FIRST date is front-truncated (a floor of about a day), later dates whole; never read it as the opening time or a booked-out morning.
Tier C, WRITE. Books a real table (POST /bookings), only after the guest's explicit yes to the restate. Bearer access_token; body: idempotency_key, shop_id, service_id, party_size, start_sec (verbatim from the picked slot in this turn's availability), customer. Contact MUST nest under customer (flat gives 400); phone in E.164 with the guest's own country code. NEVER send zone_id/zone_name (409 slot-unavailable; the server auto-selects). Numbers and the customer object unquoted, strings quoted. Reuse an idempotency_key ONLY after a 5xx, a 429, a network timeout or a 401-forced refresh; any other 4xx created nothing: FRESH key. 409 slot-unavailable: re-check availability and re-offer, never re-POST. 500 customer-create-failed (malformed contact): normalize phone/email, retry reusing the key. Returns booking + deposit; booking.id = eventid = the guest-facing booking number. booking.start_local and end_local are venue-local (2026-07-13T10:00:00+07:00, never Z); never convert start_sec or end_sec. booking.start_sec MUST equal the picked slot's start_sec AND booking.start_local its start_local (AFTER THE BOOKING RESPONSE, VERIFY THE MEANING AND NOT JUST THE ROUND TRIP); with no start_local the start_sec match decides, and a mismatch means print no times at all. On any mismatch send only that rule's notice: no checkout and no TEMPLATE CONFIRMED until the guest keeps the booking. deposit.required false = confirmed now (TEMPLATE CONFIRMED, no checkout, no poll); required true with deposit.mode charge or absent = ordinary deposit; card_hold or card_save = card guarantee (CARD GUARANTEE IS NOT A PAYMENT). The mode alone decides, never country, city, currency or gateway. deposit.payment_options.gateways here is this booking's rail list, never restaurant.payment_gateways; one entry = call AAppoint_StartDepositCheckout at once (CONFIRM BEFORE EVERY WRITE). deposit.expires_local is the deadline before any checkout (TEMPLATE FIELDS); missing = no clock time, say the window is short. deposit.expires_at is UTC: never printed or converted. MONEY: amount is the only money field (no breakdown, VAT, fee or balance). Ordinary deposit: deposit.amount is the BASE for the whole party before any gateway fee, backend-computed for per_head and per_table alike (vendor-confirmed 2026-09-14): READ it, never derive it; it appears only in TEMPLATE CHOOSE A PAYMENT METHOD. Card guarantee: deposit.amount is the guarantee amount, never a sum due. deposit.currency = the ISO code (THB 40, HKD 200), never a symbol; missing = none. CARD FIELDS (AAppoint's contract, not yet seen live): deposit.mode card_hold = amount held, nothing charged; card_save = card saved, nothing held or charged; deposit.charged true only once money leaves the card; deposit.status awaiting-payment or pending = card not yet entered; free_cancel_until_local = the free-cancellation time, read by position, missing = omit that line; policy_text: THE VENUE'S policy_text IS SENT ONLY ON REQUEST, VERBATIM; free_cancel_until and hold_expires_at are UTC, never shown or converted.
Tier C. Reads one booking (GET /bookings/{eventid}); eventid PATH, Bearer access_token. A read, safe to repeat. 200 = this user's booking (the access token IS the identity); 404 = not theirs, never a system error. Returns {booking:{id, status, start_sec, start_local, end_local, ...}, deposit:{required, currency, amount, status, expires_local, mode, charged, ...}}. Print booking.start_local by position with the zone label, never from start_sec; missing = the stored start_local, else print no times at all. booking.status: created, confirmed, canceled, request-to-confirm, completed, no-showed. Only confirmed means booked; the deposit.status it needs follows the mode (the latest checkout's stored deposit_mode, else deposit.mode; charge or absent = ordinary deposit; a read showing card_hold, card_save, authorized or card-saved makes it a card guarantee from then on, card_hold or card_save staying the latest checkout's deposit_mode when it named one). Ordinary deposit.status: awaiting-payment, pending (page opened, money not arrived), paid, failed, canceled. Money was taken ONLY when deposit.required is true AND deposit.status is paid: a no-deposit booking also reads paid. After a cancel, a paid ordinary deposit still reads paid: the money was taken and is not refunded automatically (the refund route is TEMPLATE CANCELLED, manual_refund); an unpaid one reads canceled: nothing was taken. A card guarantee (card_hold or card_save; AAppoint's contract, not yet seen live) adds authorized, card-saved, released, capture-failed, refunded. Confirmed with paid on an ordinary deposit: TEMPLATE CONFIRMED. Confirmed with authorized or card-saved on a card guarantee, which includes any read showing card_hold, card_save, authorized or card-saved: stop polling, TEMPLATE CARD ENTERED, never wait for paid. Every other status follows ONLY THE API CONFIRMS A PAYMENT OR A CARD. Card money questions: WHERE THE MONEY STANDS ON A CARD GUARANTEE (charged missing = false). A booking cancelled late (recorded deposit_outcome forfeited) with charged not true and status authorized or card-saved still has the charge coming: answer with the forfeited money line of TEMPLATE CANCELLED (will be charged), never Held on card. free_cancel_until_local, policy_text, free_cancel_until and hold_expires_at read as AAppoint_CreateBooking describes; a missing free_cancel_until_local gives TEMPLATE CANCEL CHECKPOINT its not-known variant. deposit.expires_local (present while awaiting payment) is the deadline only while no checkout has succeeded; after one, the stored payment_expire_local. deposit.expires_at is UTC: never print or convert it (NEVER COMPUTE A TIME). deposit.amount is MUTATED IN PLACE after checkout (100 read back as 101): the gateway total, never an inconsistency. Money lines use the stored checkout amount, else this read's deposit.amount as written, never computed. Never judge payment from the /services figure.
Tier C. Restaurant detail (GET /restaurants/{shop_id}); shop_id PATH, Bearer access_token. Returns wrapped under restaurant: {restaurant:{id, accepting_new_bookings, waitlist_status, timezone, latitude, longitude, google_map_url, payment_policy, city, currency, payment_gateways}}. accepting_new_bookings is only here; require true for auto-book. waitlist_status (OPEN / CLOSED_NO_WAIT / CLOSED_OTHER) is not on the list: read it here first as the walk-in gate; AAppoint_GetWaitlistStatus adds the queue length. timezone names the zone only (Asia/Hong_Kong gives Hong Kong time), is the lookup for a list row without it, and never gives the offset. Never present google_map_url (sandbox links). Never show payment_policy or any figure or term in it: stale-prone venue prose (vendor-measured: a policy naming a THB 100 platform fee booked free). No deposit, mode, free-cancellation time or card terms here: before a booking never say a deposit is due, charged or held on a card, or that cancellation is free. Never quote currency or payment_gateways or predict from them: the booking's deposit.currency and deposit.payment_options.gateways decide.
Tier C. Polls queue position (GET /waitlist/entries/{entry_id}); entry_id is a STRING (uuid) PATH parameter, the stored waitlist_entry.entry_id from AAppoint_JoinWaitlist, never shown; Bearer access_token. Returns wrapped under waitlist_entry: {waitlist_entry:{state: CREATED|SEATED|CANCELED|ABANDONED, parties_ahead, ...}}. CREATED = waiting: tell the guest parties_ahead (0 = next; missing: in the queue, no position); stuck CREATED for 12h becomes ABANDONED. SEATED = table ready; never claim ready without a live SEATED this turn. CANCELED or ABANDONED = out of the queue. Read it when the guest asks or accepts an offer to check; the restaurant sends its own table-ready SMS. Never print or convert an entry timestamp. 404 waitlist-entry-not-found = not on THIS user's profile (another user's id always gives 404, never 403): say you cannot find that entry; never confirm or deny it exists elsewhere.
Tier C. Queue status and length (GET /restaurants/{shop_id}/waitlist?service_id={service_id}); shop_id PATH, service_id query, Bearer access_token. Call after AAppoint_GetRestaurant shows OPEN, before offering a join. ALWAYS send service_id, the dining service id from this turn's AAppoint_ListServices: the URL template always carries it, so an omitted one goes out empty or unfilled, an unmeasured request. No service id this turn: call neither this nor AAppoint_JoinWaitlist; treat the venue as CLOSED_OTHER. Returns {waitlist_status: OPEN|CLOSED_NO_WAIT|CLOSED_OTHER, min_party_size, max_party_size, parties_waiting}. OPEN: tell the guest parties_waiting so they can decide. CLOSED_NO_WAIT: walk-in only, no queue. CLOSED_OTHER: no queue; offer a normal booking or this venue's reserve link from AAppoint_ListShopeePayVenues, or with none AAppoint on (+66) 2-455-1200 or info@aappoint.me. A party outside min_party_size to max_party_size cannot join: say so, do not join. Failed call or missing field: keep AAppoint_GetRestaurant's status, give no count, bounds 1-10.
Tier C, WRITE. Joins a walk-in queue (POST /waitlist/entries); Bearer access_token; body: idempotency_key, shop_id, service_id, party_size, customer. It TEXTS THE GUEST (a join SMS, later the restaurant's table-ready SMS): restate venue and party size and get an explicit yes in a separate turn first. service_id = the dining service id from this turn's AAppoint_ListServices, as sent to AAppoint_GetWaitlistStatus. party_size 1-10, within that response's min_party_size to max_party_size. Contact nests under customer (first_name + phone minimum). One idempotency_key per join, reused only after a 5xx, a 429, a network timeout or a 401-forced refresh; any other 4xx created nothing: FRESH key. Returns 201 wrapped under waitlist_entry: {entry_id, state CREATED, shop_id, service_id, party_size, parties_ahead, created_at}. entry_id (uuid string) is the only handle for AAppoint_GetWaitlistEntry and AAppoint_CancelWaitlistEntry: store it, never show it. Tell the guest parties_ahead (missing: in the queue, no position) and that they can leave at any time; offer to check their place. Never print or convert created_at. Never retried as-is: 400 waitlist-closed, waitlist-no-wait (walk-in only), waitlist-full, waitlist-invalid-party-size: say so plainly, offer a normal booking or this venue's reserve link from AAppoint_ListShopeePayVenues, or with none AAppoint on (+66) 2-455-1200 or info@aappoint.me. 404 service-not-found: restaurant-type shops queue only their dining service, so that service_id was not it.
Tier C. Bookable services (GET /restaurants/{shop_id}/services); shop_id PATH, Bearer access_token. Call it live this turn before booking; never reuse a remembered service_id. Returns wrapped under services: {services:[{id, name_en, name_th, pricing_model, deposit, duration_sec, products:[{id, pricing_model, deposit}]}, ...]}. services[].id = service_id. Show services by name (name_en or name_th) only. deposit is a per-head or per-table RATE (pricing_model per_head or per_table says which, nothing more), a STRING with NO currency field: NEVER show it, quote it as the deposit or multiply it out; never call a service free. Use the service-level deposit, never products[].deposit (a placeholder that can mismatch). '0' does NOT mean free: a per_table venue can show 0 and still return deposit.required true with a real amount. Only the booking response decides the deposit (deposit.required, deposit.amount, deposit.mode); the payable comes from checkout.
Tier C. Lists bookable service-type slugs for the geo/category search filter (GET /service-types). access_token maps to Authorization: Bearer header. Returns {service_types:[{id, name_en, name_th}, ...]}. Use `id` (e.g. 'restaurant') as the service_type filter on AAppoint_SearchRestaurants.
Tier B (no auth, DIFFERENT HOST). Static public ShopeePay Coin Cashback feed (GET https://shopeepay.marketplace.aappoint.me/shops.json). Its Accept-only headers field suppresses partner-secret injection, which has no host scoping. Returns {meta, sections, shops:[{id, name, emoji, address, link, imageUrl, section, bookable, comingSoon?, group?}]}. Fetch ONCE per turn; reuse it for every venue that turn. THIS FEED IS NOT THE CATALOGUE: a hand-maintained cashback list; meta.lastUpdated is a hand-edit date, not a sync date. Absence NEVER means unbookable, out of network or off the marketplace: check the Partner API first, and never call a venue matching a live bookable row absent. Never state its venue count from memory or this description; count only this turn's shops rows, never as the network's size. shops[].id is a SEPARATE id space from shop_id: never match on it or send it as shop_id; match by name (name_en or name_th) and address; no confident match = the API row with no badge. Skip comingSoon and not-bookable entries. shops[].link, verbatim, is the reserve link when the Partner API cannot book the venue, never a link found elsewhere. No cashback rate, nothing about payment gateways: the badge is a name, never a number. Fetch failed: say the feed is unreachable, add no badges, infer no absence.
Tier B (no auth, corrected). Exchanges the stored refresh token for a fresh access token via POST /token. Headers carry Content-Type but NOT Authorization; the non-empty headers field suppresses the partner-secret injection, so the call carries no Authorization header and authenticates on the body refresh token alone. Call on 401 unauthorized or when the access token is older than ~1h. On 401 invalid_grant the refresh token is dead - re-register via AAppoint_RegisterUser.
Tier A. Mints this user's token pair against /register. external_user_id = the Steward's humanId (steward.partyId from the REGISTRY cycle context), stable per person across their Minds. WRITE-ONCE: store it on the FIRST registration, reuse it verbatim forever; a changed one mints a new agent_user_id and silently orphans this user's bookings (404 on read and cancel). NEVER ask the user for it or any credential. Call at SESSION START; decide from the status code, never from how a value looks. 201: continue silently. 401 or 403, only these: the operator must finish setup; say so in one line and offer the venue's reserve link from AAppoint_ListShopeePayVenues when it has one, else AAppoint on (+66) 2-455-1200 or info@aappoint.me. 429, 5xx or a timeout: transient, never setup; RETRY BEFORE YOU REPORT, then say the booking system cannot be reached right now. Idempotent on external_user_id: the SAME agent_user_id with new tokens. PARTNER_SECRET is injected as Authorization: Bearer (providerKey=aappoint, header_key=Authorization, value_prefix 'Bearer ' with its trailing space); no tool-level headers field, since a non-empty one suppresses the injection. Returns {agent_user_id, token_type, access_token (agta_...), expires_in, refresh_token (agtr_...)}. Tokens are SECRETS: TENET aappoint_session only, never echoed, written to LTM or shown.
Tier C. Two-mode restaurant search (GET /restaurants); Bearer access_token. ALWAYS send service_type=restaurant: the endpoint serves every shop type, so a dinner search can return a garage. Send only q, service_type, city, latitude, longitude, radius_km, limit, offset: an UNKNOWN parameter is silently ignored and returns the UNFILTERED list while looking filtered. q is a plain unnormalised substring: run THE NAME LADDER, dropping generic words (restaurant, cafe, the, bar, kitchen, room, house) and the city name for the token. Geo mode (service_type+latitude+longitude+radius_km) is NOT sorted nearest-first (measured 2026-09-01): follow GEO RESULTS ARE NOT SORTED NEAREST-FIRST (distance_meters 0 = MISSING, never q with radius_km, no small limit). city is an exact match taking BOTH numeric codes (1 Bangkok, 6 Khon Kaen, 14 Chiang Mai, 24 Nonthaburi, 42 Phuket) AND place names (Hong Kong): try the place name before any coordinate. Returns wrapped under restaurants: {total, limit, offset, restaurants:[{id, name_en, name_th, service_type, city, timezone, latitude, longitude, address, distance_meters?}]}. restaurants[].id = shop_id; latitude/longitude are STRINGS. total 0 proves only that this query form found nothing. Never present google_map_url (2 of 18 geo rows point at a Google sandbox host). timezone is on every row (vendor-confirmed 2026-09-12 on all 37 venues, list and detail), never on availability, and names the zone only (THE timezone FIELD NAMES THE ZONE AND NOTHING ELSE); keep one zone per venue for the whole flow. A row without timezone goes to AAppoint_GetRestaurant, never guessed from address, country or city. No row field, city and country included, predicts a deposit or a card guarantee: only the booking response does.
Tier C, WRITE that moves no money itself: opens the payment page or QR, or on a card guarantee the card page. POST /bookings/{eventid}/deposit/checkout; eventid PATH, Bearer access_token, payment_method and result_url in body. Consent: CONFIRM BEFORE EVERY WRITE (one rail: the yes to the booking covers it). result_url is where the guest LANDS BACK IN MINDS, NOT a payment-result page: payment is read only from AAppoint_GetBooking. Webapp AND the runtime gives this Mind's own mindId: https://app.hellominds.ai/?mindId={mindId}; anything else, Telegram or a mindId not known for certain included: https://app.hellominds.ai/ with no query. NEVER invent or guess a mindId; ?mindId= is a QUERY, never a path. Send result_url on every rail (missing: 400 result-url-required), never conversationId or any other parameter. NEVER retried silently, on any status or a timeout; after a timeout read AAppoint_GetBooking before any second checkout. Each success voids the previous link; switching rail is a new POST on this eventid on the guest's pick. 502 checkout-failed: that rail is unavailable, not a booking failure; offer the rails on offer (RETRY BEFORE YOU REPORT). 200 {status: already-paid} or {status: already-secured} (card entered): send no link, store nothing, read AAppoint_GetBooking; send TEMPLATE CONFIRMED or TEMPLATE CARD ENTERED only once it confirms under ONLY THE API CONFIRMS A PAYMENT OR A CARD, never that rule's not-arrived templates meanwhile. 400 payment-method-not-available or unsupported-payment-method: offer the rails on offer (TEMPLATE FIELDS); POST again only on the guest's pick. 409 deposit-not-payable: no longer payable, or on a card guarantee a card can no longer be entered; offer to book again. Returns {payment_method, checkout_url, payment_uri, amount, payment_expire_at, payment_expire_local, booking_id, deposit_mode}; a card guarantee adds policy_text and can omit payment_uri and payment_expire_at. Store each success per STORE THE PAYABLE FIGURE WITH ITS CURRENCY; the latest wins. deposit_mode (charge = ordinary deposit; card_hold or card_save = card guarantee) overrides deposit.mode, even across the charge/card line, unless a read makes it a card guarantee (CARD GUARANTEE IS NOT A PAYMENT); missing = deposit.mode, else ordinary. ORDINARY DEPOSIT: amount is THE SUM DUE, no breakdown, RAIL-DEPENDENT. Send TEMPLATE PAY NOW HAND-OFF: the table is held until payment, never the money. CARD GUARANTEE: amount is held or guaranteed, never taken; missing = the booking's deposit.amount as read. Send TEMPLATE CARD HAND-OFF, never pay or paid (CARD GUARANTEE IS NOT A PAYMENT). Free cancellation: the booking's deposit.free_cancel_until_local; missing = omit that line. policy_text never goes in the hand-off (THE VENUE'S policy_text IS SENT ONLY ON REQUEST, VERBATIM). No currency field: print deposit.currency beside amount; missing = none. Send checkout_url verbatim, never truncated. Deadline: latest SUCCESSFUL checkout's payment_expire_local (TEMPLATE FIELDS); missing = no clock time, say the window is short, send the link. payment_expire_at is UTC: never print or convert it (NEVER COMPUTE A TIME). The 30-minute window, warning and final check run until payment or card entry (THE PAYMENT WINDOW IS 30 MINUTES). A passed deadline is no expiry: only a read of booking.status canceled with the deposit unpaid or the card not entered sends TEMPLATE DEPOSIT EXPIRED, with nothing added.
Tier C. DIAGNOSTIC ONLY, never called in a user turn: it answers nothing the user asked and costs a round trip, so it belongs to setup, support and troubleshooting, never to the booking or discovery flow. Confirms the stored access token is valid (GET /me). access_token maps to the Authorization: Bearer header via headersParameters. Returns {agent_user_id, status, external_user_id, created_at}. Never echo any of these to the user: external_user_id and agent_user_id are internal identifiers.
Overview
Concierge for AAppoint restaurant bookings on minds.aappoint.me. Mints and manages a per-user access token, discovers and books partner restaurants by name or area across Thailand, Hong Kong and Japan, and checks live availability by dining zone and real seat capacity. It quotes no money before a booking exists, then takes a deposit through the payment rails that booking returns, or secures a card guarantee that holds an amount on the guest's card or saves the card, charged only for a no-show or a late cancel. Before any cancel it states what the guest stands to lose: a paid deposit is not refunded automatically, and a card guarantee cancelled after the free-cancellation time will be charged to the card. It also manages a walk-in waitlist. Times and payment deadlines are always the venue's own local time as the API sends it, labelled with the venue's zone, never raw UTC. It gives your AI agent 17 built-in tools, including aappoint cancel booking, aappoint cancel waitlist entry and aappoint check availability. Apps are free to equip, and once equipped your AI Mind can use AAppoint Dr Watson Suite automatically while it works. AAppoint Dr Watson Suite is currently equipped on 19 Minds.
Frequently asked questions
What is AAppoint Dr Watson Suite?
Concierge for AAppoint restaurant bookings on minds.aappoint.me. Mints and manages a per-user access token, discovers and books partner restaurants by name or area across Thailand, Hong Kong and Japan, and checks live availability by dining zone and real seat capacity. It quotes no money before a booking exists, then takes a deposit through the payment rails that booking returns, or secures a card guarantee that holds an amount on the guest's card or saves the card, charged only for a no-show or a late cancel. Before any cancel it states what the guest stands to lose: a paid deposit is not refunded automatically, and a card guarantee cancelled after the free-cancellation time will be charged to the card. It also manages a walk-in waitlist. Times and payment deadlines are always the venue's own local time as the API sends it, labelled with the venue's zone, never raw UTC. It bundles 17 tools your AI agent can call on your behalf.
What can AAppoint Dr Watson Suite do for my AI agent?
Once equipped, your AI Mind can use AAppoint Dr Watson Suite to aappoint cancel booking, aappoint cancel waitlist entry, aappoint check availability, aappoint create booking and aappoint get booking, and more — without you having to do any of it manually.
How do I connect AAppoint Dr Watson Suite to my AI Mind?
Open AAppoint Dr Watson Suite in the Ethoswarm Bazaar and select Equip to add it to one of your AI Minds. Your Mind can then use it automatically. Some apps ask you to authorize access the first time they run.
Is AAppoint Dr Watson Suite free?
Yes — AAppoint Dr Watson Suite is free to equip on your AI Mind in the Ethoswarm Bazaar.