KicketKicket
Mi cuenta
Guía · Modelo de datos▾
  • Inicio
  • Primeros pasos
  • Autenticación
  • Paginación y sincronización
  • Errores
  • Límites de uso
  • Webhooks
  • Conciliación
  • Modelo de datos
  • Referencia
  • Descargas
  • Cambios

API de Kicket · v1

  • Inicio
  • Primeros pasos
  • Autenticación
  • Paginación y sincronización
  • Errores
  • Límites de uso
  • Webhooks
  • Conciliación
  • Modelo de datos
  • Referencia
  • Descargas
  • Cambios

Modelo de datos

Cómo están armados los objetos de la API y las decisiones que conviene conocer antes de mapearlos a tu sistema.

Convenciones

  • Los campos van en inglés y snake_case. Cada objeto dice qué es en object.
  • Todo campo del esquema viene siempre: si no hay dato, va null (nunca se omite). La única excepción es customer en la venta, que viene sólo con include=customer.
  • Fechas ISO 8601 con el huso de la sucursal y milisegundos: 2026-10-27T09:15:02.123-03:00. Las de los clientes, con el huso de la casa matriz.
  • Importes como número con hasta 2 decimales, en la moneda de la sucursal (currency, ISO 4217).
  • En la v1 sólo se agregan campos y valores: ignorá lo que no conozcas y aceptá valores nuevos en los enumerados.

Cuenta y sucursales

La cuenta es la casa matriz de una cadena (o el local, si es uno solo). Una credencial ve la matriz y todas sus sucursales de hoy; cada objeto trae su branch_id. La matriz sale con is_headquarters: true. El external_code de una sucursal es el código que le pone el comercio, para cruzarla con tu sistema.

  • Una sucursal que entra a la cadena trae su historia con su updated_at de siempre (viejo): la sincronización incremental no la ve. Compará GET /branches en cada corrida y, para una nueva, hacé una carga inicial con branch_id=<nueva> y una fecha vieja.
  • Una sucursal que sale de la cadena desaparece de todos los listados, sin lápida. Lo que ya sincronizaste de ella queda en tu base: decidí vos qué hacer. En la v1 active de una sucursal es siempre true.

Una venta es una orden

Cada orden de Kicket es una venta: lo que se cobra en el mostrador, lo que pide una mesa, un pedido de la carta online, uno de delivery. En una mesa, cada ronda es una venta y check_id las agrupa: es la cuenta de la mesa.

Estado

statusQué es
OPENUna ronda de mesa todavía sin cobrar. No tiene pagos.
CLOSEDCobrada (también la cerrada en $0, la fiada y la que nace pagada). Una devolución parcial la deja CLOSED, con el total achicado.
CANCELEDAnulada sin devolver plata.
REFUNDEDAnulada con la plata devuelta.

Canal

channelQué es
counterMostrador: la caja.
tableMesa atendida por un mozo, o que comandó la caja.
qr_tableMesa que pidió sola con el QR.
onlineLa carta online: para retirar o con envío propio.
deliveryUn pedido que entró por una app de delivery.
kioskTótem de autoservicio.
otherReservado para canales nuevos.

Los canales son los mismos de Analítica: lo que suma un canal en la API es lo que suma ese canal en el Resumen.

La mesa

  • table es el nombre o número de la mesa; check_id, la cuenta que agrupa sus rondas (un id opaco y estable).
  • covers son los cubiertos de la mesa: vienen iguales en cada ronda que se cerró junta. Contalos una vez por check_id, nunca los sumes por venta.
  • waiter y cashier son personas del equipo: un id opaco (stf_…) y el nombre visible. Nunca el mail.

Si tu sistema cuenta una venta por mesa

En otros sistemas una mesa es una sola venta; en Kicket es una venta por ronda. Para verla como una: agrupá por check_id y sumá total, tip_total y los pagos; los covers, una sola vez.

  • Mientras la ronda está OPEN, check_id puede venir null (nace al cobrar en las mesas sin atención en mesa): usá table hasta que llegue. Si la mesa se cobra en dos cierres distintos, son dos check_id.
  • sales_count del reporte diario cuenta rondas, no mesas: el ticket promedio por mesa lo calculás vos, con la agrupación de arriba.
  • Un cobro de mesa con tarjeta sale repartido en un pago por ronda (con el mismo method_id): para cruzarlo con el posnet, agrupá por check_id y method_id. La propina va en tip_total de cada venta, no en un pago.

