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.
This guide is written for developers using @livepeer/react
in a React
application.
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) 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:
{
"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
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.
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 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.
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
},
},
});
If you are using the Livepeer UI Kit Player, you can use the
accessKey
prop to provide your custom
access key, which is then passed to the webhook you created to verify that it is
valid.
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
.
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:
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:
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:
curl -X GET \
-H "Livepeer-Access-Key: your-access-key" \
"https://playback.livepeer.studio/asset/hls/abcd1234/index.m3u8"
If you are using HLS.js for your own custom player, you can set the access key header like this:const hlsConfig = {
xhrSetup: function (xhr, url) {
xhr.setRequestHeader("Livepeer-Access-Key", "your-access-key");
},
};
Finally, you can append the access key to the m3u8 URL as a query parameter:
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:
{
"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.