- API Guides
- API workflow guides
- Build with the Channels API
- Create and manage channels
Create and manage channels
Channels are created with PUT /channels/{channel_id}/, where {channel_id} is the channel name you choose. The same request creates a channel that does not exist and replaces one that does, so there is no separate create endpoint and no generated identifier to keep track of.
Read How Beam channels work first if you have not picked a spec.type yet, because that choice constrains everything else in the body.
Read the interfaces first
Section titled “Read the interfaces first”Channel inputs and outputs point at real ports on the device, so start by asking the device what it has:
curl <BASE_URL>/interfaces/The response groups interfaces by kind. This is a response from a VEGA-7010, abbreviated to the first two of its four slot ports, with the addresses replaced:
{ "ip": [ { "name": "lo", "type": "IP", "ipAddresses": ["127.0.0.1"], "displayName": "lo" }, { "name": "eth0", "type": "IP", "ipAddresses": ["10.0.0.10"], "displayName": "eth0" }, { "name": "eth1", "type": "IP", "ipAddresses": ["172.16.0.10"], "displayName": "eth1" } ], "sdi": [ { "name": "slot_1_port_1", "type": "SDIASI", "url": "sdi://localhost/slot_1_port_1", "displayName": "Slot 1 / Port 1" }, { "name": "slot_1_port_2", "type": "SDIASI", "url": "sdi://localhost/slot_1_port_2", "displayName": "Slot 1 / Port 2" } ], "asi": [ { "name": "slot_1_port_1", "type": "SDIASI", "url": "asi://localhost/slot_1_port_1", "displayName": "Slot 1 / Port 1" }, { "name": "slot_1_port_2", "type": "SDIASI", "url": "asi://localhost/slot_1_port_2", "displayName": "Slot 1 / Port 2" } ], "rf_demod": [], "rf_modulator": [], "st2110": []}What a device returns depends entirely on the hardware fitted to it. The device above has no satellite demodulator or modulator, so rf_demod and rf_modulator are empty. Another device will list different slots, different port counts, and different groups, which is why this call belongs at the start of any integration rather than in your notes.
Network transports take an interface name, such as eth0. Baseband and RF transports take the url exactly as returned.
Copy the url rather than composing it. The same physical port is listed under both sdi and asi with the same name, and only the scheme in the url distinguishes them. A name on its own does not identify a port.
Read the groups you need by key and ignore the rest, rather than assuming a fixed set. The groups a device returns can differ from the ones documented in the Channels API reference.
Create a channel
Section titled “Create a channel”This request creates a contribution channel that takes a Serial Digital Interface (SDI) source, encodes it, and publishes it as a Secure Reliable Transport (SRT) listener that a remote decoder can connect to. It is created stopped, so nothing goes on air until you ask it to.
curl -X PUT <BASE_URL>/channels/news-contribution/ \ -H "Content-Type: application/json" \ -d '{ "kind": "BeamChannel", "metadata": { "name": "news-contribution", "displayName": "News contribution" }, "spec": { "type": "EncodingContribution", "state": "Stopped", "inputs": [ { "type": "SDI", "name": "sdi-in", "transport": { "url": "sdi://localhost/slot_1_port_1" } } ], "transform": { "encoding": { "video": { "codec": "H264High", "videoFormat": "1920x1080p", "bitrate": 15000000 }, "audios": [ { "codec": "AC3", "mode": "Stereo", "bitrate": 128000 } ] } }, "outputs": [ { "type": "SRTListener", "transport": { "interface": "eth0", "port": 9000 } } ] } }'The fields that are easy to get wrong:
- Set
metadata.nameto the same value as the{channel_id}in the path. It is the identifier you use in every later request, and it cannot be changed afterwards. Any string works, so a readable slug such asnews-contributionis easier to live with than a generated identifier. Channels created through the Essentials UI are named with a UUID instead, so expect both forms when you list a device you did not set up. - Each entry in
inputsneeds its ownname. This is your label for the input, and it is how the audio entries intransform.encoding.audiosrefer back to it throughinputName. The device assigns its own separate name to the input instatus, so do not expect this value to appear there. bitrateis in bits per second and accepts100000to60000000. Audiobitrateis also in bits per second, and the accepted values depend on the audio codec and mode.porton an SRT listener accepts256to65535.- Outputs take no
name, unlike inputs. The one exception is anASIoutput, wherenameis optional. The device names every output itself instatusregardless.
The response is the full channel object, including the metadata.created timestamp and an initial status.
A 200 here means the device accepted the configuration, not that the channel is configured. Confirm the result:
curl <BASE_URL>/channels/news-contribution/Read status.syncState. It reports Configuring while the device applies the change and Ok once the running configuration matches your spec. Anything else means the configuration was accepted but could not be applied, and status.syncError carries the detail.
Choosing between variants
Section titled “Choosing between variants”The body above is one shape of channel. Use this table to find the shape you need, then adapt the example:
| Your situation | spec.type | Body differences |
|---|---|---|
| Encoding a baseband source for onward contribution | EncodingContribution | Requires transform.encoding. Video codecs are the 4:2:2 and JPEG XS profiles, plus H264High and its variants. |
| Encoding a baseband source for delivery to viewers | EncodingDistribution | Requires transform.encoding. Video codecs are the delivery profiles: HEVCMain, HEVCMain10bit, H264High, H264Main, and MPEG2. |
| Encoding a baseband source into adaptive bitrate output | EncodingStreaming | Requires transform.abrEncoding instead of transform.encoding. The only output type is HttpStreaming. |
| Receiving a stream and putting it back to baseband | ReceptionDecoding | No transform. Outputs are SDI or Smpte2110. |
| Receiving a stream and passing it on untouched | ReceptionGateway | No transform. Outputs are the transport types, as for contribution. |
A reception channel is considerably shorter, because there is nothing to encode. This one takes a multicast UDP source and decodes it out of an SDI port, and starts immediately:
curl -X PUT <BASE_URL>/channels/udp-to-sdi/ \ -H "Content-Type: application/json" \ -d '{ "kind": "BeamChannel", "metadata": { "name": "udp-to-sdi", "displayName": "UDP to SDI decoder" }, "spec": { "type": "ReceptionDecoding", "state": "Running", "inputs": [ { "type": "UDP", "name": "udp-in", "transport": { "url": "udp://239.100.1.1:5001", "interface": "eth0" } } ], "outputs": [ { "type": "SDI", "transport": { "url": "sdi://localhost/slot_1_port_1" } } ] } }'A UDP input needs both a url and an interface, because the device has to know which network port to join the multicast group on. Set unicast to true if the source is a unicast stream.
For the full list of input and output schemas, including SMPTE 2110 and satellite demodulator inputs, see the Channels API reference.
Encrypting an SRT output
Section titled “Encrypting an SRT output”To encrypt an SRT output, set encryptionStandard to AES128, AES192, or AES256, and supply a passphrase of at least 10 characters:
{ "type": "SRTListener", "transport": { "interface": "eth0", "port": 9000, "encryptionStandard": "AES128", "passPhrase": "<PASSPHRASE>" }}passPhrase is optional while encryptionStandard is None, which is the default, and required as soon as it is anything else. A passphrase shorter than 10 characters is rejected.
Start, stop, and rename
Section titled “Start, stop, and rename”PATCH /channels/{channel_id}/ handles the two changes you make most often. It accepts only the desired state and the display name, so use PUT for anything else.
Start a channel:
curl -X PATCH <BASE_URL>/channels/news-contribution/ \ -H "Content-Type: application/json" \ -d '{ "spec": { "state": "Running" } }'Send "Stopped" in the same shape to take it off air. Rename it with the other half of the body:
curl -X PATCH <BASE_URL>/channels/news-contribution/ \ -H "Content-Type: application/json" \ -d '{ "metadata": { "displayName": "News contribution, main feed" } }'Both fields are nested under spec and metadata respectively. A flat body such as {"state": "Running"} does not change anything, because neither key is recognised at the top level.
Renaming changes displayName only. metadata.name is fixed for the life of the channel, so a channel that needs a different identifier has to be recreated.
Delete a channel
Section titled “Delete a channel”curl -X DELETE <BASE_URL>/channels/news-contribution/A successful delete returns 204 with no body. The device stops the underlying services before removing the channel. Errors during that cleanup are logged on the device but do not stop the channel being removed, so a 204 confirms the channel is gone rather than that everything behind it shut down cleanly.
What goes wrong
Section titled “What goes wrong”The request succeeded but nothing is on air. Check spec.state. A channel created with "state": "Stopped" stays stopped until you patch it. If it is Running, check status.syncState and status.syncError.
A codec value is rejected. The accepted video codecs depend on spec.type. HEVCMain is valid for EncodingDistribution and EncodingStreaming but not for EncodingContribution, which takes the 4:2:2 profiles. The accepted videoFormat values then depend on the codec you chose, and the interlaced formats are not available with the progressive-only codecs such as JPEG XS.
An audio bitrate is rejected. Audio bitrate is constrained by codec and mode together. AC3 with Stereo starts at 96000, while AC3 with Surround51 starts at 224000.
A PUT removed settings you did not send. PUT replaces the channel rather than merging into it. Fetch the channel, change what you need in the returned spec, and send the whole spec back.
The response is 422. The body contains a detail array, and each entry has a loc array giving the exact path to the offending field. Read loc before anything else, because it points straight at the field name.
The response is 503. The channel endpoints return 503 when the API cannot serve the request. Retry, and if it persists, check the device itself.
Where to go deeper
Section titled “Where to go deeper”- Monitor channels and devices covers reading status, alarms, and thumbnails once a channel exists.
- Beam Essentials UI walks the same configuration through the channel creation wizard, which is a useful way to see a valid combination before you script it.
- Channels API reference holds the complete
ChannelSpecschema, including every input and output variant.