Los renglones, en árbol

items viene en árbol: parent_item_id apunta al renglón padre. La plata vive en un solo nivel, así la suma de line_total de los renglones vigentes da el total.

kindQué esPlata
productUn producto vendido.Su precio, sin los adicionales.
modifierUn adicional («Leche de almendras») o una opción («Tamaño: Grande») de su padre.El adicional, su precio; la opción, 0.
comboUn combo vendido. Su product_id es el del combo.El precio del combo entero.
combo_componentLo que trajo el combo, colgando de él.0 (la plata está en el combo).
  • external_code es el código externo vigente del producto, leído al armar la respuesta: si lo cambiás después, las ventas viejas muestran el nuevo. Pero cambiarlo no mueve el updated_at de las ventas: las que ya sincronizaste se quedan con el código de antes. Para cruzar, usá product_id contra /products (ahí sí se mueve updated_at cuando cambia el código).
  • modifier_id sale del nombre del adicional u opción: es el mismo en toda la cadena y cambia si el local lo renombra. En la v1 no hay un catálogo de modificadores: los conocés por las ventas.
  • Un renglón anulado sale aparte con voided: true, cuándo y por qué. Si de 3 cafés se anularon 2, hay un renglón vivo con 1 y uno anulado con 2.
  • quantity tiene hasta 3 decimales; en lo que se vende al peso, unit es kg. Lo que se vende por litro también sale con kg en la v1: el número son litros.
  • Cada renglón cumple line_total = unit_price × quantity − discount. Los centavos que no cierran (un precio que no da justo en centavos, lo pesado) van en el descuento del último renglón y, en la venta, como un descuento other llamado «Redondeo» (de pocos centavos, puede ser negativo). Un descuento sin rótulo sale como other «Ajuste».
  • En los descuentos, benefit es el premio del programa de puntos (Kickets) y company el de una empresa, también el que se da por el dominio del mail.
  • Un combo anulado entero sale como combo anulado en $0, con su valor en los componentes anulados (al revés que un combo vivo): así lo anulado nunca se cuenta dos veces.
  • combo_name dice de qué combo salió un renglón, también en ventas viejas, de antes de que existiera el árbol, donde los componentes vienen como product sueltos.
