Catálogo de eventos

El contenido exacto de cada evento, para tenerlo delante mientras escribes el manejador.

El mecanismo —firma, reintentos, cómo configurarlos— está en Webhooks. Esta página es solo la chuleta de los payloads. Todos llegan envueltos en { id, event, createdAt, campingId, data }: lo que ves abajo es el contenido de data.

reservation.created

Una reserva queda confirmada.

datajson
{
  "reservation": {
    "id": "…", "number": 59383, "guestName": "Ana Pérez",
    "email": "ana@example.com", "phone": "+34600111222", "plate": "1234ABC",
    "from": "2026-09-01", "to": "2026-09-04", "persons": 2,
    "status": "confirmada", "checkin": "pendiente", "totalCents": 7350, "channel": "web"
  }
}

reservation.updated

Cambia el estado de una reserva (entrada, salida).

datajson
{
  "reservation": { "id": "…", "number": 59383, "status": "en_casa", "plate": "4321CBA", … }
}

reservation.cancelled

Una reserva se cancela.

datajson
{
  "reservation": { "id": "…", "number": 59383, "status": "cancelada", … }
}

checkin.completed

El huésped completa el check-in y sus viajeros.

datajson
{
  "reservation": { "id": "…", "number": 59383, "checkin": "completado", … }
}

payment.received

Se registra un cobro de la reserva.

datajson
{
  "reservation": { "id": "…", "number": 59383, "totalCents": 7350, … }
}

access.opened

Se abre una puerta o barrera, por el medio que sea.

datajson
{
  "via": "anpr",            // anpr | guest | operator
  "plate": "1234ABC",       // null si no fue por matrícula
  "reservationId": "…",     // null si abrió recepción sin reserva
  "lockId": "…",
  "lockLabel": "Barrera de entrada",
  "at": "2026-08-21T18:00:00.000Z"
}

access.denied

Una matrícula llega a la barrera y no está autorizada.

datajson
{
  "plate": "9999ZZZ",
  "reason": "unknown_plate",
  "direction": "entrada",                     // por qué lado llegaba
  "at": "2026-08-21T18:00:00.000Z"
}

access.exit_unknown

Sale un vehículo cuya matrícula no reconocemos: la barrera se abre igual (ya está dentro) y queda anotado.

datajson
{
  "plate": "9999ZZZ",
  "direction": "salida",
  "opened": true,                             // se abre igual: quien sale ya está dentro
  "at": "2026-08-21T18:00:00.000Z"
}

traveler.registered

Se registra un viajero en el parte (escaneado o tecleado).

datajson
{
  "reservationId": "…",
  "travelers": [{ "guestId": "…", "action": "created", "numeroDocumento": "12345678Z" }],
  "source": "api"
}

invoice.issued

Se emite una factura.

datajson
{
  "invoice": {
    "id": "…", "series": "A", "number": 143, "reference": "A143",
    "issuedAt": "2026-08-20T10:12:00.000Z",
    "customerName": "Ana Pérez", "customerNif": "12345678Z",
    "totalCents": 7350, "type": "F1"          // F1 completa · R1 rectificativa
  },
  "reservationId": "…"                        // null si la factura no cuelga de una reserva
}

Si te pierdes eventos

Reintentamos durante unas horas, pero si tu servidor estuvo caído más tiempo no hace falta que nos pidas un reenvío: GET /api/v1/events?since=… devuelve lo que se emitió, y reconcilias tú.

curl "https://pernocta.app/api/v1/events?since=2026-08-21T00:00:00Z&limit=200" \
  -H "Authorization: Bearer pna_live_TU_CLAVE"