Comparar y exportar
Comparar códigos
GET /v1/analytics/compare recibe codeIds (hasta 4, separados por comas) y los habituales range, tz y groupBy. La respuesta trae una serie por código sobre los mismos intervalos: sus puntos, sus totales, el periodo anterior de la misma duración, el cambio respecto a él y la parte que el código se lleva de los escaneos comparados.
Los códigos que la clave no puede ver vuelven en omitted en lugar de hacer fallar la solicitud. Un código estático aparece con tracked: false y cero puntos, porque sus escaneos no se cuentan.
curl "https://api.dotwick.com/v1/analytics/compare?codeIds=qr_8841ce2mxk%2Cqr_2k8m4q7x1c9v&range=7d&tz=Europe%2FBerlin" \ -H "Authorization: Bearer sk_live_…"{ "groupBy": "day", "tz": "Europe/Berlin", "from": "2026-09-09T00:00:00+02:00", "to": "2026-09-12T00:00:00+02:00", "previous": { "from": "2026-09-06T00:00:00+02:00", "to": "2026-09-09T00:00:00+02:00" }, "buckets": [ "2026-09-09T00:00:00+02:00", "2026-09-10T00:00:00+02:00", "2026-09-11T00:00:00+02:00" ], "series": [ { "codeId": "qr_8841ce2mxk", "name": "Van fleet – unit 14", "tracked": true, "points": [ { "ts": "2026-09-09T00:00:00+02:00", "scans": 40, "uniques": 31 }, { "ts": "2026-09-10T00:00:00+02:00", "scans": 52, "uniques": 44 }, { "ts": "2026-09-11T00:00:00+02:00", "scans": 58, "uniques": 47 } ], "totals": { "scans": 150, "uniques": 122, "bots": 3 }, "previous": { "scans": 100, "uniques": 80 }, "deltas": { "scans": 0.5, "uniques": 0.525 }, "share": 0.75 }, { "codeId": "qr_2k8m4q7x1c9v", "name": "Van fleet – unit 15", "tracked": true, "points": [ { "ts": "2026-09-09T00:00:00+02:00", "scans": 12, "uniques": 10 }, { "ts": "2026-09-10T00:00:00+02:00", "scans": 20, "uniques": 17 }, { "ts": "2026-09-11T00:00:00+02:00", "scans": 18, "uniques": 15 } ], "totals": { "scans": 50, "uniques": 42, "bots": 0 }, "previous": { "scans": 60, "uniques": 51 }, "deltas": { "scans": -0.167, "uniques": -0.176 }, "share": 0.25 } ], "omitted": []}Descargar escaneos en CSV
GET /v1/analytics/export responde con el propio CSV (text/csv, como archivo adjunto) para los filtros de los demás endpoints de estadísticas: codeId o codeIds, folderId, tagId, gtin, country y un periodo. kind elige el archivo: daily_totals, scan_rows, breakdowns.
daily_totals es una fila por periodo (añade splitByCode=true para una fila por código), scan_rows es una fila por escaneo y breakdowns lista cada fila de las dimensiones que indiques. Los tres necesitan un plan con exportación a CSV; scan_rows necesita además estadísticas por escaneo. Las filas más antiguas que el historial del plan no están en el archivo.
Por encima de 10.000 filas la respuesta es 413 payload_too_large con details.reason use_export_job. Inicia entonces un trabajo de exportación.
Periodos grandes: un trabajo de exportación
POST /v1/analytics/exports recibe los mismos filtros como cuerpo JSON (kind es obligatorio) y prepara el archivo en segundo plano, hasta 1.000.000 filas. Más que eso es 413 con details.reason too_many_rows: acota el periodo. Envía una Idempotency-Key.
La respuesta es 202 con un exportId. Consulta GET /v1/exports/{id} hasta que esté listo y lee de ahí el enlace de descarga. Un correo también anuncia el archivo; envía email: false para omitirlo.
curl -X POST https://api.dotwick.com/v1/analytics/exports \ -H "Authorization: Bearer sk_live_…" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: van-014-scans-q3" \ -d '{ "kind": "scan_rows", "range": "90d", "tz": "Europe/Berlin", "codeIds": [ "qr_8841ce2mxk" ], "email": false }'{ "exportId": "exp_2m7x4k9q1c8v3b6n", "status": "queued"}