Saltar al contenido principal
PUT
/
stores
Upsert de tiendas
curl --request PUT \
  --url https://api.example.com/stores
{
  "data": {
    "created": 0,
    "updated": 1
  }
}
Crea o actualiza una o más tiendas del comercio autenticado. Usa este endpoint para sincronizar datos de ubicación, disponibilidad por canal, zonas de fulfillment y métodos de pago desde tu POS o RMS hacia Fire spark. Cada elemento del arreglo se identifica por id. Si no existe una tienda con ese id para el comercio, Fire spark la crea. Si ya existe, Fire spark actualiza los campos editables listados abajo. En una actualización, los campos omitidos conservan su valor actual.
Requiere un access token con el scope stores:write. Consulta Autorizar para obtener un token.
Los valores de id de la tienda son inmutables. No puedes cambiar el id de una tienda existente por este endpoint — envía el mismo id que usas en tu POS o RMS en cada sincronización.
Este endpoint falla cuando la tienda tiene overrides programados que entran en conflicto con los campos que intentas sincronizar. Resuelve o espera a que terminen los overrides en conflicto antes de enviar cambios desde tu POS o RMS.

Headers

HeaderRequeridoDescripción
x-brand-idNoLimita el upsert a tiendas de esta marca. Identificador externo de la marca — solo alfanuméricos, _ y -. 1–64 caracteres. Si se omite, aplican todas las tiendas del comercio.

Solicitud

Envía un arreglo JSON. Cada elemento representa una tienda. Incluye id en cada elemento — es el identificador externo estable de tu POS o RMS y la clave del upsert. No se puede cambiar después de crear la tienda.
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": "ubicacion-pos-01",
      "brand_id": "0001",
      "name": "Calle Principal",
      "status": "ACTIVE",
      "timezone": "America/Guayaquil",
      "contact": {
        "email": "principal@comercio.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": "Restaurante Calle Principal"
      },
      "channels": {
        "APP": {
          "id": "app-principal",
          "uid": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
          "name": "App móvil",
          "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"
    }
  ]'

Campos de la solicitud

CampoTipoDescripción
idstringObligatorio. Identificador externo de la tienda en tu POS o RMS. Solo alfanuméricos, _ y -. 1–64 caracteres. Único por comercio. Clave del upsert. No se puede cambiar después de crear la tienda.
brand_idstringIdentificador externo de la marca. Solo alfanuméricos, _ y -. 1–64 caracteres. Opcional — omitir o null para comercios de una sola marca.
namestringNombre visible. 1–100 caracteres.
statusstringACTIVE o INACTIVE.
contactobjectContacto de la tienda. email y phone (E.164) son obligatorios cuando se envía contact.
locationobjectDirección física y coordenadas.
timezonestringZona horaria IANA. 1–100 caracteres.
channelsobjectConfiguración de fulfillment por canal. Cada canal incluye un mapa fulfillment indexado por tipo. Puede ser un objeto vacío {}.
paymentsobjectMétodos de pago y si la tienda acepta pedidos.
cms_template_idstring (UUID)Plantilla CMS a asignar. Omitir para conservar el valor actual en una actualización, o enviar null para quitar la plantilla. Debe referenciar una plantilla existente con entity STORES.
cms es de solo lectura en las respuestas de tienda. Puedes asignar o quitar una plantilla con cms_template_id, pero no puedes escribir valores de campos CMS por este endpoint.

Validación de objetos anidados

CampoTipoRequeridoRestricciones
emailstringCorreo válido.
phonestringFormato E.164.
namestringNo1–100 caracteres.
CampoTipoRequeridoRestricciones
latitudenumber-90 a 90.
longitudenumber-180 a 180.
address_line_1string3–255 caracteres.
address_line_2stringNo3–255 caracteres.
citystring1–100 caracteres.
countrystring1–100 caracteres.
postal_codestringSolo números. 4–10 dígitos.
business_namestring1–100 caracteres.
unit_numberstringNoSolo números. 1–10 dígitos.
Mapa indexado por código de canal. Cada valor requiere id, uid, name y fulfillment — un mapa de tipos de fulfillment para ese canal. Cada fulfillment requiere uid, id, type, name, pricing, coverage_zones y availability.
CampoTipoRestricciones
is_tax_inclusiveboolean
minimum_order_valuenumber≥ 0.
maximum_order_valuenumber0–1,000,000.
tax_ratenumber0–1.
feesarrayCada cargo requiere id, type (FIXED o PERCENTAGE), tax_inclusive, name (objeto localizado), amount (≥ 0) y percentage (0–1).
CampoTipoRestricciones
statusstringOPEN, CLOSED o TEMPORARILY_CLOSED.
schedulesarray | nullArreglo de mapas de horario semanal indexados por día (monday a sunday). Cada día requiere start_time y end_time como horas ISO. null cuando no hay restricción de horarios.
temporary_closed_reasonobjectTexto localizado por locale.
temporary_closed_untilstringFecha y hora ISO 8601 con offset.
Requiere uid, id, type, name, pricing, coverage_zones y availability. instructions es opcional como objeto localizado.Las zonas de cobertura requieren name y type (RADIUS o POLYGON). Cuando type es RADIUS, incluye radius_info con latitude, longitude y radius (0–100,000 metros). Cuando type es POLYGON, incluye polygon_info.polygon como arreglo de puntos con coordenadas.
CampoTipoRestricciones
orderableboolean
methodsarrayCada método requiere method (CREDIT, DEBIT, CASH, BANK_TRANSFER u OTHER), minimum_order_value, maximum_order_value y providers.
Cada proveedor requiere id (UUID), name y status (ACTIVE o INACTIVE).

Respuesta

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

Respuestas de error

EstadoDescripción
400El cuerpo de la solicitud no pasó la validación. Revisa las restricciones de campos arriba.
401Access token ausente o inválido.
403El token no incluye el scope stores:write.
422Violación de regla de negocio — por ejemplo intentar cambiar el id de una tienda, id duplicado para el comercio, u overrides programados que entran en conflicto con los cambios solicitados.
Error de validación
{
  "error": "validation_error",
  "message": "location.postal_code: Postal code must be numbers only"
}