Centro de Ayuda de Dardo

Operaciones y eventos

Leer el historial de transacciones: qué eventos existen, qué campos trae cada operación y cómo filtrarlos

Todo lo que pasa con una tarjeta queda registrado como una operación: un sello acreditado, una visita, un canje, una instalación. GET /api/v2/operations es el endpoint que te devuelve ese historial, y es el que vas a usar para conciliar tu sistema con Dardo.

curl "https://api.dardo.ai/api/v2/operations?itemsPerPage=100" \
  -H "X-API-Key: TU_CLAVE_API"

Filtros disponibles

ParámetroTipoPara qué
templateIdintegerOperaciones de una plantilla de tarjeta puntual
customerIduuidTodo el historial de un cliente
cardIdstringHistorial de una tarjeta, por su número de serie
startDatefechaDesde cuándo
endDatefechaHasta cuándo
pageintegerPágina. Default 1, mínimo 1
itemsPerPageintegerDefault 30, rango 11000

Traer el último mes de un cliente:

curl "https://api.dardo.ai/api/v2/operations?customerId=UUID_DEL_CLIENTE&startDate=2026-08-01&endDate=2026-08-31" \
  -H "X-API-Key: TU_CLAVE_API"

El catálogo de eventos

Cada operación trae dos campos que dicen qué pasó: eventId (número) y eventName (texto).

eventIdeventNameQué pasó
1Stamps earnedSe acreditaron sellos
2Rewards redeemedEl cliente canjeó un premio
3Rewards earnedEl cliente alcanzó un premio y quedó disponible para canjear
5Card installedEl cliente instaló la tarjeta en su teléfono
6Card deleted from deviceEl cliente borró la tarjeta de su teléfono
16Feedback sentEl cliente dejó una opinión
24Points earnedSe acreditaron puntos
29Shared cardEl cliente compartió su tarjeta
42Visit loggedSe registró una visita

Esta tabla son los eventos observados en cuentas reales, no una lista cerrada publicada por la API. Un programa que use mecánicas distintas puede registrar eventos que no están acá. Si te aparece un eventId que no figura, escribinos a soporte@dardo.ai con el número y lo sumamos.

Ramificá por eventId, no por eventName

Dos de los eventName llegan con un espacio al final: "Stamps earned " y "Rewards redeemed ". Son, justamente, los dos eventos centrales de un programa de lealtad.

op.eventName === "Stamps earned"   // false, aunque el evento SEA ese
op.eventId === 1                   // correcto

Una comparación por igualdad contra el texto falla en silencio: no tira error, simplemente no entra nunca en ese if. Es de los errores más caros de encontrar porque todo parece funcionar.

eventId es numérico y estable. Usalo para la lógica, y dejá eventName para mostrar en pantalla o loguear. Si por lo que sea necesitás comparar el texto, aplicale .trim() primero.

Los campos de una operación

CampoTipoQué es
idintegerIdentificador de la operación
companyIdintegerLa cuenta
templateIdintegerLa plantilla de tarjeta
customerIduuidEl cliente
customerobjetoDatos del cliente, embebidos. Incluye sus segments
cardIdstringNúmero de serie de la tarjeta
cardDevicestringDónde tiene instalada la tarjeta: Apple Wallet, Google Pay, PWA
eventIdintegerQué pasó. Ramificá por acá
eventNamestringDescripción del evento, para mostrar
managerIdinteger | nullQué persona del equipo la registró
locationIdinteger | nullEn qué sucursal
amountnumberLa magnitud del evento: cuántos sellos, cuántos puntos
purchaseSumnumberEl monto de la compra asociada
balancenumberSaldo de la tarjeta después de la operación
sourcestringPor dónde entró la operación
commentstring | nullNota libre, si la operación la incluyó
createdAtstringFecha y hora, ISO 8601 con offset
updatedAtstringÚltima modificación

amount y purchaseSum son cosas distintas

amount es la magnitud del evento: si se acreditaron 2 sellos, es 2. purchaseSum es la plata de la compra que originó esa acreditación.

Una venta de $36.900 que otorga un sello se registra con amount: 1 y purchaseSum: 36900. Para facturación o conciliación querés purchaseSum; para saber cuántos sellos se movieron, amount.

purchaseSum se expresa en unidades de la moneda de la cuenta, no en centavos. Esto es distinto del objeto Check de Punto de venta, donde los montos van en centavos. Si tu integración usa las dos cosas, no mezcles las unidades.

source: por dónde entró la operación

ValorOrigen
scannerLa app de escáner, en el mostrador
apiUn llamado a la API — acá es donde va a aparecer tu integración
workflowUna automatización
autoEl sistema, sin intervención
webappEl panel web
""Sin origen registrado. Es un valor posible: contemplá la cadena vacía

Filtrar por source del lado del cliente es la forma de separar lo que registró tu integración de lo que hizo el personal en el local.

managerId y locationId vienen vacíos seguido

Los dos son null en la mayoría de las operaciones: solo se completan cuando la operación la registró una persona del equipo desde una sucursal. Una acreditación hecha por API no los trae.

Si necesitás saber en qué sucursal ocurrió una venta que cargás vos, leé la advertencia sobre sucursales en Punto de venta.

Para resolver el nombre de una sucursal a partir de su locationId, cruzá contra Ubicaciones.

Paginar el historial

La respuesta trae un meta con el total:

{
  "data": [ ... ],
  "meta": { "totalItems": 36012, "itemsPerPage": 100, "currentPage": 1 }
}

No hay totalPages ni hasMore: se calculan.

const ultimaPagina = Math.ceil(meta.totalItems / meta.itemsPerPage);

Un historial grande se pagina en muchos pedidos, y mientras los recorrés pueden entrar operaciones nuevas que corren las filas. Para conciliar, acotá siempre con startDate y endDate sobre un período ya cerrado en vez de recorrer el historial completo. Más detalle en Límites y paginación.

On this page