Skip to main content
PUT
/
menus
Upsert menus
curl --request PUT \
  --url https://api.example.com/menus
Creates or updates one or more menus for the authenticated merchant. Use this endpoint to sync composed catalog structure, schedules, and overrides from your POS or RMS into Fire spark. Each array element 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.
Requires an access token with the menus:write scope. See Authorize to obtain a token.
Menu id values are immutable. You cannot change an existing menu’s id through this endpoint — send the same id you use in your POS or RMS on every sync.

Headers

HeaderRequiredDescription
x-brand-idNoScope the upsert to menus for this brand. External brand identifier — alphanumeric characters, _, and - only. 1–64 characters. When omitted, all menus for the merchant are eligible.

Request

Send a JSON array. Each element represents one menu. Include id on every element — it is the stable external identifier from your POS or RMS and the upsert key.
curl -X PUT "https://firespark.vercel.app/api/integrations/v1/menus" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "x-brand-id: 0001" \
  -d '[
    {
      "id": "lunch-delivery",
      "store_id": "downtown",
      "store_uid": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
      "channel_id": "app",
      "channel_uid": "c3d4e5f6-a7b8-9012-cdef-123456789012",
      "fulfillment_id": "delivery",
      "fulfillment_uid": "d4e5f6a7-b8c9-0123-def4-567890abcdef",
      "name": "Lunch delivery menu",
      "description": "Weekday lunch items for app delivery",
      "schedules": [{
        "monday": { "start_time": "11:00:00", "end_time": "15:00:00" },
        "tuesday": { "start_time": "11:00:00", "end_time": "15:00:00" },
        "wednesday": { "start_time": "11:00:00", "end_time": "15:00:00" },
        "thursday": { "start_time": "11:00:00", "end_time": "15:00:00" },
        "friday": { "start_time": "11:00:00", "end_time": "15:00:00" }
      }],
      "products": [],
      "categories": [],
      "modifier_groups": [],
      "overrides": [],
      "status": "ACTIVE"
    }
  ]'

Writable fields

FieldRequired on createDescription
idYesExternal menu identifier. Upsert key. Immutable after creation.
store_idYesExternal store identifier. Must match a store synced via Upsert stores.
store_uidYesFire spark store identifier.
channel_idYesExternal channel identifier. Must match a channel synced via List channels.
channel_uidYesFire spark channel identifier.
fulfillment_idYesExternal fulfillment identifier. Must match fulfillment synced via List fulfillment.
fulfillment_uidYesFire spark fulfillment identifier.
nameYesDisplay name. 1–100 characters.
descriptionNoOptional description. Up to 500 characters.
schedulesNoWeekly hour maps. null when there is no schedule restriction.
productsNoProducts in this composed menu.
categoriesNoCategories in this composed menu.
modifier_groupsNoModifier groups in this composed menu.
cms_template_idNoCMS template UUID. null to clear.
overridesNoScheduled menu changes.
statusNoACTIVE or INACTIVE. Defaults to ACTIVE.
Read-only fields such as uid, organization_id, merchant_id, and cms are ignored on write.

Response

Returns the upserted menu objects in data, matching the shape described in List menus.

Error responses

StatusDescription
400Validation error — invalid field values or missing required fields.
401Missing or invalid access token.
403Token does not include the menus:write scope.
409Referenced store, channel, or fulfillment does not exist for this merchant.