Saltar al contenido
Tickeep
Índice de la API

Receta: tu propio control de acceso

Conectar tornos, lectores o el software de puerta que ya tengas con las entradas de Tickeep.

Última actualización: 23 de agosto de 2026

Si ya tienes tornos, lectores o un sistema de puerta, no hace falta que tu equipo cambie de herramienta: la API valida entradas de Tickeep desde el hardware que ya usas.

Lo que necesitas: una clave con tickets:validate —que ya incluye tickets:read—.

Acota la clave a la sala

Un proveedor de control de acceso no necesita ver el resto de tu organización. Emítele una clave limitada a esa sala: fuera de su ámbito, todo responde 404. Si tienes varias puertas, una clave por puesto te deja distinguirlas en la auditoría.

El circuito

GET /tickets?performanceId=…       → el padrón, antes de abrir
POST /tickets/{code}/check-in      → con dryRun: consultar sin consumir
POST /tickets/{code}/check-in      → sin dryRun: la persona pasa

1. Descargar el padrón

Antes de abrir puertas, tráete quién está previsto:

async function padron(performanceId: string) {
  const entradas = []
  let cursor: string | undefined
  do {
    const p = await tickeep.tickets({ performanceId, limit: 100, cursor })
    entradas.push(...p.data)
    cursor = p.nextCursor ?? undefined
  } while (cursor)
  return entradas
}

Sirve para dos cosas: saber cuánta gente esperas y tener una lista contra la que buscar por nombre cuando alguien llega sin el QR.

El padrón no sustituye a la validación

Lo que se descarga es una foto. Entre que la bajas y la puerta abre puede haber ventas nuevas, devoluciones y anulaciones. Validar contra tu copia local marcaría entradas legítimas como desconocidas y dejaría pasar entradas anuladas.

La validación va siempre contra el servidor. El padrón es para consultar, no para decidir.

Refréscalo mientras la puerta está abierta si la venta sigue activa.

2. Validar

const { result, ticket } = await tickeep.checkIn(codigo, { performanceId })

switch (result) {
  case 'valid':             return abrirTorno(ticket)
  case 'alreadyUsed':       return rechazar(`Ya se usó a las ${hora(ticket.checkedInAt)}`)
  case 'void':              return rechazar('Entrada anulada')
  case 'wrongPerformance':  return rechazar('Es de otra fecha del mismo evento')
  case 'wrongEvent':        return rechazar('Es de otro evento')
  case 'invalidToken':      return rechazar('Código no válido')
  case 'notFound':          return rechazar('No existe')
  default:                  return rechazar('Resultado desconocido')
}
El veredicto llega en un 200

/check-in responde 200 siempre. Que una entrada esté repetida o anulada no es un error de tu petición: es el resultado del control.

Eso te deja distinguir dos cosas que si no se confundirían: un result distinto de valid significa «esta persona no pasa», y un error HTTP significa «tu integración está rota». Tu operario de puerta necesita saber cuál de las dos es.

Ese default no es decorativo: pueden aparecer veredictos nuevos, y un lector que se cuelgue ante uno desconocido es peor que uno que lo rechace educadamente.

3. Manda siempre performanceId

Es lo que impide quemar las entradas de mañana

Sin performanceId, la entrada de la función de mañana escaneada hoy se marca como usada. Mañana, cuando esa persona llegue de verdad, recibirá alreadyUsed y tendrás una discusión en la puerta.

Con performanceId, ese mismo escaneo devuelve wrongPerformance y no consume nada.

Es un campo opcional en el contrato porque hay flujos donde no se sabe la fecha —comprobar un código por teléfono, por ejemplo—. En un lector de puerta, mándalo siempre.

4. Tornos: consultar y después abrir

Un torno que enseña la ficha del asistente antes de dejar pasar necesita las dos llamadas:

// El QR pasa por el lector
const previo = await tickeep.checkIn(codigo, { performanceId, dryRun: true })
if (previo.result !== 'valid') return mostrarRechazo(previo.result)

mostrarFicha(previo.ticket)   // nombre, tarifa, zona, consumiciones

// La persona empuja el torno
const definitivo = await tickeep.checkIn(codigo, { performanceId })
if (definitivo.result === 'valid') abrirTorno()

dryRun: true devuelve el veredicto sin consumir la entrada. Ojo con el hueco entre las dos llamadas: si el asistente se da la vuelta después de la consulta, la entrada sigue sin usar. Es correcto —no ha entrado nadie— pero tu interfaz debería dejarlo claro.

5. Varias puertas a la vez

No hace falta coordinarlas. La entrada se consume con una operación atómica: si dos lectores escanean el mismo código en el mismo instante, uno recibe valid y el otro alreadyUsed. Nunca pasan los dos.

Puedes poner cuatro puestos en paralelo sin ningún estado compartido entre ellos.

6. Si se cae la red

Es el escenario que hay que pensar antes, no durante.

No valides en local

La tentación es validar contra el padrón descargado cuando no hay conexión. No lo hagas: no puedes detectar una entrada usada en otra puerta, y una entrada anulada después de la descarga pasaría.

Cuando la red vuelva y sincronices, te encontrarás con entradas que ya estaban usadas y no sabrás cuáles pasaron dos veces.

Lo que sí puedes hacer:

  • Reintentar con cortes cortos. Un timeout de 3 segundos y dos reintentos cubren la mayoría de microcortes sin que el operario note nada.
  • Registrar los códigos que no pudiste validar y procesarlos cuando vuelva la conexión, sabiendo que algunos saldrán alreadyUsed.
  • Usar la app de Tickeep para las puertas sin cobertura. Está hecha para eso: descarga el padrón con las firmas y valida en local, con su propio mecanismo de reconciliación. Ver escanear entradas.

7. Auditoría

Una validación hecha por API queda a nombre de la clave, no de una persona. En el panel se distingue de las que hace tu equipo con la app.

Si necesitas saber qué puerta validó qué, emite una clave por puesto y nómbralas claramente («Puerta principal», «Acceso VIP»). Es la única forma de reconstruirlo después.

Lo que no puedes hacer

  • Generar tus propios QR. La firma que hace válida una entrada no se expone nunca, y ningún endpoint la devuelve. Se distribuyen los PDF y los QR que emite Tickeep.
  • Deshacer un check-in. Si alguien se equivoca en la puerta, se corrige desde el panel.
  • Anular una entrada. Desde el panel, o devolviendo el pedido.
  • Consumir las consumiciones incluidas. El campo includes ya viene con su contador used, pero el consumo todavía no está expuesto por API.

Antes de la primera noche

Prueba los siete veredictos

Incluidos wrongPerformance y void. El día del concierto no es el momento de descubrir que tu pantalla no sabe qué poner.

Comprueba que mandas performanceId

En todas las llamadas del lector.

Mide cuánto tarda una validación

Y decide qué enseña el operario mientras espera. Una cola avanza a la velocidad del feedback.

Ten un plan para la caída de red

Aunque sea «se avisa al responsable de sala». Escrito, no improvisado.

Emite una clave por puesto

Para que la auditoría sirva de algo.