---
title: Creating a Source, Channel, and Target
slug: zen-master-api/creating-a-source-channel-and-target
docTags: 
createdAt: 2025-06-30T17:13:19.600Z
---

To help you get started with the ZEN Master API, we will walk through some common tasks here:

- Create a Source
- Create a Channel
- Create a Target

Because there are many ways to use REST APIs, we will do this in two different ways: first, we will create the objects using the popular REST client Postman; next, we will complete the same tasks using a Python script.

## Prerequisites

### General

- Access to the ZEN Master API
- An API key
- The ZEN Master API Reference (find it in the Documents section of the [Customer Portal](https://portal.zixi.com/my-documents))
- A [cluster](docId\:NJaOz_85Pcy2-QxgUYjSO)  with at least one [Broadcaster](docId\:xYscySO498lY77ZjQr-51) set up in ZEN Master

### For the Postman section

- [Postman](https://www.postman.com/) - you can use either the desktop or online version

If you haven't already set up a ZEN Master API collection in Postman, follow the instructions in [Step 2 - Getting Started with Postman](docId:8rVjfs6-skYEDlJ8WpYf7).

### For the Python section

- [Python](https://www.python.org/) installed on your system

## Postman Instructions

:::hint{type="info"}
Note: you should look at the API Reference for each of the requests. We will only be including required fields here, but there are many more.
:::

### Get IDs that will be needed for other requests

First we will get `id` values for the Broadcaster, Cluster and other objects that will be required for the API requests that we will be making.

::::WorkflowBlock
:::WorkflowBlockItem
Get the `id` for your Broadcaster Cluster by going to the **clusters >&#x20;**`GET`**&#x20;List all Clusters** request in Postman:

::Image[]{src="https://api.archbee.com/api/optimize/amUtKWPrNQCS-26DKyGuI-Aa0e4xIbeVJ1-6NP276ui-20250701-192722.png" size="46" width="772" height="796" position="center" alt="GET Clusters Request" showCaption="false"}
:::

:::WorkflowBlockItem
Uncheck all the request **parameters -&#x20;**&#x75;nless you know the ***exact*** name of your Cluster, in which case you can set that as the value of the `name` parameter to return just that object:

![Request Parameters](https://api.archbee.com/api/optimize/amUtKWPrNQCS-26DKyGuI-WcX-3TARy1rUW-bXTlI1g-20250701-193623.png)
:::

:::WorkflowBlockItem
With or without the `name` parameter, click **Send** to **submit** the request.
:::

:::WorkflowBlockItem
If you used the `name` parameter, there should be just one object in the response. If not, you will get all the cluster objects, but you can find the one you are looking for by searching the response JSON for some portion of the Cluster name:

![Searching in the Postman Response](https://api.archbee.com/api/optimize/amUtKWPrNQCS-26DKyGuI-VpUfaB8zVcdtA-c92uOgC-20250701-194007.png)
:::

:::WorkflowBlockItem
Save the Cluster `id` for use in steps below.
:::

:::WorkflowBlockItem
Now do the same for **Broadcasters:&#x20;**`GET`**&#x20;broadcasters**, using the **name** parameter if you have the exact name, or find it in the list and save its `id` as well:

::Image[]{src="https://api.archbee.com/api/optimize/amUtKWPrNQCS-26DKyGuI-g9xub0coWy0YYPCC_NbNg-20250702-135115.png" size="58" width="1272" height="1062" position="center" alt="GET Broadcasters" showCaption="false"}
:::

:::WorkflowBlockItem
You also need to `GET` or create a Tag `id`. To do this, go to the **tags** section of the API and either `GET` a list of all tags and choose one, or use the `POST` request to create a new one. If you create a new one, just go to the **Body** of the `POST`request and enter a `name` for the tag. You will find the `id` for the Tag in the response after you send the request.

![Create tag Request Body](https://api.archbee.com/api/optimize/amUtKWPrNQCS-26DKyGuI-b4tGnXii_vJ3bjAhYGjus-20250702-163554.png)
:::

:::WorkflowBlockItem
Next, you will need an `alerting_profile_id` , which is the same thing as an event profile `id`.  Go to **events>profiles>**`GET`**&#x20;List all Events Profiles** and send the request. Save the `id` for the **Default** profile - it will probably be the first one, though it will probably *not* have the `id` you see below.

![Default Events Profile](https://api.archbee.com/api/optimize/amUtKWPrNQCS-26DKyGuI-O7ssfrA_Lov4-TX4wnMN1-20250702-164915.png)
:::
::::

Now you have all the information you need to go on and create your source, channel, and targets.

### Create the source

::::WorkflowBlock
:::WorkflowBlockItem
Now go to **sources>fileUrl>**`POST`**&#x20;Create File URL Source**.

::Image[]{src="https://api.archbee.com/api/optimize/amUtKWPrNQCS-26DKyGuI-eviBhM24m9RlLCfo55utb-20250702-135842.png" size="32" width="554" height="1464" position="center" alt="fileUrl POST Request" showCaption="false"}
:::

:::WorkflowBlockItem
Go to the **Body** tab and replace the JSON there with the following:

```json
{
  "broadcaster_cluster_id": YOUR_CLUSTER_ID,
  "name": "Test Source PM",
  "protocol": "http_file",
  "resource_tag_ids": [
    YOUR_TAG_ID
  ],
  "target_broadcaster_id": YOUR_BROADCASTER_ID,
  "type": "file",
  "url": "https://zixi-file-sources.s3.amazonaws.com/ts/bbb_AVC_420_8bit_1080p60.ts",
  "alerting_profile_id": YOUR_ALERTING_PROFILE_ID
}
```
:::

:::WorkflowBlockItem
Replace the values in ALL\_CAPS with the `id` values you obtained in the previous section and remove all additional values so that your request body looks something like this:

![Sample Request Body for Create Source](https://api.archbee.com/api/optimize/amUtKWPrNQCS-26DKyGuI-Xl8mlS4abaLu3Uae9MZrn-20250702-192442.png)
:::

:::WorkflowBlockItem
You should see a **success** response - if you get an error instead, check the request body to make sure you put in the correct `id` values for the tag, alerting profile, cluster, and Broadcaster.
:::

:::WorkflowBlockItem
When you get a success response, save the returned source `id` as you will need it for the next section.
:::
::::

### Create a pass-through channel

:::::WorkflowBlock
:::WorkflowBlockItem
Go to **channels>passthrough>**`POST`**&#x20;Create a new Pass-Through Channel**:

::Image[]{src="https://api.archbee.com/api/optimize/amUtKWPrNQCS-26DKyGuI-oUePsQ6FJVm7uR1JFAMhT-20250703-155949.png" size="46" width="756" height="1068" position="center" alt="Create Pass-Through Channel Request" showCaption="false"}
:::

::::WorkflowBlockItem
Go to the **Body** tab and replace the JSON there with the following:

```json
{
    "name": "Test Channel PM",
    "resource_tag_ids": [
        YOUR_TAG_ID
    ],
    "alerting_profile_id": YOUR_ALERTING_PROFILE_ID,
    "broadcaster_cluster_id": YOUR_CLUSTER_ID,
    "target_broadcaster_id": YOUR_BROADCASTER_ID,
    "sources": [
        {
            "primary": true,
            "source_id": THE_ID_OF_THE_SOURCE_YOU_CREATED
        }
    ]
}
```

:::hint{type="info"}
If you forgot to save the source `id`, you can find it using a `GET`**&#x20;List Sources** request and searching the results for the source name.
:::


::::

:::WorkflowBlockItem
Replace the values in ALL\_CAPS with the `id` values you obtained in the previous section, so that your request body looks something like this:

::Image[]{src="https://api.archbee.com/api/optimize/amUtKWPrNQCS-26DKyGuI-zF7Hk8RerDy5L4DWRboNY-20250703-160517.png" size="80" width="1288" height="864" position="center" alt="Create Channel Request Body" showCaption="false"}
:::

:::WorkflowBlockItem
You should see a **success** response - if you get an error instead, check the request body to make sure you put in the correct `id` values for the source, tag, alerting profile, cluster, and Broadcaster.
:::

:::WorkflowBlockItem
When you get a success response, save the returned channel `id` as you will need it for the next section.
:::
:::::

### Create a UDP target

:::::WorkflowBlock
:::WorkflowBlockItem
Go to **targets>urd\_rtp>**`POST`**&#x20;Create a new UDP/RTP Target**:

::Image[]{src="https://api.archbee.com/api/optimize/amUtKWPrNQCS-26DKyGuI-kbRCBvFFpFwg-UaoIld2w-20250703-180747.png" size="46" width="602" height="490" position="center" alt="Create UDP/RTP Target" showCaption="false"}
:::

::::WorkflowBlockItem
Go to the **Body** tab and replace the JSON there with the following:

```json
{
    "name": "Test Target PM",
    "resource_tag_ids": [
        YOUR_TAG_ID
    ],
    "alerting_profile_id": YOUR_ALERTING_PROFILE_ID,
    "rtp": false,
    "host": "127.0.0.1",
    "port": 5001,
    "passthrough_channel_id": THE_ID_OF_THE_CHANNEL_YOU_CREATED
}
```

:::hint{type="info"}
Note that the host value of 127.0.0.1 is the localhost IP - this assumes that the Broadcaster you are working with is installed on the same machine you are working on. If that is not the case, you will need to use `GET`**&#x20;List Broadcasters** to get the Broadcaster objects again, find your Broadcaster, and get the value of the `source_ip` field in the response.
:::


::::

::::WorkflowBlockItem
Replace the values in ALL\_CAPS with the `id` values you obtained in the previous section, so that your request body looks something like this:

::Image[]{src="https://api.archbee.com/api/optimize/amUtKWPrNQCS-26DKyGuI-Uid7R7AjHLwhn5eoC_LVH-20250703-191528.png" size="64" width="1028" height="820" position="center" alt="Create Target Request Body" showCaption="false"}

:::hint{type="info"}
If you forgot to save the channel `id`, you can find it using a `GET`**&#x20;List Pass-Through Channels** request and searching the results for the channel name.
:::
::::

:::WorkflowBlockItem
You should see a **success** response - if you get an error instead, check the request body to make sure you put in the correct `id` values for the channel, tag, and alerting profile.
:::
:::::

## Python Instructions

The beauty of REST APIs is that you can automate your requests using any language that supports HTTP requests - NodeJS, Java, Swift, whatever you use.

Here we are going to use the popular Python language. Rather than build a script from scratch, we're just going to give you one that is very flexible and that you can use for any ZEN Master API request(s):

```python
# Create Source, Channel, and Target
print("Tech Week: Create Source, Channel, Targets")

import requests
import json

#########################################
# Class for ZM API requests
#########################################

class APIClient:
  def __init__(self, baseUrl, headers):
    self.baseUrl = baseUrl
    self.headers = headers

  def make_request(self, method, endpoint, payload):
    url = self.baseUrl + endpoint
    response = requests.request(method, url, headers=self.headers, data=payload)

    # Parse the JSON response into a Python dictionary
    data = response.json()
    print(f"API request method: {method} success: {data['success']}")
    print(f"Object ID: {data['result']['id']}")
    print(f"Object name: {data['result']['name']}")
    return data

#########################################
# ZEN Master environment
#########################################

baseUrl = "https://api.zen.zixi.com/v2"
apiKey = 'YOUR_API_KEY

headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'charset': 'UTF-8',
  'x-api-key': apiKey
}

client = APIClient(baseUrl, headers)

#########################################
# Create File URL Source
#########################################

endpoint = "/sources"

payload = json.dumps({
  "name": "Test Source Python",
  "resource_tag_ids": [
    YOUR_TAG_ID
  ],
  "alerting_profile_id": YOUR_ALERTING_PROFILE_ID,
  "broadcaster_cluster_id": YOUR_CLUSTER_ID,
  "target_broadcaster_id": YOUR_BROADCASTER_ID,
  "protocol": "http_file",
  "type": "file",
  "url": "https://zixi-file-sources.s3.amazonaws.com/ts/bbb_AVC_420_8bit_1080p60.ts"
})

# response = requests.request("POST", url, headers=headers, data=payload)
data = client.make_request("POST", endpoint, payload)
sourceId = data['result']['id']
print(f"Create File URL Source ID: {sourceId}")

#########################################
# Create Pass-Through Channel 
#########################################

endpoint = "/channels/passthrough"

payload = json.dumps({
  "name": "Test Channel Python",
  "resource_tag_ids": [
    YOUR_TAG_ID
  ],
  "alerting_profile_id": YOUR_ALERTING_PROFILE_ID,
  "broadcaster_cluster_id": YOUR_CLUSTER_ID,
  "target_broadcaster_id": YOUR_BROADCASTER_ID,
  "sources": [
    {
      "primary": True,
      "source_id": sourceId
    }
  ]
})

data = client.make_request("POST", endpoint, payload)
channelId = data['result']['id']
print(f"Create Pass-Through Channel ID: {channelId}")


#########################################
# Create UDP Target (2)
#########################################

endpoint = "/targets/udp_rtp"

payload = json.dumps({
  "name": "Test Target Python",
  "resource_tag_ids": [
    YOUR_TAG_ID
  ],
  "alerting_profile_id": YOUR_ALERTING_PROFILE_ID,
  "rtp": False,
  "host": "127.0.0.1",
  "port": 5001,
  "passthrough_channel_id": channelId
})

data = client.make_request("POST", endpoint, payload)

#########################################
# End
#########################################
```

As with the Postman requests, you will need to replace the ALL\_CAPS values with your own (but not the source and channel ids, as the script captures those from the responses). See the first section under Postman Instructions above to get the tag, alerting profile, cluster, and Broadcaster ids.

Note that the first two sections of the script define a class for submitting requests and parsing responses, and then to define the ZEN Master Envoronment. The sections after that define the endpoints and request bodies for each request, and then invoke the `client` object to make the request.

You can **run** the script in on a command line by navigating to the folder where saved the edited script and running:

```python
python3 {script_name}.py
```

You may need to install the Python **requests** and/or **json** modules, which the script imports.