Los renglones de la venta de ejemplo
[
  {
    "object": "sale_item",
    "sale_id": "6720a3f1c9e2b4d7a1f3e8c2",
    "parent_item_id": null,
    "product_id": "66b2e47a91c3d05f8e2a4b61",
    "external_code": "CAF-010",
    "modifier_id": null,
    "combo_name": null,
    "quantity": 1,
    "unit": "unit",
    "unit_price": 2800,
    "discount": 280,
    "line_total": 2520,
    "voided": false,
    "voided_at": null,
    "void_reason": null,
    "id": "6720a3f1c9e2b4d7a1f3e8c3",
    "kind": "product",
    "name": "Café con leche"
  },
  {
    "object": "sale_item",
    "sale_id": "6720a3f1c9e2b4d7a1f3e8c2",
    "parent_item_id": "6720a3f1c9e2b4d7a1f3e8c3",
    "product_id": null,
    "external_code": null,
    "modifier_id": "a3f9c2e1b7d04",
    "combo_name": null,
    "quantity": 1,
    "unit": "unit",
    "unit_price": 600,
    "discount": 60,
    "line_total": 540,
    "voided": false,
    "voided_at": null,
    "void_reason": null,
    "id": "6720a3f1c9e2b4d7a1f3e8c3:m:a3f9c2e1b7d04",
    "kind": "modifier",
    "name": "Leche de almendras"
  },
  {
    "object": "sale_item",
    "sale_id": "6720a3f1c9e2b4d7a1f3e8c2",
    "parent_item_id": "6720a3f1c9e2b4d7a1f3e8c3",
    "product_id": null,
    "external_code": null,
    "modifier_id": "o5e1d7c3a9b20",
    "combo_name": null,
    "quantity": 1,
    "unit": "unit",
    "unit_price": 0,
    "discount": 0,
    "line_total": 0,
    "voided": false,
    "voided_at": null,
    "void_reason": null,
    "id": "6720a3f1c9e2b4d7a1f3e8c3:m:o5e1d7c3a9b20",
    "kind": "modifier",
    "name": "Tamaño: Grande"
  },
  {
    "object": "sale_item",
    "sale_id": "6720a3f1c9e2b4d7a1f3e8c2",
    "parent_item_id": null,
    "product_id": "66b2e47a91c3d05f8e2a4b70",
    "external_code": "CMB-002",
    "modifier_id": null,
    "combo_name": "Desayuno clásico",
    "quantity": 1,
    "unit": "unit",
    "unit_price": 7500,
    "discount": 750,
    "line_total": 6750,
    "voided": false,
    "voided_at": null,
    "void_reason": null,
    "id": "6720a3f1c9e2b4d7a1f3e8d0",
    "kind": "combo",
    "name": "Desayuno clásico"
  },
  {
    "object": "sale_item",
    "sale_id": "6720a3f1c9e2b4d7a1f3e8c2",
    "parent_item_id": "6720a3f1c9e2b4d7a1f3e8d0",
    "product_id": "66b2e47a91c3d05f8e2a4b62",
    "external_code": "PAN-003",
    "modifier_id": null,
    "combo_name": "Desayuno clásico",
    "quantity": 1,
    "unit": "unit",
    "unit_price": 0,
    "discount": 0,
    "line_total": 0,
    "voided": false,
    "voided_at": null,
    "void_reason": null,
    "id": "6720a3f1c9e2b4d7a1f3e8c4",
    "kind": "combo_component",
    "name": "Medialunas (3)"
  },
  {
    "object": "sale_item",
    "sale_id": "6720a3f1c9e2b4d7a1f3e8c2",
    "parent_item_id": "6720a3f1c9e2b4d7a1f3e8d0",
    "product_id": "66b2e47a91c3d05f8e2a4b63",
    "external_code": "BEB-021",
    "modifier_id": null,
    "combo_name": "Desayuno clásico",
    "quantity": 1,
    "unit": "unit",
    "unit_price": 0,
    "discount": 0,
    "line_total": 0,
    "voided": false,
    "voided_at": null,
    "void_reason": null,
    "id": "6720a3f1c9e2b4d7a1f3e8c5",
    "kind": "combo_component",
    "name": "Jugo de naranja"
  },
  {
    "object": "sale_item",
    "sale_id": "6720a3f1c9e2b4d7a1f3e8c2",
    "parent_item_id": null,
    "product_id": "66b2e47a91c3d05f8e2a4b64",
    "external_code": "COC-104",
    "modifier_id": null,
    "combo_name": null,
    "quantity": 1,
    "unit": "unit",
    "unit_price": 4500,
    "discount": 0,
    "line_total": 4500,
    "voided": true,
    "voided_at": "2026-10-27T09:31:12.045-03:00",
    "void_reason": "Lo pidió por error",
    "id": "6720a3f1c9e2b4d7a1f3e8c6:v1",
    "kind": "product",
    "name": "Tostado de jamón y queso"
  }
]

Productos de la cadena

/products trae una fila por sucursal: el «Café con leche» de una cadena de siete locales son siete productos, cada uno con su product_id, su precio y su estado. chain_product_id los junta: es el mismo en las copias que la casa matriz vinculó: las que nacen del alta de la cadena y las que se juntan en Cadena → «Vínculos entre sucursales» (el código externo no las vincula).

  • Para «el producto de la cadena», agrupá por chain_product_id; si viene null, el producto no está vinculado: usá su id.
  • La disponibilidad es por fila: status y active de la copia de cada sucursal.
  • barcode es el código de barras del producto (el que lee el lector de la caja): único por sucursal y null si no tiene. No es el external_code, que es el código de tu sistema.
  • Los renglones de las ventas traen el product_id de la copia de la sucursal: para sumar por producto de la cadena, cruzalo contra /products.

