API integration¶
An external system can create streams and channels, assign subscriptions and obtain URLs for a viewer application. The two examples below take you from creating a stream to obtaining a subscriber playback URL.
Open the API reference¶
The reference is embedded in your Catena installation. Open it from the console, or replace https://catena.example.com with your installation address:
- Central API —
https://catena.example.com/central/api-v4/docs/: stream configuration and cluster management. - Catena API —
https://catena.example.com/catena/api-v1/docs/: channels, packages and subscribers. - Catena TV API —
https://catena.example.com/catena/api-v1/docs/tv/: viewer sign-in and accessible channels. - Playback API —
https://catena.example.com/central/api-v4/docs/playback/: media playback.
Each page provides search and Download OpenAPI JSON. The schema belongs to the installed build. Reference pages open without authentication when their API prefix is exposed; management requests themselves require authentication.
Entities and authentication¶
- Stream stores broadcast settings. A channel stores the storefront title and number, references a stream through
stream_name, and belongs to packages. - Operator credentials authenticate requests to the Central and Catena APIs. The examples use HTTP Basic; send the password over HTTPS.
- Device token is returned when a subscriber signs in through the TV API. Send it in subsequent requests as
Authorization: Bearer …. The subscriber also has a separateplayback_token, which the TV API accepts to identify the subscriber. - Playback ticket is already included in the
playback_urlreturned by the TV API. You do not need to pass device tokens or the operator password to the player.
Before you start¶
Before you start, prepare:
- Bash — to run the examples in one session.
- curl — to send HTTP requests.
- jq — to construct and read JSON.
- An operator account with permission to change settings.
Run both examples in the same Bash session: the second uses variables from the first. These commands create test records in your installation; use a test environment. Password input is hidden and passwords are not written into commands.
Create a stream and channel¶
Set BASE and API_USER for your installation. The example creates a disabled stream without a source (enabled: false), so you can check API operations without starting a broadcast. If-None-Match: * prevents overwriting an existing stream with the same name.
set -euo pipefail
BASE='https://catena.example.com'
API_USER='admin'
read -r -s -p 'Operator password: ' API_PASSWORD
printf '\n'
BASE="${BASE%/}"
STREAM="api-example-$(date +%s)"
curl -fsS -u "$API_USER:$API_PASSWORD" \
-X PUT "$BASE/central/api-v4/streams/configs/$STREAM" \
-H 'Content-Type: application/json' \
-H 'If-None-Match: *' \
-d '{"title":"Integration example","enabled":false}'
CHANNEL=$(
jq -n --arg stream "$STREAM" \
'{title:"Example channel",number:1,stream_name:$stream}' |
curl -fsS -u "$API_USER:$API_PASSWORD" \
-X POST "$BASE/catena/api-v1/channels" \
-H 'Content-Type: application/json' --data-binary @-
)
CHANNEL_ID=$(printf '%s' "$CHANNEL" | jq -er '.id')
CHANNEL=$(
curl -fsS -u "$API_USER:$API_PASSWORD" \
"$BASE/catena/api-v1/channels/$CHANNEL_ID"
)
VERSION=$(printf '%s' "$CHANNEL" | jq -er '.version')
curl -fsS -u "$API_USER:$API_PASSWORD" \
-X PATCH "$BASE/catena/api-v1/channels/$CHANNEL_ID" \
-H 'Content-Type: application/json' \
-H "If-Match: \"$VERSION\"" \
-d '{"title":"Updated example channel"}' | jq .
The channel creation response contains its id. Before editing, read the channel and take its version: for this resource, the ETag is the quoted version. PATCH sends only the new title; the stream reference is preserved.
Assign a subscription and obtain a URL¶
Continue in the same session. Enter a test subscriber password of at least eight characters. Create a package that requires a subscription (free: false), add the channel to it, and subscribe the subscriber to the package. Then sign in as the viewer. Package names must contain 2 to 20 characters: Latin letters, digits, hyphens or underscores.
read -r -s -p 'Subscriber password: ' SUB_PASSWORD
printf '\n'
LOGIN="api-$(date +%s)"
PACKAGE=$(
jq -n --arg name "$LOGIN" '{name:$name,free:false}' |
curl -fsS -u "$API_USER:$API_PASSWORD" \
-X POST "$BASE/catena/api-v1/packages" \
-H 'Content-Type: application/json' --data-binary @-
)
PACKAGE_ID=$(printf '%s' "$PACKAGE" | jq -er '.id')
jq -n --arg p "$PACKAGE_ID" --arg c "$CHANNEL_ID" \
'{package_id:$p,channel_id:$c}' |
curl -fsS -u "$API_USER:$API_PASSWORD" \
-X POST "$BASE/catena/api-v1/package-channels" \
-H 'Content-Type: application/json' --data-binary @-
SUBSCRIBER=$(
curl -fsS -u "$API_USER:$API_PASSWORD" \
-X POST "$BASE/catena/api-v1/subscribers" \
-H 'Content-Type: application/json' \
-d '{"name":"Integration example"}'
)
SUBSCRIBER_ID=$(printf '%s' "$SUBSCRIBER" | jq -er '.id')
jq -n --arg login "$LOGIN" --arg password "$SUB_PASSWORD" \
'{login:$login,password:$password}' |
curl -fsS -u "$API_USER:$API_PASSWORD" \
-X PATCH "$BASE/catena/api-v1/subscribers/$SUBSCRIBER_ID/credentials" \
-H 'Content-Type: application/json' --data-binary @- >/dev/null
jq -n --arg s "$SUBSCRIBER_ID" --arg p "$PACKAGE_ID" \
'{subscriber_id:$s,package_id:$p}' |
curl -fsS -u "$API_USER:$API_PASSWORD" \
-X POST "$BASE/catena/api-v1/subscriptions" \
-H 'Content-Type: application/json' --data-binary @-
SESSION=$(
jq -n --arg login "$LOGIN" --arg password "$SUB_PASSWORD" \
'{login:$login,password:$password,device_name:"Example app"}' |
curl -fsS -X POST "$BASE/playback/tv/login" \
-H 'Content-Type: application/json' --data-binary @-
)
DEVICE_TOKEN=$(printf '%s' "$SESSION" | jq -er '.token')
curl -fsS "$BASE/playback/tv/channels" \
-H "Authorization: Bearer $DEVICE_TOKEN" |
jq --arg id "$CHANNEL_ID" \
'.channels[] | select(.id == $id) | {title,playback_url}'
The last request prints the channel title and playback_url, a path from the installation root with the ticket already included. Prepend BASE to obtain an absolute URL. Request /playback/tv/channels again to obtain a current ticket. GET /playback/tv/channels/{channel_id}/play with viewer authentication returns 307 and a Location header containing the playback URL.
Playback requirements¶
Obtaining a URL confirms that the subscriber has access to the channel. To watch video, configure the stream source, enable the stream and check its placement on a streamer. This example leaves the stream disabled. Video access settings are described under playback protection and Catena tickets.
Handle errors¶
- 401 — check the operator credentials or viewer token. The management and TV APIs use different credentials.
- 412 — the record has changed. Read it again and review its current values before sending another PATCH with the new version.
- 422 — inspect
error.errors: each entry contains apathto the invalid field and amessage. For example, a string instead of an integer innumberreturns the path["number"].
A channel appears for a subscriber if it belongs to a subscribed package or a free package. In this example, the channel is absent before the subscription is assigned. See subscriber access rules.
Delete test records¶
After checking the examples, run these commands in the same session. They delete the records created above; subscriptions and package-channel links are removed by cascade.
curl -fsS -u "$API_USER:$API_PASSWORD" \
-X DELETE "$BASE/catena/api-v1/subscribers/$SUBSCRIBER_ID"
curl -fsS -u "$API_USER:$API_PASSWORD" \
-X DELETE "$BASE/catena/api-v1/packages/$PACKAGE_ID"
curl -fsS -u "$API_USER:$API_PASSWORD" \
-X DELETE "$BASE/catena/api-v1/channels/$CHANNEL_ID"
curl -fsS -u "$API_USER:$API_PASSWORD" \
-X DELETE "$BASE/central/api-v4/streams/configs/$STREAM"