RTMP servers

The RTMP servers section covers the endpoints used to provision and operate long-lived RTMP ingest endpoints in Callaba Engine. This is the layer you use when OBS, software encoders, or external publishers should push RTMP into one managed listener.

Compared with SRT-focused sections, RTMP servers are simpler on the transport side but stronger on packaging and controlled ingest. The create and update calls shape the listen port, player buffer length, and optional allowed-stream rules, while the runtime layer generates the nginx RTMP config plus the related HLS and DASH output directories for the server.

The operational methods complete that lifecycle. Use start and stop to toggle the runtime process, getAll and getCount for list views, and getById when you need the populated allowed-stream records attached to a specific RTMP ingest point.

If your team drives RTMP server lifecycle actions from an operator workflow, the create, start, and stop examples below now also include ready-to-adapt vMix Script tabs alongside the usual API snippets.

Workflow examples

These scenarios frame why an RTMP server exists in a production design, not only what the create payload looks like.

Use an RTMP server as the stable ingest boundary for OBS or software encoders

Create an RTMP server when publishers should push to one fixed RTMP endpoint and the downstream distribution chain may evolve later.

  • Module chain: Publisher / OBS / encoder -> MODULE_RTMP_SERVERS
  • Why it helps: the ingest port, player buffer policy, and stream-access rules live in one reusable server object.
  • Operational fit: recurring live inputs, demo environments, or any setup where the ingest address should stay stable.

Use an RTMP server when publisher and receiver access should be explicit

RTMP servers are also a good fit when the ingress point should actively control who may publish or receive.

  • Control layer: stream_control_type + access_settings
  • Why it helps: you can seed stream-key or IP-based rules together with the server instead of managing ad hoc access later.
  • Good fit for: shared operators, partner publishers, and controlled internal preview endpoints.

Use an RTMP server when HLS and DASH packaging should come with the ingest point

The RTMP server service does more than store a port. It generates the runtime RTMP config and prepares the related HLS and DASH output folders under the VOD path.

  • Why it helps: the ingest endpoint and the packaging output stay tied to the same server lifecycle.
  • What to remember: create/update/start regenerate runtime config, while stop/remove tear the generated config back down.
  • Typical fit: browser playback, embedded players, and packaged replay paths built from RTMP ingest.
Create RTMP server
Collapse
POST
/api/rtmp-servers/create

Creates a new RTMP server resource in Callaba Engine.

The current Swagger definition exposes this method as POST /api/rtmp-servers/create with an application/json request body. The field names and example payload below are aligned with the live dashboard form and the backend validation rules.

This method does more than reserve a port. The service persists the RTMP server object, assigns the TCP listen port, generates the nginx RTMP config, prepares the HLS and DASH output directories for the server, and reloads the HTTP runtime config.

At the API and dashboard layer, server_buflen is expressed in seconds. The form defaults to 5, and the validated contract allows values from 1 to 120.

If you include stream_control_type and access_settings, the backend also creates the related allowed-stream records. One current live nuance matters here: create still returns access: [] on the top-level server object even when access rules were created. Use getById when you need the populated access list immediately after provisioning.

Authentication uses the dashboard-issued JWT token in the x-access-token header.

If this provisioning step is triggered from an operator toolchain, the preset examples below also expose a vMix Script tab so the same RTMP server creation shapes can be adapted for button or shortcut workflows.

Examples by preset

The examples below are grouped by the preset families that matter most when creating an RTMP server: a basic open ingest listener, a server restricted by explicit stream keys, and a server restricted by fixed IP addresses.

That preset-driven shape is easier to work with than one oversized request body because it mirrors the real control choices a team makes at provisioning time.

Workflow-oriented use cases

These examples help frame why the RTMP server should exist in the pipeline, not only how to shape the request body.

Provision a reusable ingest point for OBS or another software encoder

Use this pattern when an encoder should push RTMP into one stable listener and the downstream chain may change later.

  • Module chain: Publisher / OBS / encoder -> MODULE_RTMP_SERVERS
  • Why teams use it: the listen port and playback buffering policy live in one reusable ingest object.
  • What stays stable: RTMP ingest address, port ownership, and the packaging boundary behind it.

