Saltar al contenido
Desarrolladores

Una API a la altura de tu producto

Eventos, sesiones, entradas, pedidos, accesos, clientes y devoluciones por API REST, con la misma lógica que el panel. Versionada por fecha, idempotente y con webhooks firmados.

Versión actual
2026-10-01
Formato
REST · JSON · UTF-8
Alojamiento
Servidores en la UE
Autenticación
Bearer · claves restringidas
curl https://api.addon-ticket.com/v1/orders \
  -H "Authorization: Bearer sk_test_7Qp2…" \
  -H "AddOnTicket-Version: 2026-10-01" \
  -H "Idempotency-Key: 5f1c2a9e-checkout-8841" \
  -H "Content-Type: application/json" \
  -d '{
    "session": "ses_0199c2a4e1b37d40a6f2c9e15b7d3a08",
    "items": [{ "ticket_type": "tt_0199c2a4e1b37d40a6f2c9e15b7d3a11", "quantity": 2 }],
    "customer": { "name": "Lucía Ortega", "email": "lucia@example.com" },
    "payment_mode": "checkout_link"
  }'
201Created · 84 ms
{
  "id": "ord_0199c2a5f0d47e2b8c1a9e3f5d7b2c64",
  "object": "order",
  "number": "AOT-7Q4M-2K",
  "status": "pending_payment",
  "event": "evt_0199c2a4e1b37d40a6f2c9e15b7d39f2",
  "session": "ses_0199c2a4e1b37d40a6f2c9e15b7d3a08",
  "channel": "api",
  "buyer": { "name": "Lucía Ortega", "email": "lucia@example.com", "phone": null },
  "amount_subtotal": 7800,
  "amount_fees": 606,
  "amount_total": 8406,
  "currency": "EUR",
  "payment_url": "https://api.addon-ticket.com/pay/…",
  "expires_at": "2026-10-01T10:10:00Z",
  "tickets": [],
  "livemode": false
}
Principios

Aburrida en lo que importa

Las decisiones de diseño que hacen que una integración funcione el día del estreno igual que el día que la escribiste.

REST y JSON predecibles

Recursos en plural, verbos HTTP de siempre e identificadores con prefijo legible. Si sabes leer una URL, sabes usar la API.

GET /v1/tickets/tkt_k3m9q2x7ab

Versionado por fecha

Tu integración queda fijada en la versión con la que empezaste. Los cambios incompatibles solo llegan cuando tú cambias la cabecera.

AddOnTicket-Version: 2026-10-01

Claves de prueba y de producción

Mismo código, dos mundos separados: las claves de prueba solo ven eventos de prueba y cobran en sandbox. Cada clave lleva solo los permisos que necesita.

sk_test_… · sk_live_…

Idempotencia

Reintenta sin miedo: con la misma clave durante 24 h devolvemos la misma respuesta y nunca cobramos dos veces.

Idempotency-Key: 5f1c2a9e-checkout-8841

Paginación por cursor

Listas estables aunque entren pedidos mientras paginas. Hasta 100 elementos por página, has_more y next_cursor.

?limit=100&starting_after=ord_0199c2a5f0d4…

Errores tipados

Cada error trae tipo, código estable, mensaje en español, el parámetro que lo provocó y el Request-Id para que lo busquemos contigo.

{ "type": "permission_error", "code": "insufficient_scope" }

Límites claros

100 peticiones por segundo por clave real y 25 en pruebas, con cabeceras RateLimit-* y Retry-After. ¿Una salida a la venta enorme? Lo ampliamos.

429 · rate_limit_error · Retry-After: 1

Un error, tal y como te llega:

{
  "error": {
    "type": "invalid_request_error",
    "code": "ticket_type_sold_out",
    "message": "No quedan entradas suficientes",
    "param": null,
    "doc_url": "…/desarrolladores#errores-ticket_type_sold_out",
    "request_id": "req_8Yk2pQm1…"
  }
}
Recursos

Once recursos. Todo el ciclo de una entrada.

Del evento a la puerta y a la devolución. Ids con prefijo (evt_, ses_, tt_, ord_, tkt_), importes en céntimos y fechas en UTC.

https://api.addon-ticket.com/v1

  • events

    Crea, edita y publica eventos. Con una clave de pruebas nacen como eventos de prueba.

    GETPOSTPATCH/v1/events
  • sessions

    Fechas de cada evento: horario, puertas, aforo y ventana de venta.

    GETPOSTPATCH/v1/events/{id}/sessions
  • ticket_types

    Precios, cupos, canales de venta y verificación requerida.

    GETPOSTPATCH/v1/events/{id}/ticket_types
  • availability

    Aforo, vendidas, retenidas y libres por tipo de entrada y butaca.

    GET/v1/sessions/{id}/availability
  • orders

    Pedidos de servidor a servidor: con enlace de pago o cobrados fuera (taquilla, B2B).

    GETPOST/v1/orders
  • tickets

    Entradas emitidas por pedido, sesión o evento, con titular, estado y acceso.

    GET/v1/tickets
  • checkins

    Valida un QR o un tkt_ desde tornos y controles de terceros.

    POST/v1/checkins
  • customers

    Compradores de tu organización, consentimiento e historial de gasto.

    GET/v1/customers
  • refunds

    Devoluciones totales, por entradas o por importe, con la misma lógica que el panel.

    GETPOST/v1/refunds
  • reports

    Ventas por día: pedidos, entradas, importe, comisiones y devoluciones.

    GET/v1/reports/sales
  • webhooks

    Suscripciones por tipo de evento, prueba de envío y rotación del secreto.

    GETPOSTPATCHDELETE/v1/webhook_endpoints
  • Especificación OpenAPI 3.1 en /v1/openapi.json y referencia navegable en /v1/docs: genera tu cliente o impórtala en tu herramienta.

