Ir al contenido

Guía rápida

Esta guía recorre el ciclo completo con curl contra producción. Sustituye $GATE_KEY por tu llave y $EXPERIENCE_ID por el UUID del evento que te dio alpadevs.

Ventana de terminal
export GATE_BASE="https://gate-partners.alpadevs.com"
export GATE_KEY="agk_0123456789abcdef0123456789abcdef0123456789abcdef"
export EXPERIENCE_ID="22222222-2222-4222-8222-222222222222"

Paso 0 — Enlace de la experiencia (lo hace Gate)

Sección titulada «Paso 0 — Enlace de la experiencia (lo hace Gate)»

Tu llave pertenece a tu proveedor. Para operar sobre un evento, el administrador de Gate debe enlazar esa experiencia a tu proveedor y compartirte su experienceId. Hasta entonces, cualquier petición sobre ese evento responde:

{ "error": { "code": "EXPERIENCE_NOT_LINKED", "message": "Experience is not linked to this provider" } }

Puedes comprobar que el servicio responde sin autenticación:

Ventana de terminal
curl -s "$GATE_BASE/status"
{ "status": "ok" }

Un solo POST con tres filas: un boleto simple, un pase de 3 usos cuyo QR es una URL estilo Google Charts, y un boleto ya anulado.

Ventana de terminal
curl -s -X POST "$GATE_BASE/v1/partner/tickets/bulk" \
-H "Authorization: Bearer $GATE_KEY" \
-H "Content-Type: application/json" \
-d @- <<JSON
{
"experienceId": "$EXPERIENCE_ID",
"rows": [
{
"qrContent": "ABC.DEF",
"externalRef": "TG-1001",
"holderRef": "user-42",
"holderName": "Ana Pérez",
"metadata": { "priceName": "VIP", "experienceName": "Main Event" }
},
{
"qrContent": "https://chart.googleapis.com/chart?cht=qr&chl=GHI.JKL",
"externalRef": "TG-1002",
"maxUses": 3,
"holderRef": "+5215512345678",
"holderName": "Carlos Ruiz"
},
{
"qrContent": "MNO.PQR",
"externalRef": "TG-1003",
"status": "void"
}
]
}
JSON

Respuesta:

{ "inserted": 3, "updated": 0, "reissued": 0, "rejected": [] }

El QR de TG-1002 se guarda normalizado como GHI.JKL (el parámetro chl). Si repites exactamente el mismo request, la respuesta pasa a { "inserted": 0, "updated": 3, "reissued": 0, "rejected": [] }: el bulk es idempotente por externalRef.

Ventana de terminal
curl -s "$GATE_BASE/v1/partner/tickets/TG-1001?experienceId=$EXPERIENCE_ID" \
-H "Authorization: Bearer $GATE_KEY"

Antes de que nadie lo escanee:

{
"externalRef": "TG-1001",
"experienceId": "22222222-2222-4222-8222-222222222222",
"status": "valid",
"redeemedAt": null,
"syncedAt": "2026-08-28T09:00:00.000+00:00"
}

Después de que entre por la puerta:

{
"externalRef": "TG-1001",
"experienceId": "22222222-2222-4222-8222-222222222222",
"status": "redeemed",
"redeemedAt": "2026-08-29T10:00:01.123456+00:00",
"syncedAt": "2026-08-28T09:00:00.000+00:00"
}

Un externalRef inexistente responde 404:

{ "error": { "code": "TICKET_NOT_FOUND", "message": "Ticket not found" } }
Ventana de terminal
curl -s -X POST "$GATE_BASE/v1/partner/tickets/void" \
-H "Authorization: Bearer $GATE_KEY" \
-H "Content-Type: application/json" \
-d "{ \"experienceId\": \"$EXPERIENCE_ID\", \"externalRef\": \"TG-1002\" }"
{ "status": "voided" }

Repetir la anulación responde { "status": "already_void" }. Intentar anular TG-1001 una vez redimido responde 409 REDEEMED_CONFLICT.

Ventana de terminal
curl -s "$GATE_BASE/v1/partner/redemptions?limit=100" \
-H "Authorization: Bearer $GATE_KEY"
{
"items": [
{
"externalRef": "TG-1001",
"experienceId": "22222222-2222-4222-8222-222222222222",
"redeemedAt": "2026-08-29T10:00:01.123456+00:00"
}
],
"nextSince": null
}

nextSince: null significa que no hay más por ahora. Guarda el redeemedAt del último item y úsalo como ?since= en tu siguiente ciclo de polling. Detalle de la paginación en GET /redemptions.