• Skip to Search
  • Skip to Content
  • Skip to Side Navigation
Getting StartedSDK ReferenceGlossary
  • Home
  • Getting Started
  • SDK Reference
  • Portal
  • How-To
  • Troubleshooting
  • FAQs
  • Reference
  • Glossary
REST API
Web SDK
Android SDK
iOS SDK
Unity SDK
React Native SDK
EdgeAuth SDK
  • Overview
  • Channel
  • Room
  • Stream
  • RTMP
  • Transformation
  • Reporting
  • Analytics
  • Notification
  • Live and On-Demand

Notification API

The PCast™ streaming platform can notify your backend via web hook on certain stream events.

  • Stream publishing starts
  • Stream publishing stops
  • Live HLS and DASH streams available
  • Video on demand asset available

Register Notification Endpoint

Request

You can set the callback endpoint for your application using a PUT request.

HTTP
1PUT /pcast/application/<applicationId>/callback HTTP/1.1
2Host: pcast.phenixrts.com
3Accept: application/json
4Content-Type: application/json
5Content-Length: 194
6Authorization: Basic YXBwbGljYXRpb25JZDpzZWNyZXQ=
7
8{
9 "callback": {
10 "protocol": "<protocol>",
11 "host": "<host>",
12 "port": <port>,
13 "method": "<method>",
14 "path": "<path>",
15 "query": "<query>"
16 }
17}
cURL
1$ curl https://pcast.phenixrts.com/pcast/application/<applicationId>/callback \
2-H "Accept: application/json" \
3-H "Content-Type: application/json" \
4-u applicationId:secret \
5-X PUT \
6-d '{
7 "callback": {
8 "protocol": "<protocol>",
9 "host": "<host>",
10 "port": <port>,
11 "method": "<method>",
12 "path": "<path>",
13 "query": "<query>"
14 }
15 }'

The Content-Length header is automatically populated by curl. If using another method to access the API, you must calculate and populate the Content-Length header.

Request Fields

FieldDescription
credentials (optional)The preferred way of passing the credentials is with HTTP authentication header. Alternatively they can be passed in the request body (deprecated).
callback (required)The object defining the callback endpoint. See object structure below.

Callback Object

FieldDefault ValueDescription
protocol (optional)"http"The protocol to use for notifications: "http" or "https"
host (required)The host to use for notifications (E.g. "mywebsite.com")
port (optional)80 (HTTP) or 443 (HTTPS)A numerical (not a string) value defining the port to use for notifications
method (optional)"POST"The HTTP method to use for notifications: "GET", "POST" or "PUT"
path (optional)"/"The path to use for notifications (E.g. "/phenix/callback")
query (optional)emptyThe query parameters (E.g. "param1=true&param2=false&param3")

Response

The platform will return a successful response that contains a "status" field. The HTTP status code is set according to the status field.

HTTP
1HTTP/1.1 200 OK
2Content-Type: application/json; charset=utf-8
3Content-Length: 107
4
5{"status":"ok","endpoint":"POST https://webhook.site:443/1234abcd-1234-6789-0123-abcdef123456?param1=true"}
cURL
1{
2 "status": "ok",
3 "endpoint": "POST https://webhook.site:443/1234abcd-1234-6789-0123-abcdef123456?param1=true"
4}

Status Codes

HTTPStatusRetryDescription
200 OKokneverStream was successfully terminated.
400 Bad RequestvariesneverIndicates an issue with the request itself.
401 UnauthorizedunauthorizedneverThe streaming platform was not able to authorize the provided credentials.
4XXvariesneverIndicates an issue with the request itself.
503 Service UnavailablecapacityonceThe system is temporarily overloaded. Please try again later.
5XXvariesonce immediately, then exponential backoffA transient server error.

Response Fields

FieldDescription
statusThe status code
endpointThe resolved end point to confirm your settings were applied as intended.

Notification Types

The streaming platform notifies the callback endpoint when certain platform events occur.

Event NameDescription
Stream StartedTriggers when a new stream is published
Stream EndedTriggers when a published stream ends
Live AvailableTriggers when a live playlist of a published stream is ready
On-Demand AvailableTriggers when a on-demand playlist of a published stream is ready

We will be using the callback.method of POST in the examples for each notification type below. However "GET", "POST" or "PUT" are fully supported.

Debugging Notifications
Consider the webhook.site online tool if you need a way to debug callbacks from our platform.

Stream Started Notification

HTTP
1POST <callback.path> HTTP/1.1
2Host: <callback.host>:<callback.port>
3Content-Type: application/json
4Content-Length: 250
5
6{
7 "apiVersion": 0,
8 "entity", "stream",
9 "what", "started",
10 "data": {
11 "streamId": "<streamId>",
12 "tags": [
13 "<tag>"
14 ]
15 },
16 "sessionId": "<sessionId>",
17 "timestamp": "2019-01-23T21:12:55.384Z"
18}
cURL
1$ curl <callback.url> \
2-H "Content-Type: application/json" \
3-X POST \
4-d '{
5 "apiVersion": 0,
6 "entity", "stream",
7 "what", "started",
8 "data": {
9 "streamId": "<streamId>",
10 "tags": [
11 "<tag>"
12 ]
13 },
14 "sessionId": "<sessionId>",
15 "timestamp": "2019-01-23T21:12:55.384Z"
16 }'