Provision a controlled ingest point with explicit stream access

Use this pattern when the RTMP boundary should decide who may publish or receive before traffic reaches the rest of the stack.

  • Control layer: stream_control_type + access_settings
  • Why teams use it: stream keys or IP-based allowlists are created together with the server instead of being tracked manually later.
  • Typical fit: shared studios, partner handoffs, and internal preview flows where anonymous publish access is not acceptable.

Provision an ingest point that should also own HLS and DASH output setup

Use this pattern when the RTMP server should be the place where ingest and packaging begin together.

  • Runtime side effect: config generation + HLS/DASH output directory preparation
  • Why teams use it: playback packaging stays tied to the ingest server lifecycle instead of being bolted on later.
  • Good fit for: embedded players, replay paths, and packaged browser playback built from RTMP input.
Allow only specified stream keys

Use this pattern when publishers and receivers should authenticate with explicit RTMP stream keys instead of open ingest. It mirrors the dashboard preset that seeds one publisher key and one receiver key.

Allow only specified stream keys
curl --request POST \
--url http://localhost/api/rtmp-servers/create \
--header 'x-access-token: <your_api_token>' \
--header 'Content-Type: application/json' \
--data '{
"server_name": "Live Protected",
"server_type": "SERVER_TYPE_RTMP",
"server_port": 1945,
"server_buflen": 5,
"server_active": true,
"stream_control_type": "CONTROL_ACCESS_STREAM_ID",
"access_settings": [
{
"stream_id": "rtmp-stream-01",
"role_name": "publisher"
},
{
"stream_id": "rtmp-stream-01",
"role_name": "receiver"
}
]
}'
Allow only specified IP addresses

Use this pattern when the RTMP peers are known fixed hosts. The dashboard preset creates publisher and receiver rules keyed by host instead of stream id.

Allow only specified IP addresses
curl --request POST \
--url http://localhost/api/rtmp-servers/create \
--header 'x-access-token: <your_api_token>' \
--header 'Content-Type: application/json' \
--data '{
"server_name": "Live Allowlisted",
"server_type": "SERVER_TYPE_RTMP",
"server_port": 1945,
"server_buflen": 5,
"server_active": true,
"stream_control_type": "CONTROL_ACCESS_IP_ADDRESS",
"access_settings": [
{
"host": "127.0.0.1",
"role_name": "publisher"
},
{
"host": "127.0.0.1",
"role_name": "receiver"
}
]
}'
Request body parameters
Basic settings
server_name
string

Dashboard label: Name.

The form defaults to Live. Validation requires a non-empty value and rejects slashes.

server_type
string

Current validated API contract accepts SERVER_TYPE_RTMP.

server_active
boolean

Dashboard label: Enable once created.

Enabled is the server state. Turning it off disconnects all publishers and receivers attached to the RTMP server.

Runtime settings
server_port
integer

Dashboard label: Port.

The dashboard default is 1945. The frontend validation currently accepts values from 1945 to 65535, while the backend validator accepts 1 to 65535.

server_buflen
integer

Dashboard label: Buffer length (s).

This value is configured in seconds at the API/form layer. The dashboard default is 5 and the current validation range is 1 to 120.

Internally, the RTMP layer uses this to shape player buffering before playback starts.

Access control
stream_control_type
string

Dashboard section: Allowed streams.

Controls whether the RTMP server validates incoming publishers and receivers by explicit stream key or by host allowlist. The live create flow currently uses values such as CONTROL_ACCESS_STREAM_ID and CONTROL_ACCESS_IP_ADDRESS.

access_settings
array

Optional set of access rules to create together with the server.

For stream-key mode, each item typically contains stream_id and role_name. For IP-based mode, each item uses host and role_name.

Create RTMP server
curl --request POST \
--url http://localhost/api/rtmp-servers/create \
--header 'x-access-token: <your_api_token>' \
--header 'Content-Type: application/json' \
--data '{
"server_name": "Live",
"server_type": "SERVER_TYPE_RTMP",
"server_port": 1945,
"server_buflen": 5,
"server_active": true
}'
Response
Identity and runtime
_id
string

