> ## 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.

# Control access using webhooks

> Learn how to add access control to a content with React, using webhooks

Webhooks offer a versatile and dynamic approach to access control for both
assets and livestreams. By setting up a webhook, you can validate access
requests on the fly, allowing for real-time, context-sensitive decisions.

When a user requests access to content, the webhook you've specified will be
called. This webhook can then decide whether to grant or deny access based on
custom logic, such as user authentication, subscription status, or any other
criteria.

<Info>
  This guide is written for developers using `@livepeer/react` in a React
  application.
</Info>

The example below uses webhook to create and watch a gated content.

## Create an Access Control Webhook Handler

Set up an endpoint (e.g., [https://yourdomain.com/api/check-access](https://yourdomain.com/api/check-access)) to handle the
logic for granting or denying access to your assets. This endpoint should accept
a POST request with a JSON payload containing the access key and webhook
context.

This is an example of a payload this endpoint would receive:

```json POST /api/check-access theme={"theme":{"light":"github-light","dark":"dark-plus"}}
{
  "accessKey": "your-access-key",
  "context": {
    "assetId": "abcd1234",
    "userId": "user5678"
  },
  "timestamp": 1680530722502
}
```

The payload in `context` is defined by your application.

### Register the Access Control Webhook

Use the
[Livepeer Studio dashboard](https://livepeer.studio/dashboard/developers/webhooks)
to create a new webhook with the type `playback.accessControl` and specify the
URL of your access control endpoint.

You can then use the ID of the webhook in the next step.

## Create content with a playback policy webhook

### For assets

Create an asset with a playback policy webhook, passing the ID of the webhook
you created in the previous step.

```tsx accessControl.ts theme={"theme":{"light":"github-light","dark":"dark-plus"}}
import { Livepeer } from "livepeer";
import { TypeT } from "livepeer/dist/models/components";

const livepeer = new Livepeer({
  apiKey: process.env.STUDIO_API_KEY ?? "",
});

await livepeer.asset.create({
  name: "...",
  playbackPolicy: {
    type: TypeT.Webhook,
    // This is the id of the webhook you created in step 2
    webhookId: "<webhook_id>",
    webhookContext: {
      // This is the context you want to pass to your webhook
      // It can be anything you want, and it will be passed back to your webhook
    },
  },
});
```

You can then use the [returned TUS URL](/api-reference/asset/upload) to upload
the asset.

### For livestreams

Create a stream with a playback policy webhook, passing the ID of the webhook
you created in the previous step.

```tsx accessControl.ts theme={"theme":{"light":"github-light","dark":"dark-plus"}}
import { Livepeer } from "livepeer";
import { TypeT } from "livepeer/dist/models/components";

const livepeer = new Livepeer({
  apiKey: process.env.STUDIO_API_KEY ?? "",
});

await livepeer.stream.create({
  name: "...",
  playbackPolicy: {
    type: TypeT.Webhook,
    // This is the id of the webhook you created in step 2
    webhookId: "<webhook_id>",
    webhookContext: {
      // This is the context you want to pass to your webhook
      // It can be anything you want, and it will be passed back to your webhook
    },
  },
});
```

### Configure the Player

If you are using the Livepeer UI Kit Player, you can use the
[`accessKey`](/sdks/react/player/Root#accesskey) prop to provide your custom
access key, which is then passed to the webhook you created to verify that it is
valid.

<Info>
  The React Player passes the access key with a header, `Livepeer-Access-Key`,
  to the backend, for WebRTC and HLS playback. For MP4 playback, it uses a query
  parameter, `accessKey`.
</Info>

```tsx theme={"theme":{"light":"github-light","dark":"dark-plus"}}
import * as Player from "@livepeer/react/player";

export const CreateAndViewAsset = () => {
  const accessKey = getAccessKeyForYourApplication();

  return (
    <Player.Root src={src} accessKey={accessKey}>
      <Player.Container>
        <Player.Video />
      </Player.Container>
    </Player.Root>
  );
};
```

### Using a custom player

If you are not using the player, you will need to pass a header,
`Livepeer-Access-Key`, when you perform WebRTC SDP negotiation, or when you play
back from a m3u8 URL.

For WebRTC SDP negotiation, here is an example of the header being passed:

```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
curl -X POST \
     -H "Content-Type: application/sdp" \
     -H "Livepeer-Access-Key: your-access-key" \
     --data-binary "@sdpfile.sdp" \
     "https://livepeercdn.studio/webrtc/abcd1234"
```

You can also append the access key to the WebRTC URL as a query parameter,
similar to:

```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
curl -X POST \
     -H "Content-Type: application/sdp" \
     --data-binary "@sdpfile.sdp" \
     "https://livepeercdn.studio/webrtc/abcd1234?accessKey=your-access-key"
```

Similarly, for HLS playback, you can pass the access key in a header:

```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
curl -X GET \
     -H "Livepeer-Access-Key: your-access-key" \
     "https://playback.livepeer.studio/asset/hls/abcd1234/index.m3u8"
```

<Info>
  If you are using HLS.js for your own custom player, you can set the access key header like this:

  ```tsx theme={"theme":{"light":"github-light","dark":"dark-plus"}}
  const hlsConfig = {
    xhrSetup: function (xhr, url) {
      xhr.setRequestHeader("Livepeer-Access-Key", "your-access-key");
    },
  };
  ```
</Info>

Finally, you can append the access key to the m3u8 URL as a query parameter:

```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
curl -X GET \
     "https://playback.livepeer.studio/asset/hls/abcd1234/index.m3u8?accessKey=your-access-key"
```

### Receive the Webhook from Livepeer

When a user attempts to access the content, Livepeer will call your access
control endpoint with the access key and webhook context. Your endpoint should
process the request and return a response indicating whether the stream access
should be allowed or disallowed.

Here is an example request sent to your access control endpoint:

```json theme={"theme":{"light":"github-light","dark":"dark-plus"}}
{
  "context": {
    // Same value from the `asset.playbackPolicy.webhookContext` field
  },
  "accessKey": "<access_key>" // this is exact value of the prop passed to the Player, or the query parameter
}
```

In your access control endpoint, implement the logic to verify the access key
and decide whether to grant access to the content. If the access is allowed,
return a `2XX` response. Otherwise, the playback will be disallowed.
