Docs
POST /v1/enrich/restaurant
Match a restaurant you already have. A matched response returns the compass_id to store and the evidence Decide uses.
Complete food menu
Every returned restaurant includes vegan_dining.menu: all food dishes, stored prices and ingredients, without drinks or descriptions. No option is required. Search accepts at most 10 restaurants per request. Credits stay unchanged. Google-labeled menus return an empty menu with null counts and excluded: "source_not_permitted".
Ingredients as printed on the restaurant's menu, when listed. May be incomplete. Not for allergy decisions.
Menus deduplicate by normalized dish name. The first stored food row supplies display fields. Original sections are grouped with main courses first; other sections retain stored order, and unknown sections come last. False is_vegan includes unconfirmed classifications. Menus are never truncated: JSON responses above 250 KB return 413 full_menu_too_large; streaming Search emits an error event with status 413. Reduce the Search limit or retrieve restaurants individually.
Request
| Field | Type | Notes |
|---|---|---|
| name | string | Required restaurant name. |
| address | string | Required unless google_place_id is provided. |
| google_place_id | string | Optional match key. Use only when already available from the customer workflow. |
curl -X POST "https://api.compassfoodtechnologies.com/v1/enrich/restaurant" \
-H "Content-Type: application/json" \
-H "X-Compass-API-Key: $COMPASS_API_KEY" \
-d '{
"name": "Example Ramen House",
"address": "123 Example Street, Brooklyn, NY"
}'Matched response
EnrichResponseMatched: 76 contract leaves. A row is one contract leaf. Optional leaves, missing restaurant evidence, and fast mode can omit fields. This count is the schema, not a promise that every response contains every field.
| Field | Type | Notes |
|---|---|---|
| ai_generated | boolean | Required on this object. |
| client_ref | string | Optional. Omitted when the value is absent. |
| compass_id | string | Required on this object. |
| compass_request_id | string | Required on this object. |
| evidence[].evidence_id | string | Required on this object. Key field. Paraphrased evidence excerpts, not a menu. |
| evidence[].excerpt | string | Optional. Omitted when the value is absent. Key field. Paraphrased evidence excerpts, not a menu. |
| evidence[].paraphrase_method | automatic | manual | none | Optional. Omitted when the value is absent. Key field. Paraphrased evidence excerpts, not a menu. |
| evidence[].source | string (uri) | Required on this object. Key field. Paraphrased evidence excerpts, not a menu. |
| evidence[].tier | A | B | Required on this object. Key field. Paraphrased evidence excerpts, not a menu. |
| evidence[].type | menu_item | review_signal | external_source | user_report | restaurant_declared | Required on this object. Key field. Paraphrased evidence excerpts, not a menu. |
| evidence[].weight | primary | supporting | Required on this object. Key field. Paraphrased evidence excerpts, not a menu. |
| google_place_id | string | Optional. Omitted when the value is absent. |
| identity_status | resolved | Optional. Omitted when the value is absent. |
| match_confidence | number | Required on this object. |
| matched | true | Required on this object. |
| restaurant.address.city | string | null | Required on this object. |
| restaurant.address.country | string | null | Required on this object. |
| restaurant.address.postal_code | string | null | Required on this object. |
| restaurant.address.state | string | null | Required on this object. |
| restaurant.address.street | string | null | Required on this object. |
| restaurant.compass_id | string | Required on this object. |
| restaurant.coordinates.lat | number (double) | null | Required on this object. |
| restaurant.coordinates.lng | number (double) | null | Required on this object. |
| restaurant.cuisine_types[] | string | Required on this object. |
| restaurant.dietary_profile.food_availability.fish | yes | no | unknown | Required on this object. |
| restaurant.dietary_profile.food_availability.meat | yes | no | unknown | Required on this object. |
| restaurant.dietary_profile.food_availability.pescatarian_options | yes | no | unknown | Required on this object. |
| restaurant.dietary_profile.food_availability.shellfish | yes | no | unknown | Required on this object. |
| restaurant.dietary_profile.food_availability.vegan_options | yes | no | unknown | Required on this object. |
| restaurant.dietary_profile.food_availability.vegetarian_options | yes | no | unknown | Required on this object. |
| restaurant.dietary_profile.fully_vegan | boolean | null | Required on this object. |
| restaurant.dietary_profile.vegan_friendly | boolean | null | Required on this object. |
| restaurant.evidence[].evidence_id | string | Required on this object. |
| restaurant.evidence[].excerpt | string | Optional. Omitted when the value is absent. |
| restaurant.evidence[].paraphrase_method | automatic | manual | none | Optional. Omitted when the value is absent. |
| restaurant.evidence[].source | string (uri) | Required on this object. |
| restaurant.evidence[].tier | A | B | Required on this object. |
| restaurant.evidence[].type | menu_item | review_signal | external_source | user_report | restaurant_declared | Required on this object. |
| restaurant.evidence[].weight | primary | supporting | Required on this object. |
| restaurant.last_evaluated_at | string (date-time) | null | Required on this object. |
| restaurant.last_verified_at | string (date-time) | null | Required on this object. |
| restaurant.name | string | null | Required on this object. |
| restaurant.services | object of boolean | Optional. Omitted when the value is absent. |
| restaurant.source_freshness.newest_signal_age_days | integer | Required on this object. Key field. Age of the signals behind the score. |
| restaurant.source_freshness.oldest_signal_age_days | integer | Required on this object. Key field. Age of the signals behind the score. |
| restaurant.vegan_dining.dishes_availability | yes | unknown | Required on this object. |
| restaurant.vegan_dining.match_status | matched | no_supported_match | evidence_unavailable | Required on this object. |
| restaurant.vegan_dining.matched_dishes[].category | string | null | Required on this object. |
| restaurant.vegan_dining.matched_dishes[].evidence_id | string | Required on this object. |
| restaurant.vegan_dining.matched_dishes[].match_type | exact | variant | not_requested | Required on this object. |
| restaurant.vegan_dining.matched_dishes[].name | string | Required on this object. |
| restaurant.vegan_dining.matched_dishes[].vegan_basis | validated_menu_classification | Required on this object. |
| restaurant.vegan_dining.matching_dish_count | integer | null | Required on this object. |
| restaurant.vegan_dining.menu_collected_at | string (date-time) | null | Required on this object. |
| restaurant.vegan_dining.menu_collected_at_status | known | unknown | Required on this object. |
| restaurant.vegan_dining.menu.dish_count | integer | null | Required on this object. |
| restaurant.vegan_dining.menu.dishes[].category | string | null | Required on this object. |
| restaurant.vegan_dining.menu.dishes[].ingredients_as_listed[] | string | Required on this object. |
| restaurant.vegan_dining.menu.dishes[].is_vegan | boolean | Required on this object. |
| restaurant.vegan_dining.menu.dishes[].name | string | Required on this object. |
| restaurant.vegan_dining.menu.dishes[].price | string | null | Required on this object. |
| restaurant.vegan_dining.menu.excluded | source_not_permitted | null | Required on this object. |
| restaurant.vegan_dining.menu.vegan_dish_count | integer | null | Required on this object. |
| restaurant.vegan_dining.truncated | boolean | Required on this object. |
| restaurant.vegan_dining.vegan_dish_count | integer | null | Required on this object. |
| restaurant.vegan_score.base | 10 | 30 | 50 | 70 | 80 | null | Required on this object. Menu-based score before review adjustments. Null on legacy rows. |
| restaurant.vegan_score.is_fully_vegan | boolean | null | Required on this object. |
| restaurant.vegan_score.overall | number | null | Required on this object. |
| restaurant.vegan_score.quality_adj | 0 | 10 | null | Required on this object. Quality review adjustment: 0 or 10. |
| restaurant.vegan_score.quality_adj_reason | praised | no_standout | not_applicable | null | Required on this object. |
| restaurant.vegan_score.scored_at | string (date-time) | null | Required on this object. |
| restaurant.vegan_score.scoring_version | string | null | Required on this object. |
| restaurant.vegan_score.vegan_adj | -10 | 0 | 10 | null | Required on this object. Vegan review adjustment: -10, 0 or 10. |
| restaurant.vegan_score.vegan_adj_reason | praised | weak | not_enough_reviews | mixed | not_applicable | null | Required on this object. |
| restaurant.vegan_score.vegan_dish_count | integer | null | Required on this object. |
| restaurant.vegan_score.vegan_main_count | integer | null | Required on this object. Number of vegan mains at scoring time. |
Abridged EnrichResponseMatched example — 31 of 76 contract leaves. Illustrative values, not a live payload.
{
"compass_request_id": "req_example_ramen_house_enrich",
"matched": true,
"identity_status": "resolved",
"match_confidence": 0.97,
"compass_id": "cmp_example_ramen_house_001",
"restaurant": {
"compass_id": "cmp_example_ramen_house_001",
"name": "Example Ramen House",
"vegan_score": {
"overall": 70,
"scoring_version": "v5.0-menu",
"base": 70,
"vegan_main_count": 4,
"vegan_dish_count": 6,
"is_fully_vegan": false,
"vegan_adj": 0,
"vegan_adj_reason": "not_enough_reviews",
"quality_adj": 0,
"quality_adj_reason": "no_standout",
"scored_at": "2026-10-23T12:00:00.000Z"
},
"vegan_dining": {
"dishes_availability": "yes",
"vegan_dish_count": 6,
"matching_dish_count": 2,
"matched_dishes": [
{
"name": "Shoyu Vegan Ramen",
"category": "Pasta & Noodles",
"match_type": "variant",
"evidence_id": "ev_dish_example_shoyu_vegan_ramen",
"vegan_basis": "validated_menu_classification"
},
{
"name": "Spicy Miso Vegan Ramen",
"category": "Pasta & Noodles",
"match_type": "variant",
"evidence_id": "ev_dish_example_spicy_miso_vegan_ramen",
"vegan_basis": "validated_menu_classification"
}
],
"truncated": false,
"menu_collected_at": "2026-10-07T16:00:00Z",
"menu_collected_at_status": "known",
"match_status": "matched"
}
},
"ai_generated": true
}Unmatched response
HTTP 200 with matched: false means Compass could not confirm the record. compass_id is null. Do not call Decide and do not take the first match_candidates entry.
Name matching ignores case, spacing, and punctuation. When more than one record matches, such as two locations of one chain, identity_status is ambiguous and each candidate includes its stored address.
EnrichResponseUnmatched: 28 contract leaves. A row is one contract leaf. Optional leaves, missing restaurant evidence, and fast mode can omit fields. This count is the schema, not a promise that every response contains every field.
| Field | Type | Notes |
|---|---|---|
| ai_generated | boolean | Required on this object. |
| client_ref | string | Optional. Omitted when the value is absent. |
| compass_id | string | null | Required on this object. |
| compass_request_id | string | Required on this object. |
| coverage.covered_geography | US | Required on this object. |
| coverage.interpreted_location | string | Optional. Omitted when the value is absent. |
| coverage.note | string | Optional. Omitted when the value is absent. |
| coverage.status | in_coverage | out_of_coverage | coverage_unknown | Required on this object. |
| google_place_id | string | Optional. Omitted when the value is absent. |
| identity_status | no_confident_match | ambiguous | lookup_incomplete | Optional. Omitted when the value is absent. |
| match_candidates[].address.city | string | null | Required on this object. |
| match_candidates[].address.country | string | null | Required on this object. |
| match_candidates[].address.postal_code | string | null | Required on this object. |
| match_candidates[].address.state | string | null | Required on this object. |
| match_candidates[].address.street | string | null | Required on this object. |
| match_candidates[].compass_id | string | Required on this object. |
| match_candidates[].match_score | number | Required on this object. |
| match_candidates[].name | string | Required on this object. |
| match_candidates[].name_match.kind | exact | variant | possible | Required on this object. |
| match_candidates[].name_match.reason_codes[] | NORMALIZED_NAME | COMPATIBLE_TEXT_KEY | DISTINCTIVE_CORE | EXPLAINED_SUFFIX | UNEXPLAINED_QUERY_TERMS | CONSTRAINED_TYPO | Required on this object. |
| match_candidates[].name_match.selection_required | boolean | Required on this object. |
| match_confidence | number | Required on this object. |
| matched | false | Required on this object. |
| named_lookup.complete | boolean | Required on this object. |
| named_lookup.policy_version | named-matching/1 | named-matching/1.1 | named-matching/1.2 | named-matching/1.3 | named-matching/1.4 | Required on this object. |
| named_lookup.truncated | boolean | Required on this object. |
| resolution.compass_ids[] | string | Optional. Omitted when the value is absent. |
| resolution.status | unresolved | ambiguous | Required on this object. |
Abridged EnrichResponseUnmatched example — 13 of 28 contract leaves. Illustrative values, not a live payload.
{
"compass_request_id": "req_example_ramen_house_unmatched",
"matched": false,
"match_confidence": 0.41,
"compass_id": null,
"match_candidates": [
{
"compass_id": "cmp_example_ramen_house_candidate",
"name": "Example Ramen",
"match_score": 0.62,
"address": {
"street": "100 Example Ave",
"city": "Portland",
"state": "OR",
"postal_code": "97201",
"country": "US"
}
}
],
"ai_generated": true
}ID stability
The public compass_id on Search, Enrich, and Decide is currently the Firestore document ID. It is not the immutable compass_place_id.
Within the lifetime of a live record, compass_id stays the same across rescores and re-syncs. After a merge, the old ID keeps resolving only while the redirect alias and the live target both still exist.
Retirement, physical deletion, and a city wipe or rebuild can remove an ID. /v1/changes does not emit merge or redirect events. A deleted event can come from a closed or archived record, a retained deletion tombstone, or a qualifying RETIRED compass_place_id alias. A canonical city wipe removes that city's own records. An alias or tombstone shared with a restaurant that stays is left in place, and the wipe does not write a new deletion marker for a record it removes. The feed is not a complete deletion record.
Store the mapping, re-resolve when you need the current record, and handle an ID that no longer resolves. After a documented city rebuild, reconcile that city's data instead of relying only on /v1/changes.
Next step
Pass compass_id to Decide for a fit, not_fit, or unknown verdict per user profile — or see Integration patterns for the full chain.