{"openapi":"3.1.0","info":{"title":"Yenta Directory Read API","version":"1.0.0","description":"The Yenta directory's machine-consumable JSON reads: discover published venues, their cities, and destinations, then read a tenant's own host (its /v1/public reads). Anonymous, read-only, no authentication. Every result carries a `source` freshness reference. Powered by Yenta."},"servers":[{"url":"https://dev.yentaknows.ai","description":"The Yenta directory host."}],"externalDocs":{"description":"llms.txt — the agent entrypoint naming every Yenta surface.","url":"https://dev.yentaknows.ai/llms.txt"},"x-mcp":{"url":"https://dev.yentaknows.ai/mcp","transport":"streamable-http"},"paths":{"/v1/public/venues":{"get":{"operationId":"search_venues","summary":"Search published venues","description":"Published venues. query, city, cuisine, price_band, neighbourhood, accepts_reservations, near/radius_km, open_on/at, open_now and facets are HARD filters (a miss excludes); prefer_cuisine, prefer_neighbourhood, avoid and prefer_facets are SOFT and only rank.","parameters":[{"name":"query","in":"query","required":false,"description":"Optional free-text filter over the venue's name, alternate names, description, cuisine, neighbourhood and city.","schema":{"type":"string","maxLength":256}},{"name":"city","in":"query","required":false,"description":"Restrict to venues in this city; matched case-insensitively, and a region suffix after a comma is ignored ('Portland, OR' = 'Portland').","schema":{"type":"string","maxLength":128}},{"name":"cuisine","in":"query","required":false,"description":"Restrict to venues of this cuisine; matched case-insensitively.","schema":{"type":"string","maxLength":128}},{"name":"price_band","in":"query","required":false,"description":"Restrict to venues in this price band (e.g. '$$'); matched case-insensitively.","schema":{"type":"string","maxLength":8}},{"name":"neighbourhood","in":"query","required":false,"description":"Restrict to venues in this neighbourhood; matched case-insensitively.","schema":{"type":"string","maxLength":128}},{"name":"accepts_reservations","in":"query","required":false,"description":"true keeps only venues that accept reservations; false is the same as omitting it.","schema":{"type":"boolean"}},{"name":"near","in":"query","required":false,"description":"Only venues within radius_km of this 'latitude,longitude', nearest first.","schema":{"type":"string"}},{"name":"radius_km","in":"query","required":false,"description":"Search radius in km around 'near'; the default is applied when omitted.","schema":{"type":"number","minimum":0,"maximum":50.0}},{"name":"open_on","in":"query","required":false,"description":"Restrict to venues open on this weekday, or today/tomorrow in each venue's own timezone (optionally at 'at'); for tonight use open_on=today with at.","schema":{"type":"string","enum":["monday","tuesday","wednesday","thursday","friday","saturday","sunday","today","tomorrow"]}},{"name":"at","in":"query","required":false,"description":"A 24-hour HH:MM time; requires open_on, and keeps venues open then on that day.","schema":{"type":"string","format":"time"}},{"name":"open_now","in":"query","required":false,"description":"true keeps only venues open at their own local time now; false is the same as omitting it.","schema":{"type":"boolean"}},{"name":"prefer_cuisine","in":"query","required":false,"description":"Soft preference: venues of these cuisines rank higher; non-matches are NOT dropped.","schema":{"type":"array","items":{"type":"string"},"maxItems":8}},{"name":"avoid","in":"query","required":false,"description":"Soft preference: venues matching these cuisine/neighbourhood tokens rank LOWER; not dropped.","schema":{"type":"array","items":{"type":"string"},"maxItems":8}},{"name":"prefer_neighbourhood","in":"query","required":false,"description":"Soft preference: venues in these neighbourhoods rank higher; non-matches are NOT dropped.","schema":{"type":"array","items":{"type":"string"},"maxItems":8}},{"name":"facets","in":"query","required":false,"description":"HARD experiential-facet filter: '<facet_type>:<value>' tokens (e.g. 'dietary:vegetarian', 'vibe:romantic') from the /schema/facets vocabulary. A venue must match every facet_type given (values OR within a type, types AND across); a miss EXCLUDES it. An unknown facet_type is a 422.","schema":{"type":"array","items":{"type":"string"},"maxItems":8}},{"name":"prefer_facets","in":"query","required":false,"description":"SOFT experiential-facet preference: same '<facet_type>:<value>' tokens as facets; a venue that declares them ranks higher but is NEVER dropped.","schema":{"type":"array","items":{"type":"string"},"maxItems":8}},{"name":"limit","in":"query","required":false,"description":"Maximum items to return.","schema":{"type":"integer","minimum":1,"maximum":50,"default":50}},{"name":"cursor","in":"query","required":false,"description":"Offset of the first item to return.","schema":{"type":"integer","minimum":0,"maximum":10000,"default":0}}],"responses":{"200":{"description":"A page of matching venues.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["ok","not_available"]},"reason":{"type":"string"},"items":{"type":"array","items":{"$ref":"#/components/schemas/Venue"}},"pagination":{"$ref":"#/components/schemas/Pagination"},"source":{"$ref":"#/components/schemas/Source"}},"required":["status","source"]}}}},"404":{"description":"Not the directory host, or no such resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A parameter fell outside its bounds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/public/menu-search":{"get":{"operationId":"search_menus","summary":"Search menus across all published venues","description":"The flagship cross-venue read: published menu items across every venue, each tagged with the venue it belongs to, filtered by text, city, required dietary tags and allergens to avoid. Find venues by what is on their menu from one directory call.","parameters":[{"name":"query","in":"query","required":false,"description":"Text to match against item names and descriptions, and section and menu names; every word must match; connector words (and, with, in) aren't required.","schema":{"type":"string","maxLength":256}},{"name":"city","in":"query","required":false,"description":"Restrict to venues in this city; matched case-insensitively, and a region suffix after a comma is ignored ('Portland, OR' = 'Portland').","schema":{"type":"string","maxLength":128}},{"name":"dietary_tags","in":"query","required":false,"description":"Require ALL of these tags; case- and separator-insensitive (gluten free = gluten-free).","schema":{"type":"array","items":{"type":"string"},"maxItems":8}},{"name":"allergens","in":"query","required":false,"description":"Exclude items declaring any of these allergens.","schema":{"type":"array","items":{"type":"string"},"maxItems":8}},{"name":"max_price","in":"query","required":false,"description":"Only items priced at or under this, in the menu's currency.","schema":{"type":"number","minimum":0,"maximum":1000000.0}},{"name":"limit","in":"query","required":false,"description":"Maximum items to return.","schema":{"type":"integer","minimum":1,"maximum":50,"default":50}},{"name":"cursor","in":"query","required":false,"description":"Offset of the first item to return.","schema":{"type":"integer","minimum":0,"maximum":10000,"default":0}}],"responses":{"200":{"description":"A page of matching menu items, each tagged with its venue.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["ok","not_available"]},"reason":{"type":"string"},"items":{"type":"array","items":{"$ref":"#/components/schemas/MenuMatch"}},"pagination":{"$ref":"#/components/schemas/Pagination"},"source":{"$ref":"#/components/schemas/Source"}},"required":["status","source"]}}}},"404":{"description":"Not the directory host, or no such resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A parameter fell outside its bounds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/public/venues/{venue_slug}":{"get":{"operationId":"get_venue","summary":"Get one published venue","description":"One published venue's summary, or `not_available`.","parameters":[{"name":"venue_slug","in":"path","required":true,"description":"The venue's public slug.","schema":{"type":"string","minLength":1,"maxLength":63}}],"responses":{"200":{"description":"The venue summary, or not_available.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["ok","not_available"]},"reason":{"type":"string"},"item":{"$ref":"#/components/schemas/Venue"},"source":{"$ref":"#/components/schemas/Source"}},"required":["status","source"]}}}},"404":{"description":"Not the directory host, or no such resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A parameter fell outside its bounds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/public/venues:batch":{"get":{"operationId":"get_venues","summary":"Get several published venues (batch)","description":"One venue view per slug in ONE call — the batch counterpart of get_venue, so a shortlist needs no per-slug round-trip. The base view is always returned; include opts into the heavier per-venue reads (hours, dietary, attributes, menu_summary).","parameters":[{"name":"slugs","in":"query","required":true,"description":"The venues' slugs, as returned by /venues; duplicates resolve once. Comma-separated (slugs=a,b) and repeated (slugs=a&slugs=b) both work, and mix; maxItems bounds the total slug count either way.","schema":{"type":"array","items":{"type":"string"},"maxItems":20}},{"name":"include","in":"query","required":false,"description":"Optional add-ons opting into heavier per-venue reads; omit for the lean base view. An unknown value is a 422.","schema":{"type":"array","items":{"type":"string","enum":["attributes","dietary","hours","menu_summary"]},"maxItems":4}}],"responses":{"200":{"description":"items in the requested order, plus any slug that did not resolve.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["ok","not_available"]},"reason":{"type":"string"},"item":{"type":"object","description":"items in the requested order, one per resolved slug, plus any requested slug that did not resolve.","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Venue"}},"not_found":{"type":"array","items":{"type":"string"},"description":"Requested slugs, echoed exactly, that did not resolve."}},"required":["items","not_found"]},"source":{"$ref":"#/components/schemas/Source"}},"required":["status","source"]}}}},"404":{"description":"Not the directory host, or no such resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A parameter fell outside its bounds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/public/cities":{"get":{"operationId":"list_cities","summary":"List cities with published venues","description":"Every city that has at least one published venue.","parameters":[{"name":"limit","in":"query","required":false,"description":"Maximum items to return.","schema":{"type":"integer","minimum":1,"maximum":50,"default":50}},{"name":"cursor","in":"query","required":false,"description":"Offset of the first item to return.","schema":{"type":"integer","minimum":0,"maximum":10000,"default":0}}],"responses":{"200":{"description":"A page of cities.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["ok","not_available"]},"reason":{"type":"string"},"items":{"type":"array","items":{"$ref":"#/components/schemas/City"}},"pagination":{"$ref":"#/components/schemas/Pagination"},"source":{"$ref":"#/components/schemas/Source"}},"required":["status","source"]}}}},"404":{"description":"Not the directory host, or no such resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A parameter fell outside its bounds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/public/schema/facets":{"get":{"operationId":"facet_vocabulary","summary":"Get the facet vocabulary","description":"The closed facet vocabulary plus today's live cuisine, price band and neighbourhood values across published venues.","responses":{"200":{"description":"The facet vocabulary.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["ok","not_available"]},"reason":{"type":"string"},"item":{"$ref":"#/components/schemas/FacetVocabulary"},"source":{"$ref":"#/components/schemas/Source"}},"required":["status","source"]}}}},"404":{"description":"Not the directory host, or no such resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/public/destinations":{"get":{"operationId":"search_destinations","summary":"Search published destinations","description":"Published destinations by optional name query.","parameters":[{"name":"query","in":"query","required":false,"description":"Optional free-text filter over name (and, for venues, description).","schema":{"type":"string","maxLength":256}},{"name":"limit","in":"query","required":false,"description":"Maximum items to return.","schema":{"type":"integer","minimum":1,"maximum":50,"default":50}},{"name":"cursor","in":"query","required":false,"description":"Offset of the first item to return.","schema":{"type":"integer","minimum":0,"maximum":10000,"default":0}}],"responses":{"200":{"description":"A page of matching destinations.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["ok","not_available"]},"reason":{"type":"string"},"items":{"type":"array","items":{"$ref":"#/components/schemas/Destination"}},"pagination":{"$ref":"#/components/schemas/Pagination"},"source":{"$ref":"#/components/schemas/Source"}},"required":["status","source"]}}}},"404":{"description":"Not the directory host, or no such resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A parameter fell outside its bounds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/public/search":{"get":{"operationId":"search","summary":"Search venues and destinations together","description":"Published venues and destinations in ONE call, each result tagged with its `kind`. Use /v1/public/venues or /v1/public/destinations for type-specific filters.","parameters":[{"name":"query","in":"query","required":false,"description":"Optional free-text filter over venue name and description, and destination name.","schema":{"type":"string","maxLength":256}},{"name":"city","in":"query","required":false,"description":"Restrict venues to this city, matched case-insensitively; destinations carry no city, so it does not constrain them.","schema":{"type":"string","maxLength":128}},{"name":"kind","in":"query","required":false,"description":"Scope to 'venue' or 'destination'; omit to return both.","schema":{"type":"string","enum":["venue","destination"]}},{"name":"limit","in":"query","required":false,"description":"Maximum items to return.","schema":{"type":"integer","minimum":1,"maximum":50,"default":50}},{"name":"cursor","in":"query","required":false,"description":"Offset of the first item to return.","schema":{"type":"integer","minimum":0,"maximum":10000,"default":0}}],"responses":{"200":{"description":"A page of venues and destinations, each tagged with its kind.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["ok","not_available"]},"reason":{"type":"string"},"items":{"type":"array","items":{"$ref":"#/components/schemas/SearchResult"}},"pagination":{"$ref":"#/components/schemas/Pagination"},"source":{"$ref":"#/components/schemas/Source"}},"required":["status","source"]}}}},"404":{"description":"Not the directory host, or no such resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A parameter fell outside its bounds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/public/destinations/{destination_slug}":{"get":{"operationId":"get_destination","summary":"Get one published destination","description":"One published destination's summary, or `not_available`.","parameters":[{"name":"destination_slug","in":"path","required":true,"description":"The destination's public slug.","schema":{"type":"string","minLength":1,"maxLength":63}}],"responses":{"200":{"description":"The destination summary, or not_available.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["ok","not_available"]},"reason":{"type":"string"},"item":{"$ref":"#/components/schemas/Destination"},"source":{"$ref":"#/components/schemas/Source"}},"required":["status","source"]}}}},"404":{"description":"Not the directory host, or no such resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A parameter fell outside its bounds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"Source":{"type":"object","description":"Which approved revision an answer was read from.","properties":{"content_version":{"type":"integer"},"source":{"type":"string","description":"'directory' for cross-venue reads, or 'approved-content-revision:<id>' for a single venue/destination."},"approved_at":{"type":"string","format":"date-time","description":"When the cited revision was approved (ISO-8601), so an answer can be quoted 'as of' that time. Present on a single venue/destination answer and on each search_venues candidate's own per-item source; absent on a cross-venue directory footer."},"powered_by":{"type":"string","description":"Brand signature on the entry reads only."}},"required":["content_version","source"]},"Pagination":{"type":"object","description":"The page actually served; next_cursor is null past the last page.","properties":{"limit":{"type":"integer"},"cursor":{"type":"integer"},"next_cursor":{"type":["integer","null"]},"total":{"type":"integer"}},"required":["limit","cursor","total"]},"Venue":{"type":"object","description":"A published venue as the directory presents it.","properties":{"slug":{"type":"string"},"name":{"type":"string"},"city":{"type":"string"},"country":{"type":"string"},"currency":{"type":"string"},"description":{"type":"string"},"latitude":{"type":"string","description":"Decimal degrees as an exact string (not a float), when stated."},"longitude":{"type":"string","description":"Decimal degrees as an exact string (not a float), when stated."},"phone":{"type":"string","description":"The venue's public phone number, when stated."},"cuisine":{"type":"string","description":"The venue's cuisine, when stated."},"price_band":{"type":"string","description":"The venue's price band (e.g. '$$'), when stated."},"neighbourhood":{"type":"string","description":"The venue's neighbourhood, when stated."},"address":{"type":"object","description":"The venue's postal address; present only when it states a street address. Parts it does not state are omitted.","properties":{"street_address":{"type":"string"},"city":{"type":"string"},"region":{"type":"string","description":"State, province or emirate."},"postal_code":{"type":"string"},"country":{"type":"string","description":"ISO 3166-1 alpha-2."}},"required":["street_address"]},"address_text":{"type":"string","description":"The address as one line, ready to quote; present with address."},"map_url":{"type":"string","description":"A Google Maps link to the venue (by its Place ID, else its coordinates); present only when either is stated."},"hours":{"type":"array","description":"The venue's weekly opening hours, when stated and the venue grants get_venue_profile. One entry per open interval; a venue may have several rows for one day. day_of_week is 0=Monday..6=Sunday, and closes_at earlier than opens_at is an interval wrapping past midnight into the next day.","items":{"type":"object","properties":{"day_of_week":{"type":"integer","minimum":0,"maximum":6,"description":"0=Monday .. 6=Sunday."},"day":{"type":"string","description":"The weekday name for day_of_week (e.g. 'monday')."},"opens_at":{"type":"string","description":"Local opening time, HH:MM."},"closes_at":{"type":"string","description":"Local closing time, HH:MM; earlier than opens_at wraps past midnight."}},"required":["day_of_week","opens_at","closes_at"]}},"hours_summary":{"type":"string","description":"The week in one line, ready to quote: consecutive days with the same windows grouped, closed days last (e.g. 'Tue–Fri 17:00–22:00; Sat–Sun 11:00–23:00; closed Mon'). Present whenever hours is."},"timezone":{"type":"string","description":"The venue's IANA timezone (e.g. 'America/Chicago'), when stated."},"open_now":{"type":"boolean","description":"Whether the venue is open now at its own local time; present only when it states hours and a timezone."},"today":{"type":"object","description":"Today's opening windows at the venue's local date; present only when it states hours and a timezone.","properties":{"day":{"type":"string","description":"Today's weekday name."},"windows":{"type":"array","items":{"type":"object","properties":{"opens_at":{"type":"string","description":"HH:MM."},"closes_at":{"type":"string","description":"HH:MM."}},"required":["opens_at","closes_at"]}}},"required":["day","windows"]},"yenta_page_url":{"type":"string","description":"The venue's page on Yenta, to open or cite; present only when it is live. Not the venue's own site: that is website."},"website":{"type":"string","description":"The venue's own website; present only when it publishes one and grants get_venue_links."},"distance_km":{"type":"number","description":"Kilometres from the 'near' point; present only on a proximity search."},"accepts_reservations":{"type":"boolean","description":"true = an online or live booking is published (the same test the accepts_reservations search filter applies); false = none is published, but the venue may still take bookings by phone. Present with booking."},"how_to_book":{"type":"string","description":"One sentence from published fields: 'Book online at <url>' or 'Call <phone>'. Omitted when the venue is not bookable."},"capabilities":{"type":"array","items":{"type":"string"},"description":"Capability ids this venue granted (the tool names at its mcp_endpoint); the MCP directory lists the by-name venue_* tools instead."},"mcp_endpoint":{"type":"string","description":"The venue's own read-only MCP URL, present only when the venue is live."},"match":{"allOf":[{"$ref":"#/components/schemas/Match"}],"description":"This candidate's retrieval explanation (score + grounded reasons/conflicts). Present only on a ranked search_venues result — when the caller passed a query or a soft preference."},"source":{"allOf":[{"$ref":"#/components/schemas/Source"}],"description":"This candidate's OWN freshness reference (its approved revision and approved_at), so a shortlisted venue can be cited without a second get_venue. The list's response-level source stays the directory reference."},"attributes":{"type":"object","description":"The venue's authored experiential facets, grouped by type (vibe, good_for, not_good_for, feature, noise_level, view, dress_code, meal_period, cuisine, dietary, accessibility). Present on the single-venue reads (get_venue / get_venue_profile), and on the batch /venues:batch read when 'attributes' is in include, and only when the venue has facets and grants get_venue_profile; otherwise the key is omitted. Each property is a facet type whose value is an array of entries, each carrying the canonical facet value and its provenance class.","additionalProperties":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string","description":"The canonical (hyphenated) facet value."},"source":{"type":"string","description":"The facet's provenance class, one of: venue_verified, yenta_verified, partner_feed, public_source, inferred."},"confidence":{"type":"number","minimum":0,"maximum":1,"description":"A 0-1 confidence score, present only when the source stated one (omitted for verified facts)."}},"required":["value","source"]}}},"menu_summary":{"type":"object","description":"A compact, evidence-only summary of the venue's WHOLE approved menu, so an agent can assess it without pulling every item (get_menu) or paging search_menu. Present on the single-venue reads (get_venue, and get_venue_profile on the venue's own host), and on the batch /venues:batch read when 'menu_summary' is in include, and only when the venue has an approved menu and grants search_menu; otherwise the key is omitted. Counts and ranges only — never a derived quality label or a fabricated 'signature item'.","properties":{"item_count":{"type":"integer","description":"Total items across the whole approved menu."},"section_count":{"type":"integer","description":"Total sections; present only when sections is truncated."},"dietary_tag_count":{"type":"integer","description":"Total distinct dietary tags; present only when dietary is truncated."},"sections":{"type":"array","items":{"type":"string"},"description":"Section names, first-seen deduped, in the partner's own menu order and bounded to a configured maximum."},"price_range":{"type":"object","description":"min/max over items priced in the venue's OWN currency; omitted entirely when nothing is priced in it.","properties":{"min":{"type":"string","description":"Exact decimal string; never a float (it is a money value)."},"max":{"type":"string","description":"Exact decimal string; never a float (it is a money value)."},"currency":{"type":"string"}},"required":["min","max","currency"]},"dietary":{"type":"object","description":"Per-dietary-tag item counts, spelled exactly as the venue declared them (never normalised or invented); omitted when the menu declares none.","additionalProperties":{"type":"integer"}}},"required":["item_count","sections"]},"dietary":{"type":"object","description":"The venue's dietary-tag/allergen VOCABULARY (the dietary_tags and allergens /venue/dietary-options answers, without its examples/allergen_counts) — distinct from menu_summary.dietary's per-tag item COUNTS. Present only on the batch /venues:batch read when 'dietary' is in include, and only when the venue has an approved menu and grants get_dietary_options; otherwise the key is omitted.","properties":{"dietary_tags":{"type":"array","items":{"type":"string"}},"allergens":{"type":"array","items":{"type":"string"}}},"required":["dietary_tags","allergens"]}},"required":["slug","name","city","country","currency"]},"Match":{"type":"object","description":"A search_venues candidate's retrieval explanation, present only when ranking is active (a query or a soft prefer_cuisine/avoid/prefer_neighbourhood/prefer_facets term). No id, org or row id ever appears.","properties":{"score":{"type":"number","description":"Retrieval score: higher = a better match, RELATIVE to this result set — not a 0-100 quality verdict. Compare candidates within one response only; the absolute value has no standalone meaning."},"reasons":{"type":"array","items":{"$ref":"#/components/schemas/MatchReason"},"description":"Field-grounded POSITIVES as {attribute, value, source?, confidence?} objects (a text/cuisine/price_band/neighbourhood/facet/proximity/hours match), echoing only the row's own canonical values and closed status tokens, deduped by (attribute, value) and count-bounded by max_public_reason_terms."},"conflicts":{"type":"array","items":{"$ref":"#/components/schemas/MatchReason"},"description":"Field-grounded NEGATIVES (why_not) as the same objects, most decision-useful first: a matched avoid, every intrinsic not_good_for facet, an unmet soft preference (named by TYPE, value 'preference-unmet'), and the cheaply-known hours/not-published and booking/unavailable gaps; same bound as reasons."}},"required":["score","reasons","conflicts"]},"MatchReason":{"type":"object","description":"One grounded reason/conflict. 'attribute' is a closed-vocabulary dimension name (an essentials field, a FacetType, or one of text/proximity/hours/booking/not_good_for); 'value' is EITHER the row's own canonical value OR a fixed status token (within-radius, open-now, open-at-requested-time, name, description, preference-unmet, not-published, unavailable) — never a term the caller typed. 'source'/'confidence' appear ONLY on facet-derived entries, carrying the VenueFacet's SourceType provenance and stated confidence.","properties":{"attribute":{"type":"string"},"value":{"type":"string"},"source":{"type":"string","description":"The facet's SourceType provenance (e.g. 'venue_verified', 'inferred'); present only on facet-derived entries."},"confidence":{"type":"number","description":"The facet's stated confidence; present only when the row states one."}},"required":["attribute","value"]},"City":{"type":"object","description":"A city with at least one published venue.","properties":{"city":{"type":"string"}},"required":["city"]},"Destination":{"type":"object","description":"A published destination as the directory presents it.","properties":{"slug":{"type":"string"},"name":{"type":"string"},"country":{"type":"string"},"currency":{"type":"string"},"timezone":{"type":"string"},"default_language":{"type":"string"},"mcp_endpoint":{"type":"string","description":"The destination's MCP URL, present only when it is live."},"yenta_page_url":{"type":"string","description":"The destination's page on Yenta, to open or cite; present only when it is live."},"things_to_do":{"type":"object","description":"What the destination publishes, as counts.","properties":{"listing_count":{"type":"integer","description":"Places to eat, stay and visit (default language)."},"categories":{"type":"object","description":"Listing count per category slug, the 5 biggest.","additionalProperties":{"type":"integer"}},"event_count":{"type":"integer","description":"Upcoming events."},"guide_topic_count":{"type":"integer","description":"Guide topics (weather, safety, ...)."}}},"next_steps":{"type":"array","items":{"type":"string"},"description":"Which tool to call next for listings, events and tips."}},"required":["slug","name","country","currency","timezone","default_language"]},"MenuMatch":{"type":"object","description":"One cross-venue menu match — a published menu item tagged with the venue it belongs to, so an agent can rank venues by what is on their menu from one call. No organization or row id ever appears; the venue is identified only by its public slug.","properties":{"venue_slug":{"type":"string"},"venue_name":{"type":"string"},"menu":{"type":"string","description":"The menu the item is on."},"section":{"type":"string","description":"The menu section the item is in."},"name":{"type":"string"},"description":{"type":"string"},"price":{"type":"string","description":"Exact decimal string; never a float (it is a money value)."},"currency":{"type":"string"},"dietary_tags":{"type":"array","items":{"type":"string"}},"allergens":{"type":"array","items":{"type":"string"}},"text_home":{"type":"string","description":"The venue's browsable text home, present only when it is live."}},"required":["venue_slug","venue_name","name","price","currency","dietary_tags","allergens"]},"FacetVocabulary":{"type":"object","description":"The closed facet vocabulary (one sorted array per FacetType) plus today's live cuisine/price_band/neighbourhood values across published venues (the 'live' key) — the exact values search_venues' matching filters accept.","properties":{"vibe":{"type":"array","items":{"type":"string"},"description":"The controlled 'vibe' vocabulary, sorted."},"good_for":{"type":"array","items":{"type":"string"},"description":"The controlled 'good_for' vocabulary, sorted."},"not_good_for":{"type":"array","items":{"type":"string"},"description":"The controlled 'not_good_for' vocabulary, sorted."},"feature":{"type":"array","items":{"type":"string"},"description":"The controlled 'feature' vocabulary, sorted."},"noise_level":{"type":"array","items":{"type":"string"},"description":"The controlled 'noise_level' vocabulary, sorted."},"view":{"type":"array","items":{"type":"string"},"description":"The controlled 'view' vocabulary, sorted."},"dress_code":{"type":"array","items":{"type":"string"},"description":"The controlled 'dress_code' vocabulary, sorted."},"meal_period":{"type":"array","items":{"type":"string"},"description":"The controlled 'meal_period' vocabulary, sorted."},"cuisine":{"type":"array","items":{"type":"string"},"description":"The controlled 'cuisine' vocabulary, sorted."},"dietary":{"type":"array","items":{"type":"string"},"description":"The controlled 'dietary' vocabulary, sorted."},"accessibility":{"type":"array","items":{"type":"string"},"description":"The controlled 'accessibility' vocabulary, sorted."},"live":{"type":"object","description":"Distinct essentials values in use today, folded + one display each.","properties":{"cuisine":{"type":"array","items":{"type":"object","description":"One live essentials value: the folded value search_venues' matching filter accepts (canonical) and one representative spelling (display).","properties":{"canonical":{"type":"string"},"display":{"type":"string"}},"required":["canonical","display"]}},"price_band":{"type":"array","items":{"type":"object","description":"One live essentials value: the folded value search_venues' matching filter accepts (canonical) and one representative spelling (display).","properties":{"canonical":{"type":"string"},"display":{"type":"string"}},"required":["canonical","display"]}},"neighbourhood":{"type":"array","items":{"type":"object","description":"One live essentials value: the folded value search_venues' matching filter accepts (canonical) and one representative spelling (display).","properties":{"canonical":{"type":"string"},"display":{"type":"string"}},"required":["canonical","display"]}}},"required":["cuisine","price_band","neighbourhood"]}},"required":["vibe","good_for","not_good_for","feature","noise_level","view","dress_code","meal_period","cuisine","dietary","accessibility","live"]},"SearchResult":{"type":"object","description":"A unified search result — a published venue or destination, tagged with `kind`. When `kind` is 'venue' the object is a Venue; when 'destination', a Destination (see those schemas). Each item keeps its own `source` freshness reference.","properties":{"kind":{"type":"string","enum":["venue","destination"]}},"required":["kind"],"additionalProperties":true},"Error":{"type":"object","description":"The uniform error envelope; every 404 is byte-identical.","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}