Saltar al contenido
Tickeep
Índice de la API

Primeros pasos: de la clave a la primera venta

Cinco llamadas que van de crear una clave a emitir una entrada de verdad, con el porqué de cada paso.

Última actualización: 23 de agosto de 2026

Esta página va de arriba abajo: al final habrás emitido una entrada real. Si solo vas a mostrar el cartel en tu web, con los tres primeros pasos tienes bastante.

Antes de empezar necesitas una clave con permiso orders:write —que ya incluye la lectura del catálogo— creada en Configuración → Desarrolladores. Ver autenticación.

export TICKEEP_API_KEY="tk_live_..."
Esto crea ventas de verdad

No hay entorno de pruebas aislado todavía. Haz este recorrido contra una sala de pruebas de tu organización, no contra la sala con la que vendes.

1. Qué salas alcanza tu clave

Es el punto de entrada de cualquier integración: de aquí salen los venueId que necesita todo lo demás.

GET/venues

Salas a las que llega esta clave. Sin paginación: una organización tiene unas pocas salas, no miles.

curl https://app.tickeep.com/api/v1/venues \
  -H "Authorization: Bearer $TICKEEP_API_KEY"
{
  "data": [
    {
      "id": "6a42356a296cb2dfe6ba1c7f",
      "name": "Sala Tempo",
      "slug": "tempo",
      "host": "entradas.salatempo.com",
      "timezone": "Europe/Madrid"
    }
  ]
}

Guarda el id. El host te hará falta luego para componer las URLs de las imágenes.

export VENUE="6a42356a296cb2dfe6ba1c7f"

2. Las próximas fechas

Un evento puede tener una fecha o cincuenta. Lo que se vende es la fecha concreta —lo que la API llama performance y el panel llama sesión—, así que es lo que hay que listar.

GET/performances

Fechas concretas, en orden cronológico ascendente. Acepta eventId, venueId, from y to.

curl -G https://app.tickeep.com/api/v1/performances \
  -H "Authorization: Bearer $TICKEEP_API_KEY" \
  --data-urlencode "venueId=$VENUE" \
  --data-urlencode "from=2026-09-01T00:00:00Z"
{
  "data": [
    {
      "id": "6a72089e1f4c8b0d3e5a9c11",
      "eventId": "6a7207c4b8e1a2f5c9d04e33",
      "venueId": "6a42356a296cb2dfe6ba1c7f",
      "name": null,
      "status": "active",
      "doorsAt": "2026-09-12T19:30:00.000Z",
      "startsAt": "2026-09-12T20:00:00.000Z",
      "endsAt": null,
      "capacity": 300,
      "sold": 128,
      "available": 172
    }
  ],
  "hasMore": false,
  "nextCursor": null
}
export PERF="6a72089e1f4c8b0d3e5a9c11"

3. Qué se puede vender ahora

GET/performances/{id}/availability

Tipos de entrada a la venta en esta fecha, con precio y cuántas quedan.

curl "https://app.tickeep.com/api/v1/performances/$PERF/availability" \
  -H "Authorization: Bearer $TICKEEP_API_KEY"
{
  "performanceId": "6a72089e1f4c8b0d3e5a9c11",
  "capacity": 300,
  "sold": 128,
  "available": 172,
  "ticketTypes": [ "…el objeto completo de cada tarifa…" ],
  "availability": [
    {
      "ticketTypeId": "6a7209f2c3d4e5f60718293a",
      "name": "Entrada general",
      "price": { "amount": 1800, "currency": "EUR" },
      "available": 172,
      "onSale": true
    }
  ]
}

Dos cosas de esta respuesta:

El precio va en céntimos. 1800 son 18,00 €. Nunca decimales — el porqué está en convenciones.

Esto no reserva nada. Es una foto del momento. Entre que la lees y vendes, otro comprador puede llevarse la última entrada. Úsala para pintar tu selector, no como garantía.

export TT="6a7209f2c3d4e5f60718293a"

4. Reservar

Aquí empieza la venta. Un pedido nace pending con el stock ya retenido a tu nombre durante 30 minutos.

POST/orders

Crea el pedido y reserva el stock. Exige la cabecera Idempotency-Key.

curl -X POST https://app.tickeep.com/api/v1/orders \
  -H "Authorization: Bearer $TICKEEP_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "venueId": "'$VENUE'",
    "items": [{ "ticketTypeId": "'$TT'", "quantity": 2 }],
    "customer": { "email": "ana@ejemplo.com", "name": "Ana" }
  }'
{
  "id": "6a7300aa11bb22cc33dd44ee",
  "reference": "TK-TEMPO-20260823-AB12",
  "venueId": "6a42356a296cb2dfe6ba1c7f",
  "status": "pending",
  "source": "api",
  "paymentMethod": "pending",
  "customer": { "email": "ana@ejemplo.com", "name": "Ana", "phone": null },
  "lines": [
    {
      "eventId": "6a7207c4b8e1a2f5c9d04e33",
      "performanceId": "6a72089e1f4c8b0d3e5a9c11",
      "ticketTypeId": "6a7209f2c3d4e5f60718293a",
      "eventName": "Peter Rock en directo",
      "ticketTypeName": "Entrada general",
      "performanceStartsAt": "2026-09-12T20:00:00.000Z",
      "unitPrice": { "amount": 1800, "currency": "EUR" },
      "quantity": 2,
      "lineTotal": { "amount": 3600, "currency": "EUR" }
    }
  ],
  "subtotal": { "amount": 3600, "currency": "EUR" },
  "serviceFee": { "amount": 200, "currency": "EUR" },
  "total": { "amount": 3800, "currency": "EUR" },
  "ticketsIssued": false,
  "reservationExpiresAt": "2026-08-23T18:30:00.000Z",
  "paidAt": null
}

