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

# Access control with webhooks

> Gate playback using a webhook that validates the viewer and returns allow or deny.

With **webhook** access control, when a viewer tries to play gated content, Livepeer Studio calls your endpoint. You return 2XX to allow, or non-2XX to deny.

## 1. Create an access-control webhook

In [Livepeer Studio → Developers → Webhooks](https://livepeer.studio/dashboard/developers/webhooks), create a webhook with type **playback.accessControl** and the URL of your endpoint (e.g. `https://yourdomain.com/api/check-access`).

## 2. Create gated content

When creating the stream or asset, set `playbackPolicy` to the webhook type and your webhook ID and context:

```ts icon="terminal" theme={"theme":{"light":"github-light","dark":"dark-plus"}}
await livepeer.stream.create({
  name: "Gated stream",
  playbackPolicy: {
    type: "webhook",
    webhookId: "<webhook_id>",
    webhookContext: { assetId: "...", userId: "..." },
  },
});
```

Same idea for `livepeer.asset.create` with `playbackPolicy`.

## 3. Configure the Player

Pass an **access key** (e.g. Session token or user id) to the Player. The Player sends it to Livepeer, which forwards it to your webhook:

```tsx icon="terminal" theme={"theme":{"light":"github-light","dark":"dark-plus"}}
<Player.Root src={src} accessKey={getAccessKeyForUser()}>
  <Player.Container><Player.Video /></Player.Container>
</Player.Root>
```

## 4. Handle the webhook

Your endpoint receives a POST with `accessKey` and `context`. Validate the key (e.g. Check auth, subscription). Return **2XX** to allow playback, **non-2XX** to deny.

**Custom player:** For WebRTC or HLS, send the access key in the `Livepeer-Access-Key` header or as query param `accessKey` on the playback URL.