Los pagos

Los pagos de una venta suman su total. Además de la plata que entró, hay créditos que cubren una parte; los distingue kind:

kindQué es
paymentPlata que entró, con un medio de pago.
creditCrédito de una empresa (beneficio corporativo).
on_accountCuenta corriente: se fió, no entró plata todavía.
depositLa seña de una reserva.
ticket_creditEl crédito de consumo que traía una entrada.
table_creditEl crédito de una mesa VIP.
  • method_id es la clave estable del medio (la lista de abajo) y method_type su familia: cash, debit, credit, transfer, qr, wallet u other.
  • amount es la parte del total que cubre; charged_amount, lo que de verdad se cobró con ese medio (en lo online, con servicio, propina y envío; en la caja y la mesa, la parte que se cargó, sin la propina; null en los créditos).
  • Los pagos de una venta son un conjunto: cuando cambia el updated_at de la venta, reemplazalos todos. Si se corrige el reparto, un pago puede cambiar de id.
  • Una devolución sale del pago por cuyo medio volvió la plata: si una venta pagada con efectivo y débito devuelve una parte en efectivo, sólo el pago en efectivo queda partially_refunded. charged_amount es lo que se cobró con ese medio, refunded_amount lo que volvió y amount lo que quedó de la venta en ese medio.
  • En una venta CANCELED los pagos salen approved si la plata quedó en la caja, y canceled si nunca se cobró (una venta duplicada o cargada por error): ahí ningún pago suma.

Los medios de pago

method_idNombretype
cashEfectivocash
card_debitTarjeta débitodebit
card_creditTarjeta créditocredit
card_prepaidTarjeta prepagadebit
cardTarjetaother
mercadopagoMercadoPagowallet
transferTransferenciatransfer
mercadopago_qrQR Mercado Pagoqr
nave_qrQR Naveqr
modo_qrQR MODOqr
other_qrQR de otro procesadorqr
qrQRqr
mp_pointMercadoPago Pointother
nave_pointTerminal Naveother
getnet_pointTerminal Getnetother
cloverTerminal Cloverother
online_mercadopagoOnline · Mercado Pagoother
online_naveOnline · Naveother
online_getnetOnline · Getnetother
online_stripeOnline · Stripeother
online_dlocalgoOnline · dLocal Goother
online_mobbexOnline · Mobbexother
online_fiservOnline · Fiservother
online_paywayOnline · Paywayother
online_modoOnline · MODOother
online_pvsOnline · PVSother
delivery_pedidosyaPedidosYaother
delivery_rappiRappiother
delivery_ubereatsUber Eatsother
deliveryAplicación de deliveryother
on_accountCuenta corrienteother
corporate_creditCrédito corporativoother
reservation_depositSeña de reserva (online)other
ticket_creditCrédito de la entradaother
table_creditCrédito de la mesaother
otherOtroother

GET /payment-methods dice en qué sucursales está habilitado cada uno.

Los ids

Casi todos son el id de Kicket: 24 caracteres hexadecimales, únicos en toda la plataforma. Algunos objetos no tienen un id propio en Kicket y la API les arma uno estable:

QuéFormaEjemplo
Clientecus_ + 24 hexcus_8f2a1c9d0e7b4a65c3d1e2f0
Persona del equipostf_ + 24 hexstf_1b9e5c2a7d4f8e03a6c2b9d1
Combo vendido (renglón)El id de esa instancia del combo6720a3f1c9e2b4d7a1f3e8d0
Adicional u opción<renglón>:m:<token>6720a3f1c9e2b4d7a1f3e8c3:m:a3f9c2e1b7d04
Renglón anulado<renglón>:v<n>6720a3f1c9e2b4d7a1f3e8c6:v1
Pago sin id propio (ventas viejas, el cobro online)<venta>:p<n>6720a3f1c9e2b4d7a1f3e8c2:p0
Pago con un crédito<venta>:<kind>6720a3f1c9e2b4d7a1f3e8c2:ticket_credit
Renglón de delivery sin producto vinculado (product_id null)<venta>:u<n>6720a3f1c9e2b4d7a1f3e8c2:u0
Cobro sin detalle de productos, o una diferencia que ningún renglón explica<venta>:sin-detalle6720a3f1c9e2b4d7a1f3e8c2:sin-detalle
Medio de pagoUna clavecard_debit
Tratá todos los ids como texto opaco: no los partas ni dependas de su forma.