Mongo-style identifier of the RTMP server.

id
string

Convenience alias for _id.

server_name
string

Name stored for the RTMP server.

server_type
string

Type of the server. The live product returns SERVER_TYPE_RTMP.

server_port
string

Listening RTMP port returned by the product.

server_buflen
integer

Configured RTMP buffer length.

server_active
boolean

Current running state flag stored on the server object.

server_port_id
string

Port document attached to the RTMP listener.

server_created
string

Creation timestamp.

server_modified
string

Last modification timestamp.

Access control
stream_control_type
string

Access-control mode stored on the RTMP server, when provided.

access
array

The live create response currently returns this as an empty array even when access_settings were submitted. Use getById to retrieve the populated related access records.

Operation result
success
boolean

The model exposes success: true as a virtual field in successful responses.

Response: Create RTMP server
JSON
{
"_id": "69c1fb0128c95839e0e022d5",
"__v": 0,
"access": [],
"server_active": true,
"server_buflen": 5,
"server_created": "2026-03-24T02:46:25.044Z",
"server_name": "Docs RTMP Server",
"server_port": "1945",
"server_type": "SERVER_TYPE_RTMP",
"server_user_id": "69360341db559495f643de6a",
"server_port_id": "69c1fb0128c95839e0e022d7",
"server_modified": "2026-03-24T02:46:25.056Z",
"id": "69c1fb0128c95839e0e022d5",
"success": true
}
Get RTMP servers count
Expand
POST
/api/rtmp-servers/getCount

Returns the number of RTMP server records visible to the current token context.

The live product returns a bare count object such as { count: 0 }, without an additional wrapper field.

Request body parameters
This method has no parameters
Get RTMP servers count
curl --request POST \
--url http://localhost/api/rtmp-servers/getCount \
--header 'x-access-token: <your_api_token>' \
--header 'Content-Type: application/json' \
--data '{}'
Response
count
integer

The live product returns a bare count object such as { count: 1 }.

Response: Get RTMP servers count
JSON
{
"count": 1
}
Get all RTMP servers
Expand
POST
/api/rtmp-servers/getAll

Returns the RTMP server list for the current user context.

The request body can include pagination and sorting fields. The dashboard store uses { server_created: 1 } as the default sort order.

The live product returns a bare array of RTMP server objects. Unlike getById, this list response does not populate the related access records.

Request body parameters
limit
integer

Optional page size for the list query.

skip
integer

Optional offset for paginated listing.

sort
object

Optional sort descriptor. The dashboard store defaults to { server_created: 1 }.

filter
object

Optional filter object forwarded to the backend query.

Get all RTMP servers
curl --request POST \
--url http://localhost/api/rtmp-servers/getAll \
--header 'x-access-token: <your_api_token>' \
--header 'Content-Type: application/json' \
--data '{
"limit": 10,
"skip": 0,
"sort": {
"server_created": 1
}
}'
Response
array of RTMP server objects
array

The live product returns a bare array, not a wrapped object. Each item follows the same top-level shape as the create/update/start/stop response.

Response: Get all RTMP servers
JSON
[
{
"_id": "69c1fb0128c95839e0e022d5",
"__v": 0,
"access": [],
"server_active": true,
"server_buflen": 5,
"server_created": "2026-03-24T02:46:25.044Z",
"server_name": "Docs RTMP Server",
"server_port": "1945",
"server_type": "SERVER_TYPE_RTMP",
"server_user_id": "69360341db559495f643de6a",
"server_port_id": "69c1fb0128c95839e0e022d7",
"server_modified": "2026-03-24T02:46:25.056Z",
"id": "69c1fb0128c95839e0e022d5",
"success": true
}
]
Get RTMP server by id
Expand
POST
/api/rtmp-servers/getById

Loads one RTMP server by id.

This is the method to use when you need the full RTMP server object together with the populated access list.

That distinction matters in practice: the live create response can still show access: [] even when access rules were created, while getById resolves and returns the related stream records.

