> ## Documentation Index
> Fetch the complete documentation index at: https://docs.apifycloud.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks

> Lifecycle events delivered to your systems

Every state change on a booking can be pushed to your systems as a
webhook. You configure subscriptions per video app; each
subscription chooses which event types it wants and where they
should be delivered.

## Events

| Event                   | When it fires                                                   |
| ----------------------- | --------------------------------------------------------------- |
| `scheduled.created`     | A booking was created (through any surface).                    |
| `scheduled.rescheduled` | The `scheduled_at` of an existing booking changed.              |
| `scheduled.cancelled`   | A booking transitioned to `cancelled`.                          |
| `scheduled.confirmed`   | A `pending_confirmation` booking was confirmed by the customer. |
| `scheduled.no_show`     | The grace window passed without anyone joining.                 |

You subscribe to any subset you care about. A subscription can
receive one event type or all of them.

## Delivery

Each webhook request is a `POST` to the URL you registered with a
JSON body and signed headers:

```
POST <your-url>
Content-Type: application/json
X-ApifyCloud-Signature: sha256=<hmac>
X-ApifyCloud-Event: scheduled.created
X-ApifyCloud-Delivery: <subscriptionId>:<attempt>
X-ApifyCloud-Timestamp: <ISO-8601>

{
  "event": "scheduled.created",
  "deliveredAt": "...",
  "attempt": 1,
  "payload": { "scheduled_call": { ... } }
}
```

The `payload.scheduled_call` object carries the full booking
record — ids, times, status, guest info, assigned agent,
timeline-relevant fields.

## Signature verification

The `X-ApifyCloud-Signature` header is an **HMAC-SHA256** of the
raw request body, keyed with the subscription's secret, hex-encoded.

Your endpoint should:

1. Read the raw body as bytes (before any JSON parsing).
2. Compute `HMAC-SHA256(secret, body)`.
3. Compare the hex digest against the value after `sha256=` in
   the header, using a constant-time comparison.
4. Reject the request if they don't match.

The subscription's secret is generated by the console when you
create the subscription. Keep it out of source control.

## Retries

Deliveries that fail (non-2xx response, network error, timeout)
are retried automatically with exponential backoff. After a few
failed attempts the subscription surfaces a failing status in the
console so an operator can investigate. Subscriptions that
consistently fail can be auto-paused.

Retries are **best-effort** — design your endpoint to be
idempotent. The `X-ApifyCloud-Delivery` header includes both the
subscription id and the attempt number so you can detect repeat
deliveries of the same event.

## Managing subscriptions

From `Apps → [your video app] → Scheduled calls → Config` an admin
can:

* Add a new subscription with a URL and an event-type allowlist.
* Pause or re-enable a subscription.
* View the last delivery status and retry manually.
* Rotate the signing secret.

## What's next

<CardGroup cols={2}>
  <Card title="Rescheduling & cancellation" href="/guides/scheduled-calls/rescheduling-cancellation">
    Which lifecycle transitions trigger which events.
  </Card>

  <Card title="API reference" href="/api-reference/scheduled-calls/list">
    Query bookings directly via the API.
  </Card>
</CardGroup>