Qué queda afuera

  • El consumo que viene incluido con una entrada y los vales de regalo: su plata está en la entrada, y Analítica tampoco los cuenta como ventas.
  • Los checkouts que nadie pagó (un link de cobro sin pagar). Cuando se pagan, aparecen.
  • Las cajas abiertas: sólo se exponen cerradas.
  • Las sucursales que dejaron de ser parte de la cadena.
  • Mails del equipo, notas internas y datos de pagadores: nunca salen.

Lo que la v1 no tiene (y por qué)

DatoEn la v1
El IVA por venta o renglónNo hay IVA por producto: sólo existe en la factura de ARCA. total es con IVA.
«Para llevar»No se distingue: sale como counter u online.
La propina por pagoSólo por venta (tip_total). En la caja y la mesa ningún pago la trae; en lo online viene dentro de charged_amount.
Precio de lista contra precio con promociónunit_price ya trae la promoción aplicada.
Listas de preciosprice del producto es el de la carta.
El DNI del clienteNo sale.
Lo contado por medio en el arqueoSólo el efectivo contado (counted_cash).
El cliente de una mesa por QRSu customer_id suele venir null: la mesa no pide datos.
Subcategorías, entradas y eventosNo están en la v1.

Desde cuándo vale cada dato de la historia

La carga inicial puede traer años de ventas, pero algunos datos se empezaron a guardar hace poco. Antes de esa fecha no es que no pasó: no se guardaba.

DatoDesdeAntes
Renglones anulados (voided)28-oct-2026Lo anulado no aparece.
Id propio de cada pago dividido28-oct-2026<venta>:p<n>
Dos combos iguales en una venta, como dos renglones28-oct-2026Un solo renglón con cantidad 2.
covers28-oct-2026null
closed_at de una venta del mostrador28-oct-2026Igual a opened_at (el alta).
closed_by de una caja24-sep-2026null

Algunos nombres, para no confundirse

  • method_type del pago es lo mismo que type del medio de pago.
  • status de la venta va en MAYÚSCULAS (CLOSED); los demás enumerados, en minúscula.
  • Un combo es un product con type: combo; is_combo dice lo mismo.
  • expected de una caja es lo vendido por medio, no lo esperado en el cajón (eso es counted_cash − cash_difference).
  • Lo que se vende por litro sale con unit: kg y el número son litros.

Clientes

Un cliente es una persona en toda la cuenta: el mismo cus_… en todas las sucursales. Se identifica por su teléfono (en E.164) o, si no dejó, por su mail. La venta trae customer_id (o null si fue anónima); el cliente completo pide customers:read. El id es opaco: con él no se puede recuperar el teléfono ni el mail. Ver la referencia.

  • Si alguien dejó primero sólo el mail y después el teléfono, son dos clientes en la v1: unirlos le cambiaría el id a uno que ya sincronizaste.
  • updated_at se mueve sólo cuando cambian sus datos (nombre, teléfono, mail, una sucursal nueva), no con cada compra: last_purchase_at cambia sin moverlo.
  • GET /customers?phone=… y ?email=… llevan el dato personal en la URL: no dejes esas URLs en logs que vea cualquiera. Lo que escribe el personal en el motivo de una anulación (void_reason) sale con los mails y teléfonos tapados.
  • Los clientes los arma Kicket cada minuto: el customer_id de una venta recién cobrada puede llegar uno o dos minutos antes que el cliente a /customers (mientras tanto, su GET da 404 e include=customer no lo trae).
AnteriorConciliaciónSiguienteReferencia