Request body parameters
id
string

Identifier of the RTMP server to load.

Get RTMP server by id
curl --request POST \
--url http://localhost/api/rtmp-servers/getById \
--header 'x-access-token: <your_api_token>' \
--header 'Content-Type: application/json' \
--data '{
"id": "69c1fb0128c95839e0e022d5"
}'
Response
Server object
server fields
object

The top-level RTMP server fields match the create response shape.

Populated access list
access[]
array

Unlike the live create response, getById populates the related access records.

access[].role_name
string

Role attached to the access record, for example publisher or receiver.

access[].stream_id
string

RTMP stream key when stream-id based access control is used.

access[].host
string

Allowed host when IP-based access control is used.

access[].name
string

Human-readable stream/access label generated by the backend, such as Server name: publisher.

Response: Get RTMP server by id
JSON
{
"_id": "69c1fb2f28c95839e0e02359",
"__v": 0,
"access": [
{
"_id": "69c1fb2f28c95839e0e0235e",
"__v": 0,
"active": true,
"audio_settings": {
"streams": []
},
"created": "2026-03-24T02:47:11.807Z",
"entityModel": "RTMPServerModel",
"entity_id": "69c1fb2f28c95839e0e02359",
"host": "",
"module_name": "MODULE_RTMP_SERVERS",
"name": "Docs RTMP Protected: publisher",
"role_name": "publisher",
"stream_id": "rtmp-stream-01",
"user_id": "69360341db559495f643de6a",
"id": "69c1fb2f28c95839e0e0235e",
"success": true
},
{
"_id": "69c1fb2f28c95839e0e02361",
"__v": 0,
"active": true,
"audio_settings": {
"streams": []
},
"created": "2026-03-24T02:47:11.807Z",
"entityModel": "RTMPServerModel",
"entity_id": "69c1fb2f28c95839e0e02359",
"host": "",
"module_name": "MODULE_RTMP_SERVERS",
"name": "Docs RTMP Protected: receiver",
"role_name": "receiver",
"stream_id": "rtmp-stream-01",
"user_id": "69360341db559495f643de6a",
"id": "69c1fb2f28c95839e0e02361",
"success": true
}
],
"server_active": true,
"server_buflen": 5,
"server_created": "2026-03-24T02:47:11.801Z",
"server_name": "Docs RTMP Protected",
"server_port": "1946",
"server_type": "SERVER_TYPE_RTMP",
"server_user_id": "69360341db559495f643de6a",
"stream_control_type": "CONTROL_ACCESS_STREAM_ID",
"server_modified": "2026-03-24T02:47:11.804Z",
"server_port_id": "69c1fb2f28c95839e0e0235b",
"id": "69c1fb2f28c95839e0e02359",
"success": true
}
Update RTMP server
Expand
POST
/api/rtmp-servers/update

Updates an existing RTMP server.

The update contract mirrors the create contract, but includes the server id. Internally, the service reuses the same validation and persistence path as create, then regenerates the RTMP config for the saved server object.

Use this method when you need to change the listen port, player buffer length, active state, or allowed-stream policy without deleting and recreating the ingest boundary.

Request body parameters
id
string

Identifier of the RTMP server being updated.

server_name / server_port / server_buflen / server_active
mixed

The update contract mirrors create. The service reuses the same validation path and regenerates the RTMP config after the document is saved.

Update RTMP server
curl --request POST \
--url http://localhost/api/rtmp-servers/update \
--header 'x-access-token: <your_api_token>' \
--header 'Content-Type: application/json' \
--data '{
"id": "69c1fb0128c95839e0e022d5",
"server_name": "Live Updated",
"server_type": "SERVER_TYPE_RTMP",
"server_port": 1945,
"server_buflen": 7,
"server_active": false
}'
Response
updated RTMP server object
object

The live product returns the updated server object on the top level together with success: true.

