Skip to main content
PUT
/
stores
Upsert stores
curl --request PUT \
  --url https://api.example.com/stores
{
  "data": {
    "created": 0,
    "updated": 1
  }
}
Creates or updates one or more stores for the authenticated merchant. Use this endpoint to sync location details, channel availability, fulfillment zones, and payment settings from your POS or RMS into Fire spark. Each array element is matched by id. When no store 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 stores:write scope. See Authorize to obtain a token.
Store id values are immutable. You cannot change an existing store’s id through this endpoint — send the same id you use in your POS or RMS on every sync.
This endpoint fails when the store has scheduled overrides that conflict with the fields you are syncing. Resolve or wait out conflicting overrides before pushing changes from your POS or RMS.

Headers

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

Request

Send a JSON array. Each element represents one store. Include id on every element — it is the stable external identifier from your POS or RMS and the upsert key. It cannot be changed after the store is created.
curl -X PUT "https://firespark.vercel.app/api/integrations/v1/stores" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "x-brand-id: 0001" \
  -d '[
    {
      "id": "pos-location-01",
      "brand_id": "0001",
      "name": "Main Street",
      "status": "ACTIVE",
      "timezone": "America/Guayaquil",
      "contact": {
        "email": "main@merchant.com",
        "phone": "+593991234567"
      },
      "location": {
        "latitude": -2.1894,
        "longitude": -79.8891,
        "address_line_1": "Calle Principal 456",
        "city": "Guayaquil",
        "country": "Ecuador",
        "postal_code": "090101",
        "business_name": "Main Street Restaurant"
      },
      "channels": {
        "APP": {
          "id": "app-main",
          "uid": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
          "name": "Mobile app",
          "fulfillment": {
            "DELIVERY": {
              "uid": "c3d4e5f6-a7b8-9012-cdef-123456789012",
              "id": "delivery",
              "type": "DELIVERY",
              "name": "Delivery",
              "pricing": {
                "is_tax_inclusive": false,
                "minimum_order_value": 10,
                "maximum_order_value": 200,
                "tax_rate": 0.15,
                "fees": []
              },
              "coverage_zones": [],
              "availability": {
                "status": "OPEN",
                "schedules": [{
                  "monday": { "start_time": "10:00:00", "end_time": "22:00:00" },
                  "tuesday": { "start_time": "10:00:00", "end_time": "22:00:00" },
                  "wednesday": { "start_time": "10:00:00", "end_time": "22:00:00" },
                  "thursday": { "start_time": "10:00:00", "end_time": "22:00:00" },
                  "friday": { "start_time": "10:00:00", "end_time": "22:00:00" }
                }]
              }
            }
          }
        }
      },
      "payments": {
        "orderable": true,
        "methods": []
      },
      "cms_template_id": "d4e5f6a7-b8c9-0123-def4-567890abcdef"
    }
  ]'

Request fields

FieldTypeDescription
idstringRequired. External store identifier from your POS or RMS. Alphanumeric characters, _, and - only. 1–64 characters. Unique per merchant. Used as the upsert key. Cannot be changed after the store is created.
brand_idstringExternal brand identifier. Alphanumeric characters, _, and - only. 1–64 characters. Optional — omit or set null for single-brand merchants.
namestringDisplay name. 1–100 characters.
statusstringACTIVE or INACTIVE.
contactobjectStore contact. email and phone (E.164) are required when contact is sent.
locationobjectPhysical address and coordinates.
timezonestringIANA timezone. 1–100 characters.
channelsobjectPer-channel fulfillment configuration. Each channel includes a fulfillment map keyed by fulfillment type. Can be an empty object {}.
paymentsobjectPayment methods and whether the store accepts orders.
cms_template_idstring (UUID)CMS template to assign to the store. Omit to keep the current value on update, or set null to remove the template. Must reference an existing template with entity STORES. Required on create when you assign a template.
cms is read-only on store responses. You can assign or clear a template with cms_template_id, but you cannot write CMS field values through this endpoint.

Nested object validation

FieldTypeRequiredConstraints
emailstringYesValid email.
phonestringYesE.164 format.
namestringNo1–100 characters.
FieldTypeRequiredConstraints
latitudenumberYes-90 to 90.
longitudenumberYes-180 to 180.
address_line_1stringYes3–255 characters.
address_line_2stringNo3–255 characters.
citystringYes1–100 characters.
countrystringYes1–100 characters.
postal_codestringYesNumeric only. 4–10 digits.
business_namestringYes1–100 characters.
unit_numberstringNoNumeric only. 1–10 digits.
Map keyed by channel code. Each value requires id, uid, name, and fulfillment — a map of fulfillment types for that channel. Each fulfillment entry requires uid, id, type, name, pricing, coverage_zones, and availability.
FieldTypeConstraints
is_tax_inclusiveboolean
minimum_order_valuenumber≥ 0.
maximum_order_valuenumber0–1,000,000.
tax_ratenumber0–1.
feesarrayEach fee requires id, type (FIXED or PERCENTAGE), tax_inclusive, name (localized object), amount (≥ 0), and percentage (0–1).
FieldTypeConstraints
statusstringOPEN, CLOSED, or TEMPORARILY_CLOSED.
schedulesarray | nullWeekly hour maps keyed by day name (monday through sunday). Each day requires start_time and end_time as ISO times. null when there is no schedule restriction.
temporary_closed_reasonobjectLocalized text keyed by locale.
temporary_closed_untilstringISO 8601 datetime with offset.
Requires uid, id, type, name, pricing, coverage_zones, and availability. Optional instructions as a localized object.Coverage zones require name and type (RADIUS or POLYGON). When type is RADIUS, include radius_info with latitude, longitude, and radius (0–100,000 meters). When type is POLYGON, include polygon_info.polygon as an array of coordinate points.
FieldTypeConstraints
orderableboolean
methodsarrayEach method requires method (CREDIT, DEBIT, CASH, BANK_TRANSFER, or OTHER), minimum_order_value, maximum_order_value, and providers.
Each provider requires id (UUID), name, and status (ACTIVE or INACTIVE).

Response

{
  "data": {
    "created": 0,
    "updated": 1
  }
}

Error responses

StatusDescription
400Request body failed validation. Check field constraints above.
401Missing or invalid access token.
403Token does not include the stores:write scope.
422Business rule violation — for example attempting to change a store id, duplicate id for the merchant, or scheduled overrides that conflict with the requested changes.
Validation error
{
  "error": "validation_error",
  "message": "location.postal_code: Postal code must be numbers only"
}