The Content-Length header is automatically populated by curl. If using another method to access the API, you must calculate and populate the Content-Length header.

Request Fields

FieldDescription
apiVersionThe API version the message conforms to
entityBelongs to the "stream" entity
whatThe type is "started" indicating that the stream started
dataThe notification payload
data.streamIdThe ID of the stream that started
data.tagsArray of string tags provided when publishing the stream. The order of tags may be different than the order of tags provided during publishing.
sessionIdThe session ID of the client this stream belongs to
timestampThe RFC3339 timestamp of when the request was initiated in Zulu time

Stream Ended Notification

HTTP
1POST <callback.path> HTTP/1.1
2Host: <callback.host>:<callback.port>
3Content-Type: application/json
4Content-Length: 304
5
6{
7 "apiVersion": 0,
8 "entity", "stream",
9 "what", "ended",
10 "data": {
11 "streamId": "<streamId>",
12 "tags": [
13 "<tag>"
14 ]
15 "duration": 11457,
16 "reason": "<reason>"
17 },
18 "sessionId": "<sessionId>",
19 "timestamp": "2019-01-23T21:12:55.384Z"
20}
cURL
1$ curl <callback.url> \
2-H "Content-Type: application/json" \
3-X POST \
4-d '{
5 "apiVersion": 0,
6 "entity", "stream",
7 "what", "ended",
8 "data": {
9 "streamId": "<streamId>",
10 "tags": [
11 "<tag>"
12 ]
13 "duration": 11457,
14 "reason": "<reason>"
15 },
16 "sessionId": "<sessionId>",
17 "timestamp": "2019-01-23T21:12:55.384Z"
18 }'

The Content-Length header is automatically populated by curl. If using another method to access the API, you must calculate and populate the Content-Length header.

Request Fields

FieldDescription
apiVersionThe API version the message conforms to
entityBelongs to the "stream" entity
whatThe type is "ended" indicating that the stream ended
dataThe notification payload
data.streamIdThe ID of the stream that started
data.tagsArray of string tags provided when publishing the stream
data.durationDuration of the stream in milliseconds
data.reasonThe reason the stream ended which may be an empty string or a custom reason
sessionIdThe session ID of the client this stream belongs to
timestampThe RFC3339 timestamp of when the request was initiated in Zulu time

Live Available Notification

Reach devices with adaptive multi-bitrate live streaming capabilities. Currently HLS and MPEG-DASH playlists in adaptive multi-bitrate and various quality levels are supported.

This also makes the stream available inside all our SDKs using the streaming capability when subscribing.

There is one event for each available playlists, e.g. adaptive multi-bitrate and each quality level.
HTTP
1POST <callback.path> HTTP/1.1
2Host: <callback.host>:<callback.port>
3Content-Type: application/json
4Content-Length: 222
5
6{
7 "apiVersion": 0,
8 "entity", "stream",
9 "what", "live",
10 "data": {
11 "streamId": "<streamId>",
12 "uri": "<uri>"
13 },
14 "sessionId": "<sessionId>",
15 "timestamp": "2019-01-23T21:12:55.384Z"
16}
cURL
1$ curl <callback.url> \
2-H "Content-Type: application/json" \
3-X POST \
4-d '{
5 "apiVersion": 0,
6 "entity", "stream",
7 "what", "live",
8 "data": {
9 "streamId": "<streamId>",
10 "uri": "<uri>",
11 "isPrimary": true,
12 "isVariant": false
13 },
14 "sessionId": "<sessionId>",
15 "timestamp": "2019-01-23T21:12:55.384Z"
16 }'

The Content-Length header is automatically populated by curl. If using another method to access the API, you must calculate and populate the Content-Length header.

Request Fields

FieldDescription
apiVersionThe API version the message conforms to
entityBelongs to the "stream" entity
whatType "live" indicates a live playlist is available
dataThe notification payload
data.streamIdThe ID of the stream that started
data.uriThe URI of the playlist. File extensions: HLS -> .m3u8, MPEG-DASH -> .mpd
data.isPrimaryWhether this is a primary playlist containing variant playlists
data.isVariantWhether this is a variant playlist (Note: This flag is currently wrong. Use isPrimary until it is fixed.)
sessionIdThe session ID of the client this stream belongs to
timestampThe RFC3339 timestamp of when the request was initiated in Zulu time

On-demand Available Notification

Provide adaptive multi-bitrate on-demand streaming capabilities. Currently HLS and MPEG-DASH playlists as adaptive multi-bitrate and specific quality levels are supported.