Response: Update RTMP server
JSON
{
"_id": "69c1fb0128c95839e0e022d5",
"__v": 0,
"access": [],
"server_active": false,
"server_buflen": 7,
"server_created": "2026-03-24T02:46:25.044Z",
"server_name": "Live Updated",
"server_port": "1945",
"server_type": "SERVER_TYPE_RTMP",
"server_user_id": "69360341db559495f643de6a",
"server_port_id": "69c1fb0128c95839e0e022d7",
"server_modified": "2026-03-24T02:46:25.056Z",
"id": "69c1fb0128c95839e0e022d5",
"success": true
}
Start RTMP server
Expand
POST
/api/rtmp-servers/start

Starts an RTMP server by id.

The backend flips server_active to true, regenerates the runtime RTMP config for the saved server object, and returns that updated object on the top level of the response.

Use this method when the RTMP ingest point should come back online without changing the rest of its persisted configuration.

If this action is triggered from an operator workflow, the example set below also includes a vMix Script tab.

Request body parameters
id
string

Identifier of the RTMP server to start.

Start RTMP server
curl --request POST \
--url http://localhost/api/rtmp-servers/start \
--header 'x-access-token: <your_api_token>' \
--header 'Content-Type: application/json' \
--data '{
"id": "69c1fb0128c95839e0e022d5"
}'
Response
started RTMP server object
object

The backend flips server_active to true, regenerates the RTMP config, and returns the server object.

Response: Start RTMP server
JSON
{
"_id": "69c1fb0128c95839e0e022d5",
"__v": 0,
"access": [],
"server_active": true,
"server_buflen": 5,
"server_created": "2026-03-24T02:46:25.044Z",
"server_name": "Docs RTMP Server",
"server_port": "1945",
"server_type": "SERVER_TYPE_RTMP",
"server_user_id": "69360341db559495f643de6a",
"server_port_id": "69c1fb0128c95839e0e022d7",
"server_modified": "2026-03-24T02:46:25.056Z",
"id": "69c1fb0128c95839e0e022d5",
"success": true
}
Stop RTMP server
Expand
POST
/api/rtmp-servers/stop

Stops an RTMP server by id.

The backend flips server_active to false, removes the generated RTMP config and related runtime artifacts for the server, and returns the updated server object.

This is the operational off switch when the ingest boundary should go offline but remain available for a later start.

If this action is triggered from an operator workflow, the example set below also includes a vMix Script tab.

Request body parameters
id
string

Identifier of the RTMP server to stop.

Stop RTMP server
curl --request POST \
--url http://localhost/api/rtmp-servers/stop \
--header 'x-access-token: <your_api_token>' \
--header 'Content-Type: application/json' \
--data '{
"id": "69c1fb0128c95839e0e022d5"
}'
Response
stopped RTMP server object
object

The backend flips server_active to false, removes the generated RTMP config, and returns the server object.

Response: Stop RTMP server
JSON
{
"_id": "69c1fb0128c95839e0e022d5",
"__v": 0,
"access": [],
"server_active": false,
"server_buflen": 5,
"server_created": "2026-03-24T02:46:25.044Z",
"server_name": "Docs RTMP Server",
"server_port": "1945",
"server_type": "SERVER_TYPE_RTMP",
"server_user_id": "69360341db559495f643de6a",
"server_port_id": "69c1fb0128c95839e0e022d7",
"server_modified": "2026-03-24T02:46:25.056Z",
"id": "69c1fb0128c95839e0e022d5",
"success": true
}
Remove RTMP server
Expand
DELETE
/api/rtmp-servers/remove

Deletes an RTMP server by id.

Removal also clears the generated runtime config and the related HLS/DASH output directories created for that RTMP server.

The current live product returns an empty 201 response body on success, so treat the HTTP status as the success signal here.

Query parameters
id
string

Identifier of the RTMP server to delete.

Remove RTMP server
curl --request DELETE \
--url http://localhost/api/rtmp-servers/remove \
--header 'x-access-token: <your_api_token>' \
--header 'Content-Type: application/json' \
--data '{
"id": "69c1fb0128c95839e0e022d5"
}'
Response
empty 201 response body
none

The live product currently returns an empty response body on successful removal.

Response: Remove RTMP server
JSON