Listar los turnos cerrados de una tienda
GET /stores/{storeKey}/shifts
Devuelve los turnos de caja de la tienda que se cerraron dentro del rango de fechas, según su fecha de cierre (closes_at). No incluye los turnos de cajas eliminadas. Los resultados van ordenados por fecha de cierre y luego por identificador, y la respuesta está paginada.
Cada elemento de data tiene la misma estructura que el data del evento Cierre de turno (shift.closed). Sus campos están descritos en Cierre de turno. Los valores reflejan el estado del turno en el momento de la consulta; el webhook trae el estado en el momento del evento.
Las fechas son días calendario de la zona horaria America/Lima, con ambos extremos incluidos. El rango no puede superar 31 días.
Authorizations
Sección titulada «Authorizations »Parameters
Sección titulada « Parameters »Path Parameters
Sección titulada «Path Parameters »Identificador (UUID) de la tienda.
Example
2b7d9e40-c1a3-4f58-8e06-5a4d3c7b9f12Query Parameters
Sección titulada «Query Parameters »Primer día del rango, en formato AAAA-MM-DD. Es un día calendario de la zona horaria America/Lima y se incluye en el rango.
Example
2026-10-12Último día del rango, en formato AAAA-MM-DD. Es un día calendario de la zona horaria America/Lima y se incluye en el rango. Debe ser igual o posterior a date_from y no distar de ella más de 30 días, es decir, el rango no puede superar 31 días.
Example
2026-10-12Cantidad de registros por página. Por defecto 15.
Example
15Número de página, empezando en 1. Por defecto 1.
Example
1Responses
Sección titulada « Responses »Una página de los turnos de caja cerrados dentro del rango de fechas, cada uno con la cantidad de ventas y el total cobrado por medio de pago y moneda. Sirve para cuadrar el cierre de caja con las ventas que registró.
- Van ordenados por
closes_aty luego porid. Los registros llegan endata, los enlaces de navegación enlinksy los totales enmeta. - Un rango sin turnos cerrados responde
200condatavacío. - Cada elemento tiene la misma estructura que el
datade Cierre de turno, pero con el estado del turno al consultar, no al momento del evento. summary.paymentstrae una fila por medio de pago y moneda.amountes neto del vuelto y puede ser negativo;tipson las propinas. Ambos son cadenas de texto.opens_atycloses_atestán en UTC.closed_bypuede sernull.
object
Turnos cerrados de esta página, ordenados por closes_at y luego por id.
Turno de caja cerrado. Tiene la misma estructura que data del evento Cierre de turno (shift.closed). Los valores reflejan el estado del turno en el momento de la consulta.
object
Identificador del turno.
Número del turno. Es único por caja y es el que se imprime en el ticket de cierre.
Tienda de la caja. Si la caja fue eliminada, todos sus campos son null.
object
Identificador de la tienda.
Nombre de la tienda.
Código externo de la tienda.
Caja que cerró el turno. Si la caja fue eliminada, sus campos son null.
object
Identificador de la caja.
Nombre de la caja.
Fecha y hora de apertura del turno, en UTC.
Fecha y hora de cierre del turno, en UTC.
Resumen de lo cobrado en el turno.
object
Cantidad de órdenes distintas con al menos un pago aprobado de la caja entre opens_at y closes_at, ambos incluidos. No cuenta adelantos.
Total cobrado, con una fila por medio de pago y moneda. Ordenado por currency, luego por method_name y luego por method_id.
Total cobrado en un medio de pago y una moneda.
object
Identificador del medio de pago.
Nombre del medio de pago.
Moneda, por ejemplo PEN o USD.
Monto cobrado neto del vuelto entregado: monto recibido menos vuelto. Puede ser negativo. No incluye propinas ni adelantos. string (2 dec).
Propinas de ese medio de pago y moneda. string (2 dec).
Enlaces de la paginación. Conservan los parámetros de consulta de la petición.
object
URL de la primera página.
URL de la última página.
URL de la página anterior. Es null en la primera página.
URL de la página siguiente. Es null en la última página.
Información de la paginación.
object
Número de la página actual.
Posición del primer registro de la página dentro del total. Es null si no hay registros.
Número de la última página.
Enlaces para armar un paginador.
object
URL de la página. Es null cuando no hay página anterior o siguiente.
Texto del enlace.
true en la página actual.
URL de la operación, sin parámetros de consulta.
Cantidad de registros por página.
Posición del último registro de la página dentro del total. Es null si no hay registros.
Cantidad total de registros.
Examples
Un día con un turno cerrado
{ "data": [ { "id": "7b9d1f3a-5c7e-4a2b-8d4f-6e8a0c2b4d71", "correlative": 128, "store": { "id": "6a8c0e2f-5b7d-4d9b-9e3a-4f6b8d0c2e53", "name": "Tienda Centro", "external_id": "T01" }, "cashier": { "id": "9d2f4b6c-8e0a-4c3b-9d5f-7a1b3c5e7f82", "name": "Caja 1" }, "opens_at": "2026-10-12T13:00:00Z", "closes_at": "2026-10-12T23:04:58Z", "closed_by": { "id": "8c1e3a5b-7d9f-4b2a-8c4e-6f0a2b4d6e71", "name": "Ana Torres" }, "summary": { "sales_count": 42, "payments": [ { "method_id": "2a4c6e8b-0d2f-4b6a-9c1e-3f5a7b9d1c04", "method_name": "Efectivo", "currency": "PEN", "amount": "1250.40", "tip": "15.00" }, { "method_id": "1b3d5f7a-9c2e-4d6b-8f1a-3c5e7a9b2d93", "method_name": "Visa", "currency": "PEN", "amount": "2380.00", "tip": "95.50" }, { "method_id": "2a4c6e8b-0d2f-4b6a-9c1e-3f5a7b9d1c04", "method_name": "Efectivo", "currency": "USD", "amount": "60.00", "tip": "0.00" } ] } } ], "links": { "first": "https://host-proporcionado-por-idbi/api/open/v1/stores/6a8c0e2f-5b7d-4d9b-9e3a-4f6b8d0c2e53/shifts?date_from=2026-10-12&date_to=2026-10-12&page=1", "last": "https://host-proporcionado-por-idbi/api/open/v1/stores/6a8c0e2f-5b7d-4d9b-9e3a-4f6b8d0c2e53/shifts?date_from=2026-10-12&date_to=2026-10-12&page=1", "prev": null, "next": null }, "meta": { "current_page": 1, "from": 1, "last_page": 1, "links": [ { "url": null, "label": "« Anterior", "active": false }, { "url": "https://host-proporcionado-por-idbi/api/open/v1/stores/6a8c0e2f-5b7d-4d9b-9e3a-4f6b8d0c2e53/shifts?date_from=2026-10-12&date_to=2026-10-12&page=1", "label": "1", "active": true }, { "url": null, "label": "Siguiente »", "active": false } ], "path": "https://host-proporcionado-por-idbi/api/open/v1/stores/6a8c0e2f-5b7d-4d9b-9e3a-4f6b8d0c2e53/shifts", "per_page": 15, "to": 1, "total": 1 }}Credenciales ausentes, inválidas, deshabilitadas o vencidas. El campo error.description indica el motivo.
Formato de error de la autenticación y del control de acceso del token.
object
Detalle del error, con su código, su mensaje y su descripción.
object
Siempre es 0.
Mensaje del error.
Detalle del error, cuando existe.
Examples
Falta una de las cabeceras
{ "error": { "code": 0, "message": "No autorizado", "description": "El token es obligatorio" }}Token que no corresponde a la clave
{ "error": { "code": 0, "message": "No autorizado", "description": "El token es inválido" }}Clave inexistente
{ "error": { "code": 0, "message": "No autorizado", "description": "El token no fue encontrado" }}Token deshabilitado
{ "error": { "code": 0, "message": "No autorizado", "description": "El token está deshabilitado" }}Token vencido
{ "error": { "code": 0, "message": "No autorizado", "description": "El token expiró" }}La tienda indicada en la ruta no pertenece al token. La respuesta es la misma para una tienda ajena y para una tienda inexistente.
Formato de error de la autenticación y del control de acceso del token.
object
Detalle del error, con su código, su mensaje y su descripción.
object
Siempre es 0.
Mensaje del error.
Detalle del error, cuando existe.
Examples
{ "error": { "code": 0, "message": "Acceso denegado", "description": "El token no tiene acceso a la tienda solicitada" }}Algún parámetro de consulta no es válido. Los mensajes de errors están en español y se agrupan por nombre de campo.
Formato de error cuando los datos enviados no superan la validación.
object
Mensaje general de validación.
Mensajes de error agrupados por nombre de campo.
object
Examples
Faltan las fechas
{ "message": "Uno o más de los datos que has ingresado no cumplen con los requisitos mínimos.", "errors": { "date_from": [ "El campo date_from es obligatorio." ], "date_to": [ "El campo date_to es obligatorio." ] }}Fecha con formato incorrecto
{ "message": "Uno o más de los datos que has ingresado no cumplen con los requisitos mínimos.", "errors": { "date_from": [ "El campo date_from no corresponde con el formato de fecha Y-m-d." ] }}date_to anterior a date_from
{ "message": "Uno o más de los datos que has ingresado no cumplen con los requisitos mínimos.", "errors": { "date_to": [ "El campo date_to debe ser una fecha posterior o igual a date_from." ] }}Rango de más de 31 días
{ "message": "Uno o más de los datos que has ingresado no cumplen con los requisitos mínimos.", "errors": { "date_to": [ "El campo date_to debe ser una fecha anterior o igual a 2026-11-11." ] }}paginate fuera de rango
{ "message": "Uno o más de los datos que has ingresado no cumplen con los requisitos mínimos.", "errors": { "paginate": [ "El campo paginate no debe ser mayor a 100." ] }}