Vai al contenuto principale

Booking Webhooks

I booking webhook consegnano un POST firmato a un endpoint HTTPS che controlli ogni volta che un booking fa una transition nel workspace — created, confirmed, cancelled, rescheduled, declined, reassigned o segnalato come no-show. Questa pagina copre l'elenco eventi, il payload, gli header, la verifica della signature e il contratto di delivery/retry. Per la Bookings API read-only e un orientamento rapido, parti dall'introduzione Bookings.

nota

Le subscription webhook si configurano dalle impostazioni Bookings dell'app Copera da un amministratore del workspace — non vengono create o gestite tramite la Public API. Ogni subscription ha un receiver URL, un set di eventi e un signing secret.

Eventi

EventFires when
booking.createdA booking is created (pending or confirmed).
booking.confirmedA booking is confirmed.
booking.cancelledA booking is cancelled.
booking.rescheduledA booking is rescheduled to a new time.
booking.declinedA pending booking is declined by the host.
booking.reassignedA booking's host is reassigned (round-robin).
booking.no_showA no-show is recorded for the host or booker.

Una subscription riceve solo gli eventi che include, e solo mentre è attiva.

Payload

Ogni delivery è un POST con un body JSON:

{
"event": "booking.confirmed",
"createdAt": "2026-07-06T09:00:00.000Z",
"data": {
"id": "665f…",
"status": "CONFIRMED",
"bookingTypeId": "665f…",
"bookingTypeTitle": "Intro Call",
"start": "2026-07-08T15:00:00.000Z",
"end": "2026-07-08T15:30:00.000Z",
"durationMinutes": 30,
"timezoneAtBooking": "America/Sao_Paulo",
"hosts": [{ "userId": "665f…", "role": "ORGANIZER" }],
"booker": {
"name": "Alice Booker",
"email": "[email protected]",
"phone": "+15551234567",
"timezone": "America/Sao_Paulo",
"locale": "en"
},
"guests": [],
"answers": [{ "questionId": "q1", "label": "Topic", "value": "Pricing" }],
"location": { "type": "MEETING_CHANNEL" }
}
}

Il blocco data è il dato di booking del tuo workspace, quindi i dettagli di contatto del booker sono inclusi. I campi interni sensibili non vengono mai inviati.

Correlare un evento webhook con la Public API

Il payload webhook porta data.id. Passalo direttamente a GET /public/v1/bookings/{id} per recuperare il dettaglio completo del booking:

curl -H "Authorization: Bearer $TOKEN" \
"https://api.copera.ai/public/v1/bookings/${data.id}"

Usa lo stesso valore data.id con una richiesta autenticata alla Bookings API ogni volta che devi correlare eventi webhook con il dettaglio completo del booking.

HeaderValue
X-Copera-EventThe event string (e.g. booking.confirmed).
X-Copera-Signaturesha256=<hex> — HMAC-SHA256 of the raw request body using your subscription secret.
X-Copera-Webhook-VersionThe payload contract version (currently 1).

Verificare la signature

Calcola l'HMAC-SHA256 del raw request body (prima del parsing JSON) con il secret della subscription e confrontalo in constant time con l'hex in X-Copera-Signature:

import { createHmac, timingSafeEqual } from "node:crypto";

function isValidSignature(rawBody, header, secret) {
const expected =
"sha256=" + createHmac("sha256", secret).update(rawBody, "utf8").digest("hex");
const a = Buffer.from(header);
const b = Buffer.from(expected);
return a.length === b.length && timingSafeEqual(a, b);
}

Delivery e retry

  • Rispondi con un 2xx per confermare la ricezione.
  • Un 4xx è trattato come rejection permanente — Copera non ritenta.
  • Un 5xx, errore di network o timeout viene ritentato con exponential backoff (3 tentativi totali). Rendi il receiver idempotente — lo stesso evento può essere consegnato più di una volta.
  • Gli URL receiver devono essere endpoint HTTPS pubblici; indirizzi privati o interni vengono rifiutati.

Riferimento