16 endpoints across 6 tag groups.
Every endpoint requires the bearer header. All paths sit under api.sendside.xyz/v1. Successful responses are wrapped in the SousLab envelope. The gateway only exposes the meta / search / restaurants / chains / prices / stats surfaces — upstream /admin paths are not reachable through /v1.
Response envelope
Successful 2xx JSON is always wrapped: { data, pagination?, meta? }. List endpoints carry limit, offset, returned, has_more, and a total when known (total for exact counts, total_estimated for searches). Single-resource endpoints just return { data }. Errors and non-JSON bodies pass through unchanged.
{
"data": [ ... ],
"pagination": {
"limit": 20,
"offset": 0,
"returned": 20,
"total": 487, // exact, for /chains, /search
"has_more": true
},
"meta": { "query": "ramen", "processing_ms": 7 }
}Meta
Health and version probes. Unauthenticated, cached at the edge.
Search
Full-text + filter search across restaurants and items. Backed by Typesense upstream; results carry processing_ms in the meta block. Each hit's record is returned at the top of the document object — opt in to per-hit highlight snippets with ?include_highlights=true. Search index covers ~92% of items today; full coverage is in flight.
Search restaurants
Full-text restaurant search with optional state / cuisine / geo-radius / source-tier filters. When `geo` is present, results are sorted by distance.
Parameters
Body
qstringdefault statestringcuisinestringcuisinesstring[]geoGeoRadius{ lat, lng, radius_m } (radius_m max 50,000). Sorts by distance.has_geobooleandata_tierstringprimarysecondarysupplementaldata_tier_instring[]data_confirmationstringhighmediumlowsortstring[]limitintegerdefault 20offsetintegerdefault 0Search menu items
Full-text search across menu items (dish names, descriptions). Optional state / cuisine / price-range / stock filters.
Parameters
Body
qstringdefault statestringcuisinestringmin_pricenumbermax_pricenumberin_stock_onlybooleandefault falsegeoGeoRadiusdata_tierstringprimarysecondarysupplementaldata_tier_instring[]sortstring[]limitintegerdefault 20offsetintegerdefault 0Restaurants
Single-restaurant lookups: full record, normalized menu.
Restaurant menu
Complete normalized menu: menus → sections → items. Items include parsed price (number) and price_text (the original string — populated when upstream could not coerce to a number, e.g. “Market price”).
Parameters
Path
restaurant_idULID (26 chars)requiredChains
The chain entity layer: brand → corporate parent → public ticker. Locations, canonical menu items, and geographic price summaries per chain.
List chains
Paginated list of restaurant chain entities. Filter by ticker, parent company, cuisine, coverage priority, or full-text on canonical name. Sortable by location count or name.
Parameters
Query
qstringtickerstringparentstringcuisinestringprioritystringalt_data_criticalcpg_criticalstandardpublic_onlybooleandefault falsesortstringdefault locations_desclocations_desclocations_ascname_ascticker_asclimitintegerdefault 50offsetintegerdefault 0Chain locations
Individual storefronts attached to a chain. Filter by state / city / metro (3-digit zip prefix).
Parameters
Path
chain_idstringrequiredQuery
statestringcitystringmetrostringlimitintegerdefault 50offsetintegerdefault 0Chain price summary
Geographic spread of prices for one canonical item across a chain. Aggregates current per-source prices, grouped by state / metro / zip3 / none. Returns location count + min/median/avg/max per group.
Parameters
Path
chain_idstringrequiredQuery
canonical_item_idstringrequired/v1/chains/{id}/canonical-items.group_bystringdefault statemetro = first 3 of zip; none = single row, with group_key returned as null.statemetrozip3nonedata_tierstringprimarysecondarysupplementalPrices
Per-item current prices across sources, plus chronological price-change history.
Current item prices
All current per-source prices for one item. Returns one observation per (item, source) — the same canonical menu item may appear on multiple aggregator sources at different prices.
Parameters
Path
item_uidhex (32 chars)requiredItem price history
Chronological price-change events for one item, across all sources. Each event carries an observation_method field — one of refresh, backfill, manual, or seed — indicating how the price was captured.
Parameters
Path
item_uidhex (32 chars)requiredQuery
sinceISO-8601 timestamplimitintegerdefault 100Restaurant price history
All price-change events across all items at one restaurant. Each event carries an observation_method field — one of refresh, backfill, manual, or seed — indicating how the price was captured.
Parameters
Path
restaurant_idULID (26 chars)requiredQuery
sinceISO-8601 timestamplimitintegerdefault 200Stats
Aggregate counts and percentile prices by region.
Looking for a specific pattern?
The Recipes page has worked examples for the most common flows: search-by-city, chain price benchmarking, ticker-level price history. Or email hello@sendside.xyz and we'll write the snippet.
