menus is matched by id. When no menu exists with that id for the merchant, Fire spark creates it. When one already exists, Fire spark updates the writable fields below. Omitted fields keep their current values on update.
Scope the upsert with optional query parameters. Fire spark resolves organization and merchant context from your access token.
Requires an access token with the
menus:write scope. See
Token to obtain a token.Headers
Query parameters
Omit scope query parameters for an optional merchant-wide default — useful when store, channel, or fulfillment is not chosen yet. Add
fulfillment_id, store_id, channel_id, and/or brand_id to override that default for a specific selling context. Omit a scope parameter or pass __ANY__ to store the wildcard for that dimension. See Menu sync for the recommended baseline-and-override workflow.
Sync styles
The request body is a discriminated union onstyle. Fire spark validates each variant against a different schema.
Send
"style": "DEFAULT" or "style": "UBER_EATS" at the top level. Shared catalog entities and up to 10 menu definitions are sent in the same request for both styles.
Request
Switch between DEFAULT and UBER_EATS in the request examples panel to see both payload shapes. Both calls usePUT with scope query parameters (fulfillment_id, store_id, channel_id, brand_id).
- Default
- Uber Eats
Fire spark native payload. Products, categories, and modifier groups use Fire spark field names (
name, pricing, items, and so on).Request body
- Default
- Uber Eats
Menu fields
Each object inmenus accepts these writable fields:products
products
Each product in the request body:
|
id | Yes | string | External product identifier. |
| name | Yes | object | Localized display name keyed by locale (for example en_us). |
| description | No | object | null | Localized description. null when omitted. |
| image_url | No | string | Product image URL. JPG, PNG, or WebP. Fire spark copies it to public storage and serves a render URL so clients can add width, height, and resize. null when omitted. |
| bundled_items | No | array | Items included in a bundle or combo. Defaults to []. |
| pricing | Yes | object | Price, tax, quantity limits, and modifier configuration. See pricing. |
| availability | Yes | object | Product availability. See fields below. |
| labels | No | string[] | Short labels for Dashboard filters and quick selection. At most 64 strings (1–128 characters each). Defaults to []. |
| tags | No | object | Key/value tags for advanced custom rules. Values may be boolean, string, or number. Defaults to {}. See Custom rules. |
| metadata | No | object | Partner-specific metadata. Defaults to {}. |Each availability object:Each
bundled_items entry:|
id | Yes | string | External identifier of the bundled product. |
| refund_price | Yes | number | Refund amount when the customer removes this item from the bundle. ≥ 0. |
| included_quantity | Yes | number | Units included by default. ≥ 0. |Example product
categories
categories
Each category in the request body:
|
id | Yes | string | External category identifier. |
| name | Yes | object | Localized display name keyed by locale. |
| description | No | object | null | Localized description. null when omitted. |
| image_url | No | string | Category image URL. Must be a JPG, PNG, or WebP. null when omitted. |
| items | Yes | array | Ordered category entries. At least 1 entry. At most 1000. |
| availability | Yes | object | Category availability. See fields below. |
| labels | No | string[] | Short labels for Dashboard filters and quick selection. At most 64 strings (1–128 characters each). Defaults to []. |
| tags | No | object | Key/value tags for advanced custom rules. Values may be boolean, string, or number. Defaults to {}. See Custom rules. |
| metadata | No | object | Partner-specific metadata. Defaults to {}. |Each entry in items:Each
availability object:Example category
modifier_groups
modifier_groups
Each modifier group in the request body:
|
id | Yes | string | External modifier group identifier. Referenced from pricing.modifier_group_ids. |
| title | Yes | object | Localized group title keyed by locale. |
| description | No | object | null | Localized description. null when omitted. |
| display_type | No | string | GRID or LIST. |
| modifier_ids | Yes | array | Product UUIDs for modifiers in this group. 1–100 entries. A single-option group is valid. |
| minimum_quantity | Yes | number | Minimum selections required. ≥ 0. |
| maximum_quantity | Yes | number | Maximum selections allowed. 0–1,000,000. |
| charge_above_quantity | No | number | Number of free selections before additional charges apply. Optional. |
| metadata | No | object | Partner-specific metadata. Defaults to {}. |Example modifier group
recommendations
recommendations
Each recommendation in the top-level catalog:
Example recommendation
variant_groups
variant_groups
Each variant group:
Each entry in
variants:Example variant group
pricing
pricing
Product pricing in the request body:
|
minimum_quantity | No | number | Minimum units per order. ≥ 0. Defaults to 0. |
| maximum_quantity | No | number | Maximum units per order. 0–1,000,000. Defaults to 1000000. |
| is_tax_inclusive | Yes | boolean | Whether price includes tax. |
| tax_rate | Yes | number | Tax rate as a decimal (for example 0.15 for 15%). 0–1. |
| price | Yes | number | List price. ≥ 0. |
| anchor_price | No | number | Reference price for strikethrough or comparison. ≥ 0. |
| anchor_price_percentage | No | number | Discount shown relative to anchor_price. 0–1. |
| starting_price | No | number | null | Reference “From” price. Omit it and Fire spark calculates the lowest price that satisfies every required modifier during sync. Send null to never show it. ≥ 0. |
| modifiers | No | array | Per-group pricing and selection overrides. Defaults to []. |
| modifier_group_ids | No | array | External modifier group identifiers attached to this product. Defaults to []. |
| variant_group_ids | No | array | Variant groups asked on this base product. Each id must exist in variant_groups and appear once. A product with variant groups can’t have modifier_group_ids. Defaults to []. See Variants. |
| variants | No | array | When this product is a variant: one entry per base, each { "product_id": base id, "variant_group_option_ids": [...] } with exactly one option from every group on the base. Defaults to []. |
| recommendations_ids | No | array | Recommendation ids to surface on this product. Each id must exist in top-level recommendations. Defaults to []. |
| recommendations | No | array | Per-recommendation display settings on this product. Defaults to []. |Each object in recommendations (inside pricing) links one catalog recommendation to the parent product:Each object in
modifiers configures one modifier group referenced in modifier_group_ids. It accepts the same pricing fields as the parent product, plus modifier-specific fields:|
modifier_group_id | Yes | string | External modifier group identifier. Must match a group in modifier_group_ids. |
| minimum_quantity | No | number | Minimum units per order for modifiers in this group. ≥ 0. Defaults to 0. |
| maximum_quantity | No | number | Maximum units per order for modifiers in this group. 0–1,000,000. |
| is_tax_inclusive | Yes | boolean | Whether price includes tax for modifiers in this group. |
| tax_rate | Yes | number | Tax rate as a decimal (for example 0.15 for 15%). 0–1. |
| price | Yes | number | List price for modifiers in this group. ≥ 0. |
| anchor_price | No | number | Reference price for strikethrough or comparison. ≥ 0. |
| anchor_price_percentage | No | number | Discount shown relative to anchor_price. 0–1. |
| default_quantity | Yes | number | Pre-selected quantity for modifiers in this group. ≥ 0. |
| charge_above_quantity | No | number | Free selections before charges apply. Optional. |
| display_type | No | string | How modifiers render in the UI: RADIO, CHECKBOX, or QUANTITY. Optional. |
| image_url | No | string | Image for this product in this modifier group only. JPG, PNG, or WebP. Omit it to keep the product image. Copied to public storage like product images. |Example modifiers entry
Response
The endpoint returns asynchronously. Fire spark starts a background menu sync and responds immediately.
Treat
202 as success: the catalog is already being processed. Retry only after the current sync finishes or fails.
Treat 409 as success when replaying a release that already completed successfully. If the prior sync for that release and scope FAILED or was CANCELLED, send the same x-release-id again.
Rate limits
GET and PUT /api/integrations/v1/menus share a limit of 30 requests per 10 seconds per merchant. The limit key is the merchant_id from your access token.
Send one request at a time per merchant — wait for each response before starting the next. Do not parallelize menu upserts or reads for the same merchant.
Every response includes rate limit headers so you know when you can send the next request:
When you exceed the limit, the API returns
429 Too Many Requests. Wait Retry-After seconds (or X-RateLimit-Reset) before sending another request for that merchant.
Error responses
| Status | Description | | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --- | |400 | Validation error — invalid field values, missing required fields, or invalid weekly schedule shape. The body is { "error": "Invalid fields", "details": { "<path>": "<message>" } }. See Validation rules. |
| 401 | Missing or invalid access token. |
| 403 | Token does not include the menus:write scope. |
| 409 | Referenced store, channel, or fulfillment does not exist for this merchant, or a sync already exists for this release and scope. |
| 429 | Rate limit exceeded — wait for Retry-After / X-RateLimit-Reset before retrying. See Rate limits. | |