Convenciones del contrato
Formatos, nombres, fechas, dinero y cabeceras: lo que se repite en todas las respuestas y no vuelve a explicarse en cada endpoint.
Última actualización: 23 de agosto de 2026
Todo lo de esta página vale para cualquier endpoint de /api/v1. Léela una vez y no tendrás que volver.
Nombres y formatos
| Aspecto | Convención | Ejemplo |
|---|---|---|
| Idioma | Inglés en rutas, campos y valores | ticketType, boxOffice |
| Campos JSON | camelCase | ticketTypeId, checkedInAt |
| Segmentos de ruta | kebab-case | /check-in, /payment-link |
| Códigos de error | snake_case | invalid_input |
| Identificadores | Cadena opaca de 24 caracteres | 6a42356a296cb2dfe6ba1c7f |
Los identificadores son opacos: trátalos como cadenas y no supongas nada de su forma. Compáralos con === y guárdalos tal cual.
Fechas
Siempre ISO 8601 en UTC, con milisegundos y la Z final:
2026-08-23T20:00:00.000Z
Todas, sin excepción, tanto las que devuelve la API como las que le mandas en un filtro. La hora local es cosa de tu interfaz.
La zona horaria de cada sala viaja en el campo timezone de GET /venues (Europe/Madrid, por ejemplo). Úsala para formatear: una función que empieza a las 22:00 en Madrid es 2026-09-12T20:00:00.000Z en verano y 2026-09-12T21:00:00.000Z en invierno, y mostrar la hora equivocada en un cartel es un problema real.
Dinero
Todos los importes son un objeto con un entero de céntimos y su divisa:
{ "amount": 1250, "currency": "EUR" }
1250 son 12,50 €. Nunca verás un decimal en un importe.
Por qué. En coma flotante, 12,50 € no se representa de forma exacta. Sumas cien líneas de pedido y el total te sale con un céntimo de deriva, que en una recaudación que hay que cuadrar con el banco es exactamente el tipo de error que cuesta una tarde. Es la misma convención que usa Stripe, y por la misma razón.
Para mostrarlo:
function formatear(m: { amount: number; currency: string }, locale = 'es-ES') {
return new Intl.NumberFormat(locale, { style: 'currency', currency: m.currency })
.format(m.amount / 100)
}
// → "12,50 €"
Divide por 100 al pintar, nunca antes. Si operas en euros decimales y luego vuelves a céntimos, ya has perdido la exactitud que esto protege.
Cabeceras de respuesta
Toda respuesta, correcta o no, lleva estas:
| Cabecera | Qué es |
|---|---|
X-Request-Id | Identificador de la petición |
RateLimit-Limit | Tu tope de peticiones por minuto |
RateLimit-Remaining | Cuántas te quedan en la ventana actual |
RateLimit-Reset | Segundos hasta que se reinicie el contador |
Cache-Control | Siempre private, no-store |
En un 429 se añade además Retry-After con los segundos que hay que esperar.
X-Request-Id
X-Request-Id es lo primero que te vamos a pedir en un ticket de soporte. Con él encontramos tu petición exacta en nuestros logs en segundos; sin él, hay que adivinar a partir de la hora y el endpoint.
Puedes mandar el tuyo y lo respetamos, lo cual es cómodo si ya tienes trazas propias:
X-Request-Id: mi-traza-8f3a2b
Lo saneamos —solo letras, números, punto, guion y guion bajo, hasta 64 caracteres— y lo devolvemos. Si no lo mandas, lo generamos nosotros.
Cache-Control
Las respuestas son private, no-store siempre. Llevan datos de tus compradores y no deben acabar en una caché compartida ni en un CDN. Si necesitas cachear catálogo para tu web, cachéalo tú, en tu backend, con la política que decidas.
Métodos y cuerpos
- Los
GETno llevan cuerpo. Todo va en la query string. - Los
POSTllevan JSON y necesitanContent-Type: application/json. - Un cuerpo vacío en un
POSTque solo tiene campos opcionales es válido. - No hay
PATCH,PUTniDELETE: la API no edita ni borra recursos, solo lee y hace transiciones de estado a través de acciones con nombre (/confirm,/cancel,/check-in).
Vocabulario
El producto está en español y la API en inglés. Esta es la equivalencia completa, por si tienes que leer las dos cosas a la vez.
| Panel (español) | API (inglés) |
|---|---|
| sala | venue |
| evento | event |
| sesión / función | performance |
| tarifa / tipo de entrada | ticketType |
| abono | pass (scope: "pass") |
| entrada | ticket |
| pedido | order |
| asistente | attendee |
| taquilla | boxOffice |
| gastos de gestión | serviceFee |
| validar en puerta | checkIn |
| zona de aforo | zone |
Valores de enum
| Panel | API |
|---|---|
| pendiente / pagado / cancelado / error / reembolsado | pending / paid / cancelled / failed / refunded |
| válida / usada / anulada | valid / used / void |
| borrador / publicado | draft / published |
| activo / cancelado (sesión) | active / cancelled |
| activa / agotada / oculta (tarifa) | active / soldOut / hidden |
| online / taquilla / ambos | online / boxOffice / both |
| efectivo / TPV | cash / cardTerminal |
| simple / multisesión / recurrente | single / multiPerformance / recurring |
| DNI / NIE / pasaporte / otro | dni / nie / passport / other |
En cualquier SDK, Session ya significa «sesión de autenticación». La ambigüedad se paga en cada línea de documentación y en cada nombre de variable, así que la sesión de un evento es una performance.
Estabilidad del contrato
Dentro de /v1:
- No se quitan campos ni se renombran.
- No se cambia el tipo de un campo existente.
- No se retiran valores de un enum.
Lo que sí puede pasar sin aviso, y contra lo que tu código tiene que estar preparado:
- Aparecen campos nuevos en los objetos. Ignora los que no conozcas en vez de fallar al deserializar.
- Aparecen valores nuevos en un enum. Ten siempre una rama por defecto en tus
switch. - Cambia el contenido del cursor de paginación. Es opaco por contrato: devuélvelo tal cual, no lo desmontes.
Si algún día hubiera un cambio incompatible, sería una /v2 conviviendo con esta, y te avisaríamos con plazo.
Seguir por aquí
Todos los códigos que devuelve la API, qué significa cada uno y cuáles tiene sentido reintentar.
Todos los objetos que devuelve la API, campo a campo, con sus tipos y sus valores posibles.
Acceso programático a tu catálogo, tus ventas y tus entradas. Qué puedes construir, qué no concede nunca una clave y cómo está organizada esta referencia.