This also makes the stream available inside all our SDKs using the "on-demand" capability when subscribing.

There is one event for each available playlists, e.g. adaptive multi-bitrate and each quality level.
HTTP
1POST <callback.path> HTTP/1.1
2Host: <callback.host>:<callback.port>
3Content-Type: application/json
4Content-Length: 227
5
6{
7 "apiVersion": 0,
8 "entity", "stream",
9 "what", "on-demand",
10 "data": {
11 "streamId": "<streamId>",
12 "uri": "<uri>",
13 "isPrimary": true,
14 "isVariant": false
15 },
16 "sessionId": "<sessionId>",
17 "timestamp": "2019-01-23T21:12:55.384Z"
18}
cURL
1$ curl <callback.url> \
2-H "Content-Type: application/json" \
3-X POST \
4-d '{
5 "apiVersion": 0,
6 "entity", "stream",
7 "what", "on-demand",
8 "data": {
9 "streamId": "<streamId>",
10 "uri": "<uri>"
11 },
12 "sessionId": "<sessionId>",
13 "timestamp": "2019-01-23T21:12:55.384Z"
14 }'

The Content-Length header is automatically populated by curl. If using another method to access the API, you must calculate and populate the Content-Length header.

Request Fields

FieldDescription
apiVersionThe API version the message conforms to
entityBelongs to the "stream" entity
whatType "on-demand" indicates a on-demand playlist is available
dataThe notification payload
data.streamIdThe ID of the stream that started
data.uriThe URI of the playlist. File extensions: HLS -> .m3u8, MPEG-DASH -> .mpd
data.isPrimaryWhether this is a primary playlist containing variant playlists
data.isVariantWhether this is a variant playlist (Note: This flag is currently wrong. Use isPrimary until it is fixed.)
sessionIdThe session ID of the client this stream belongs to
timestampThe RFC3339 timestamp of when the request was initiated in Zulu time
Note on 5XX Errors
The notification service will automatically retry any 5XX HTTP errors using an exponential back-off algorithm. The first back-off is 3 seconds, the second one is 6 seconds and so on. At most 9 retries will be performed which amounts to a maximum of 25 minutes until a request is dropped.
Order of Notifications
Due to the nature of distributed environments and various effects including retries of transient errors, it's possible that notifications are delivered out of natural order. For example, it is possible that you receive a stream ended notification before the corresponding stream started notification. Please make sure that your business logic can handle out-of-order notifications.
Note On API version
It is expected that your application can handle any new fields inside a message and any new notification types without a corresponding increment of the "apiVersion" field.

Web Hook Security

HMAC Authentication

You can authenticate notifications by using the HMAC-SHA256 authentication scheme. HMAC refers to hash-based message authentication code.

To authenticate a notification, you must assert that it contains valid X-PCast-Content-Sha256 and Authorization headers.

Notification Headers

HeaderDescription
AuthorizationAuthentication information required by the HMAC-SHA256 scheme.
Content-TypeIndicates the original media type before any content encoding was applied for sending.
X-PCast-Content-Sha256Base64 encoded SHA256 hash of the request body.
X-PCast-TimestampThe RFC3339 timestamp of when the request was initiated in UNIX time.

Validate X-PCast-Content-Sha256

To validate X-PCast-Content-Sha256 header you need to stringify the request body, and generate a SHA-265 hash from it. Then you need to compare generated hash with the hash in X-PCast-Content-Sha256.

JavaScript
1//Validate X-PCast-Content-Sha256
2function isContentSha256Valid(requestStringBody, contentSha256Header) {
3 var generatedContentHash = crypto
4 .createHash('sha256')
5 .update(requestStringBody)
6 .digest('base64');
7
8 return contentSha256Header === generatedContentHash;
9}

Validate Authorization Header

The Authorization header consists of the HMAC hash of the request prefixed with HMAC-SHA256.

Authorization = 'HMAC-SHA256 ' + hash (HMAC created using the SHA-256 hash algorithm with the application secret as key).

To validate the HMAC hash of the Authorization header you must compare it with the one regenerated from the canonical representation of the request using your application secret as a key.

String-To-Sign = HTTP_METHOD + path_and_query + content_sha256_header + content_type_header + pcast_timestamp_header

JavaScript
1// Generate string to sign
2function getStringToSign(
3 method,
4 path,
5 contentSha256,
6 contentType,
7 unixTimestamp
8) {
9 return method + path + contentSha256 + contentType + unixTimestamp;
10}
JavaScript
1// Validate Authorization header
2function isAuthorizationHeaderValid(secret, stringToSign, authorizationHeader) {
3 var generatedHmacSha256Hash =
4 'HMAC-SHA256 ' +
5 crypto.createHmac('sha256', secret).update(stringToSign).digest('base64');
6
7 return generatedHmacSha256Hash === authorizationHeader;
8}
Page Content
    Copyright 2023 © Phenix RTS
    Privacy Policy | Terms of Service
    v2023-01-31T21:25:10