Webhooks

Te avisamos antes de que preguntes

Eventos firmados con HMAC-SHA256 en la cabecera AOT-Signature y reintentados durante 72 horas con espera exponencial. Cada entrega queda registrada y puedes reenviarla desde el panel.

Pedidos y entradas

  • order.paidPedido pagado (o confirmado sin cobro)
  • order.refundedDevolución total o parcial
  • ticket.issuedEntrada emitida, una por plaza
  • ticket.transferredLa entrada cambió de titular
  • ticket.checked_inEntrada leída en una puerta de entrada

Eventos y dinero

  • event.publishedEvento publicado y a la venta
  • session.cancelledSesión cancelada
  • payout.paidCobro ingresado en tu cuenta

Verificación

  • verification.completedDNI, edad o descuento comprobados con IA
webhooks/verify.tsTypeScript
import { createHmac, timingSafeEqual } from "node:crypto";

// AOT-Signature: t=1759312800,v1=9c1f0e…  (dos v1 mientras rotas el secreto)
export function verify(rawBody: string, header: string, secret: string) {
  const parts = header.split(",").map((p) => p.split("="));
  const t = Number(parts.find(([k]) => k === "t")?.[1]);
  if (!t || Math.abs(Date.now() / 1000 - t) > 300) return false; // 5 min

  const expected = createHmac("sha256", secret)
    .update(`${t}.${rawBody}`)
    .digest();

  return parts
    .filter(([k]) => k === "v1")
    .some(([, v]) => {
      const got = Buffer.from(v, "hex");
      return got.length === expected.length && timingSafeEqual(got, expected);
    });
}

Comprueba siempre la firma sobre el cuerpo sin procesar y rechaza marcas de tiempo de más de 5 minutos: así evitas repeticiones aunque alguien intercepte una petición.

Clientes y herramientas

Tu lenguaje, con la especificación oficial

La especificación OpenAPI 3.1 está publicada: genera un cliente tipado para tu lenguaje con las herramientas de siempre. El entorno de pruebas funciona igual que producción.

TypeScript / Node

$ npx openapi-typescript https://api.addon-ticket.com/v1/openapi.json -o addon-ticket.d.ts

PHP 8.2+

$ npx @openapitools/openapi-generator-cli generate -g php -i https://api.addon-ticket.com/v1/openapi.json -o addon-ticket-php

Python 3.10+

$ npx @openapitools/openapi-generator-cli generate -g python -i https://api.addon-ticket.com/v1/openapi.json -o addon_ticket

Webhooks de prueba desde el panel

En Desarrolladores › Webhooks envías un evento de prueba a tu endpoint, ves cada entrega con su respuesta y tiempo, y reenvías las que fallaron.

Enviar prueba → https://tu-web.es/webhooks
→ 200 ping 41 ms
→ 500 order.paid reintento 2/8 · Reenviar

Entorno de pruebas

Con una clave sk_test_ todo va a eventos de prueba aislados: no salen en la web, el pago es una pasarela simulada y los webhooks van a tus endpoints de prueba. Sin coste.

payment_mode: checkout_link → sandbox

Embebibles

Vende en tu web con una línea

Una línea de HTML: un botón que abre la compra sobre tu web o la compra incrustada con altura automática. Al terminar, tu página recibe el evento aot:purchase. Pesa menos de 15 KB.

<script src="https://addon-ticket.com/widget.js"
  data-event="sala-sur/sur-fest-2026" async></script>

<script>
  document.addEventListener("aot:purchase", (e) => {
    console.log("Pedido", e.detail.number);
  });
</script>
  • Botón de compra
  • Compra incrustada
  • Evento aot:purchase
  • Dominios permitidos por organización

Sáb 14 nov · Sevilla

Sur Fest 2026

Seguro incluido

Anticipada

Agotada

General

39,00 €

VIP con zona lounge

89,00 €

Pagar 84,06 €Bizum · Apple Pay · Tarjeta

Vista previa ilustrativa del widget

Estado del servicio

Transparencia, también cuando algo falla

Publicamos cada incidencia con su causa y su duración. Infraestructura propia en servidores de la UE: Postgres, Node y Valkey, sin depender de terceros para servir tus entradas.

Todos los sistemas operativos

Ejemplo ilustrativo
  • API99,99 %
  • Pagos y cobros100 %
  • Webhooks99,97 %
  • App de acceso100 %
  • Verificaciones con IA99,95 %
Hace 45 díasHoy
Sin incidencias Degradado Interrupción parcial

Tu primera entrada por API, hoy

Crea una cuenta de pruebas, copia tu clave sk_test_ y emite una entrada real en tu móvil en menos de diez minutos.