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.
These scenarios frame why an RTMP server exists in a production design, not only what the create payload looks like.
Create an RTMP server when publishers should push to one fixed RTMP endpoint and the downstream distribution chain may evolve later.
Publisher / OBS / encoder -> MODULE_RTMP_SERVERSRTMP servers are also a good fit when the ingress point should actively control who may publish or receive.
stream_control_type + access_settingsThe 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.
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.
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.
These examples help frame why the RTMP server should exist in the pipeline, not only how to shape the request body.
Use this pattern when an encoder should push RTMP into one stable listener and the downstream chain may change later.
Publisher / OBS / encoder -> MODULE_RTMP_SERVERSUse this pattern when the RTMP boundary should decide who may publish or receive before traffic reaches the rest of the stack.
stream_control_type + access_settingsUse this pattern when the RTMP server should be the place where ingest and packaging begin together.
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.
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"}]}'
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.
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"}]}'
Dashboard label: Name.
The form defaults to Live. Validation requires a non-empty value and rejects slashes.
Current validated API contract accepts SERVER_TYPE_RTMP.
Dashboard label: Enable once created.
Enabled is the server state. Turning it off disconnects all publishers and receivers attached to the RTMP server.
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.
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.
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.
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.
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}'
Mongo-style identifier of the RTMP server.
Convenience alias for _id.
Name stored for the RTMP server.
Type of the server. The live product returns SERVER_TYPE_RTMP.
Listening RTMP port returned by the product.
Configured RTMP buffer length.
Current running state flag stored on the server object.
Port document attached to the RTMP listener.
Creation timestamp.
Last modification timestamp.
Access-control mode stored on the RTMP server, when provided.
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.
The model exposes success: true as a virtual field in successful responses.
{"_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}
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.
curl --request POST \--url http://localhost/api/rtmp-servers/getCount \--header 'x-access-token: <your_api_token>' \--header 'Content-Type: application/json' \--data '{}'
The live product returns a bare count object such as { count: 1 }.
{"count": 1}
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.
Optional page size for the list query.
Optional offset for paginated listing.
Optional sort descriptor. The dashboard store defaults to { server_created: 1 }.
Optional filter object forwarded to the backend query.
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}}'
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.
[{"_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}]
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.
Identifier of the RTMP server to load.
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"}'
The top-level RTMP server fields match the create response shape.
Unlike the live create response, getById populates the related access records.
Role attached to the access record, for example publisher or receiver.
RTMP stream key when stream-id based access control is used.
Allowed host when IP-based access control is used.
Human-readable stream/access label generated by the backend, such as Server name: publisher.
{"_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}
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.
Identifier of the RTMP server being updated.
The update contract mirrors create. The service reuses the same validation path and regenerates the RTMP config after the document is saved.
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}'
The live product returns the updated server object on the top level together with success: true.
{"_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}
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.
Identifier of the RTMP server to start.
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"}'
The backend flips server_active to true, regenerates the RTMP config, and returns the server object.
{"_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}
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.
Identifier of the RTMP server to stop.
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"}'
The backend flips server_active to false, removes the generated RTMP config, and returns the server object.
{"_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}
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.
Identifier of the RTMP server to delete.
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"}'
The live product currently returns an empty response body on successful removal.