Tres detalles que ahorran disgustos:

No has mandado ningún importe. Solo ticketTypeId y quantity. El precio, el IVA y los gastos de gestión los calcula el servidor contra su base de datos. Si el cliente pudiera fijar el precio, podría venderse entradas a cero euros.

La Idempotency-Key es obligatoria aquí. Genera una por intento de compra y reutilízala en los reintentos. Si se cae la red justo después de que el servidor haya reservado, tu reintento con la misma clave recupera el mismo pedido en vez de crear otro. Está explicado entero en idempotencia.

Apunta la reference, no el id. TK-TEMPO-20260823-AB12 es lo que ve el comprador, lo que sale en su email y lo que te dicta por teléfono. El resto de endpoints de pedido van por ahí.

export REF="TK-TEMPO-20260823-AB12"

5. Confirmar el cobro

Ahora hay dos caminos. Aquí tomamos el primero.

POST/orders/{reference}/confirm

Registra que has cobrado tú, fuera de Tickeep, y emite las entradas al momento.

curl -X POST https://app.tickeep.com/api/v1/orders/$REF/confirm \
  -H "Authorization: Bearer $TICKEEP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "paymentMethod": "external" }'
{
  "order": { "…": "el pedido, ya con status: paid" },
  "ticketsStatus": "issued",
  "tickets": [
    {
      "id": "6a7301bb22cc33dd44ee55ff",
      "code": "TMP-9K4X-72QD",
      "orderReference": "TK-TEMPO-20260823-AB12",
      "status": "valid",
      "holder": null,
      "email": "ana@ejemplo.com",
      "pricePaid": { "amount": 1800, "currency": "EUR" },
      "checkedInAt": null
    }
  ]
}

Ya está: las entradas existen, tienen código y, si mandaste un email, salen hacia el comprador.

Confirmar no es cobrar

Registra que el dinero se movió fuera de Tickeep: tu datáfono, tu pasarela, efectivo en mano. Si lo que quieres es que pague el comprador por la pasarela de la sala, el camino es /payment-link.

El otro camino: que pague el comprador

POST/orders/{reference}/payment-link

Devuelve una URL de pago contra la pasarela de la sala. Caduca con la reserva.

curl -X POST https://app.tickeep.com/api/v1/orders/$REF/payment-link \
  -H "Authorization: Bearer $TICKEEP_API_KEY"
{
  "url": "https://entradas.salatempo.com/taquilla/TK-TEMPO-20260823-AB12?k=…",
  "expiresAt": "2026-08-23T18:30:00.000Z"
}

Se la mandas al comprador por email, se la enseñas como QR o la abres en tu web. Cuando paga, el webhook de la pasarela marca el pedido y dispara la entrega. Tú te enteras con el webhook order.paid.

Si el comprador se echa atrás

POST/orders/{reference}/cancel

Anula la reserva y libera el stock en el acto.

curl -X POST https://app.tickeep.com/api/v1/orders/$REF/cancel \
  -H "Authorization: Bearer $TICKEEP_API_KEY"

Cancelar explícitamente importa más de lo que parece. Si no lo haces, esas entradas siguen bloqueadas hasta que caduque la reserva —media hora— y durante ese rato no se le pueden vender a nadie. En una noche que se agota, media hora es mucho.

Lo mismo con el cliente de TypeScript

import { TickeepPartnerClient } from '@tickeep/client'

const tickeep = new TickeepPartnerClient({ apiKey: process.env.TICKEEP_API_KEY! })

const { data: venues } = await tickeep.venues()
const venueId = venues[0].id

const { data: performances } = await tickeep.performances({ venueId })
const performanceId = performances[0].id

const { availability } = await tickeep.availability(performanceId)
const ticketTypeId = availability.find((a) => a.onSale)!.ticketTypeId

const order = await tickeep.createOrder(
  { venueId, items: [{ ticketTypeId, quantity: 2 }], customer: { email: 'ana@ejemplo.com' } },
  crypto.randomUUID(), // Idempotency-Key
)

const { tickets } = await tickeep.confirmOrder(order.reference, { paymentMethod: 'external' })

Más en cliente de TypeScript.

Siguientes pasos

  • Si vas a vender de verdad desde tu web, la receta completa —con los webhooks— está en vender desde tu web.
  • Si vas a listar mucho catálogo, lee paginación y sincronización antes de escribir el bucle.
  • Y antes de subirlo a producción, errores: qué reintentar y qué no.