Eventos de webhook
Ocho tipos de evento de reserva y uno de prueba. Te suscribes a los que quieras, o a todos con «*».
| Tipo | Cuándo | Notas |
|---|---|---|
booking.created | Se crea una reserva (por cualquier canal). | changes vacío. |
booking.updated | Cambia algo relevante y no encaja en ninguno de los de abajo: fechas, direcciones, pasajeros, vuelo, precio, cliente, confirmación… | changes dice qué. |
booking.assigned | Se asigna o cambia el conductor o el vehículo (y queda alguno asignado). | Mira assignment en data. |
booking.started | El estado pasa a in_progress (pasajero a bordo). | previous_status suele ser en_camino. |
booking.completed | El estado pasa a completed. | El momento de facturar. |
booking.cancelled | El estado pasa a cancelled. | |
booking.no_show | El estado pasa a no_show. | |
booking.deleted | La reserva se borra (borrado lógico). Deja de aparecer en la API. | data todavía trae la reserva. |
webhook.test | Lo pides tú con POST /webhooks/{id}/test. | data es null. No aparece en GET /events. |
Cada cambio de la reserva produce un evento, del tipo más específico que encaje. Un cambio de estado a confirmed o en_route llega como booking.updated con status en changes; una edición de precio y de hora a la vez llega como un solo booking.updated con ambos en changes. Los cambios que solo tocan datos internos (búsqueda, avisos, contadores) no producen evento.
Reservas de la bolsa
Cuando una reserva la origina una empresa y la ejecuta otra, cada una recibe su propio evento (si tiene la salida activada). En tu data, role dice qué papel tienes y assignment.external si la ejecuta otro.
El campo changes
Son nombres de columnas internas, no de propiedades del objeto público: status, pickup_at, end_at, origin_text, dest_text, pax, luggage, flight_number, service_kind, hours, vehicle_type, price_total, sale_price_total, vat_pct, payment_mode, payment_status, passenger_name, passenger_phone, passenger_email, executor_driver_id, executor_fleet_driver_id, executor_vehicle_id, source_id, billing_client_id, deleted_at. Sirve para saber si te interesa; el valor lo lees en data. Los tres del pasajero solo aparecen con passengers:read.
Ejemplo
{
"id": "6d2e1f0a-9b8c-4d7e-a6f5-4c3b2a1d0e9f",
"type": "booking.assigned",
"version": 1,
"created_at": "2026-09-18T10:42:07.318Z",
"organization": {
"id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d"
},
"resource": {
"type": "booking",
"id": "0c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f"
},
"changes": [
"executor_fleet_driver_id",
"executor_vehicle_id"
],
"previous_status": "confirmada",
"data": {
"id": "0c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
"reference": "10031234",
"external_id": "VLC-2026-000123",
"status": "completed",
"service_type": "transfer",
"hours": null,
"pickup_at": "2026-09-18T08:30:00+00:00",
"end_at": null,
"pickup": {
"address": "Aeropuerto de Valencia (VLC)",
"lat": 39.4893,
"lng": -0.4816
},
"destination": {
"address": "Hotel Las Arenas, Valencia",
"lat": 39.4735,
"lng": -0.3245
},
"distance_km": 12.4,
"flight": {
"number": "VY1234",
"pending": false
},
"passengers": {
"count": 2,
"luggage": 2,
"luggage_big": 2,
"luggage_small": 0,
"baby_seats": 0,
"child_seats": 0,
"booster_seats": 0,
"wheelchair": false
},
"vehicle_category": "sedan",
"customer": {
"id": "7e6d5c4b-3a2b-4c1d-9e8f-7a6b5c4d3e2f",
"name": "Hotel Las Arenas"
},
"assignment": {
"external": false,
"driver": {
"id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"name": "Marta Gil",
"nickname": "Marta"
},
"vehicle": {
"id": "5f4e3d2c-1b0a-4f9e-8d7c-6b5a4f3e2d1c",
"plate": "1234 KLM",
"model": "Mercedes Clase E"
}
},
"role": "originator_and_executor",
"channel": "customer_engine",
"confirmation": {
"mode": "auto",
"confirmed_at": "2026-09-17T18:02:11+00:00"
},
"event_reference": null,
"created_at": "2026-09-17T18:02:11.204Z"
}
}Los tipos se pueden filtrar también en GET /events.