Recordings

The Recordings section covers the API endpoints for production recording jobs in Callaba Engine: managed jobs that take a live source, optionally process it, and write durable media outputs for archive, compliance, replay prep, or segmented post-event workflows.

Choose Recordings when the outcome you care about is stored media: the right files, in the right format, created at the right time, and available for operators to inspect or clean up during and after an event.

Choose Restreams instead when the same live input should be sent onward to another live destination. Both modules can use the same kinds of inputs and can apply transcoding, audio or video modifications, and overlays, but they serve different operational goals: Restreams is for live delivery, while Recordings is for managed file creation and retention.

  • Use this module to control capture windows: create jobs ahead of time, then start and stop them from automation or an operator position.
  • Use this module to monitor active recordings: check whether a recorder is running, whether the incoming live signal still looks healthy, and whether output is progressing as expected.
  • Use this module to manage recorded artifacts: review produced files, remove the wrong file without deleting the whole job, and keep archive workflows operationally clean.

This makes the module useful not only for setup, but for real-time production operations where teams need confidence that a live contribution is still being captured and that the expected files will exist when the event ends.

If your team starts and stops recording jobs from a live operator position, the create, start, and stop examples below also include ready-to-adapt vMix Script tabs.

Live recording runtime preview

getStat is where a recording job becomes operational instead of merely configured. It is the fastest check for whether media is still arriving, whether encode speed is keeping up with the event, and whether output time is still advancing the way the archive plan expects.

The preview below mirrors the same runtime fields documented for getStat: bitrate, frame cadence, encode speed, and output progress. Use it when the main question is not “does the job exist?” but “is this recording still becoming the archive we expect?”

Recording runtime

See the signals operators watch while a recording job is running

The getStat response for recordings is more than a simple heartbeat. It tells you whether media is still arriving, whether encode speed is keeping up, and whether output time keeps moving the way the archive plan expects.

Runtime preview
getStat field shape
Process view

bitrate_kbits

Previewing the same runtime signal operators usually inspect first.

1,842 kbits/s
out_time_ms
17:00:00
speed
1.00x
updated
1:55:30 AM
Operational signals
bitrate_kbits

1,842 kbits/s

A quick signal that media is still arriving before you inspect produced files.

fps

25.0

Useful when the archive must preserve the same cadence the live source promised.

speed

1.00x

If speed falls behind too far, the recording job may not keep up with a real-time event.

progress

continue

17:00:00 written · 395.6 MB

In practice, operators pair these runtime fields with start and stop controls to confirm that the capture window is still producing a usable archive, not just holding an object in the list.

Examples by preset

The most useful presets for this module are recording workflows rather than transport families alone: one continuous archive, one segmented archive, or one output format selected for playback and storage needs.

These examples keep the input on SRT Stream URL (srt://) for clarity, but the same recording object is also used in the product for SRT server, RTMP server, video call room or participant, and URL-based sources such as HLS, MPEG-DASH, RTSP, RTP, UDP, and RIST.

SRT URL to MP4 archive

{
  "recording_name": "Main program archive",
  "recording_type": "RECORDING_STREAM_TO_FILE",
  "input": {
    "input_type": "INPUT_TYPE_SRT_URL",
    "application": "IO_APPLICATION_FFMPEG",
    "input_stream_url": "srt://127.0.0.1:1935",
    "input_stream_listen_port": {},
    "input_settings": {},
    "input_module_id": "",
    "input_stream_id": "",
    "entity_name": "Main program archive",
    "module_name": "MODULE_RECORDINGS"
  },
  "output_format": "mp4",
  "recording_mode": "RECORDING_MODE_INFINITY",
  "recording_mode_settings": {
    "hours": 0,
    "minutes": 0,
    "seconds": 0
  },
  "transcoding": {
    "video_transcoding": "Disabled",
    "output_video_bitrate": 6000,
    "preset": "ultrafast",
    "tune": "Disabled",
    "crf": "Disabled",
    "pix_fmt": "Disabled",
    "encoding_rate": "",
    "filter_fps": "",
    "gop": "Disabled",
    "force_key_frames": 2,
    "frame_width": "",
    "frame_height": "",
    "slices": "",
    "cores": "",
    "xlnx_hwdev": "0",
    "audio_transcoding": "aac",
    "output_audio_bitrate": 128,
    "sample_rate": 44100
  },
  "modify_audio": {
    "type": "DISABLED",
    "channel": "1,2",
    "track": "0"
  },
  "modify_video": {
    "type": "DISABLED"
  },
  "overlay": {
    "type": "DISABLED",
    "position": {
      "x": 1,
      "y": 1
    }
  },
  "delete_after": 0,
  "active": true
}

SRT URL to split-by-time archive

{
  "recording_name": "Program segments every 10 minutes",
  "recording_type": "RECORDING_STREAM_TO_FILE",
  "input": {
    "input_type": "INPUT_TYPE_SRT_URL",
    "application": "IO_APPLICATION_FFMPEG",
    "input_stream_url": "srt://127.0.0.1:1935",
    "input_stream_listen_port": {},
    "input_settings": {},
    "input_module_id": "",
    "input_stream_id": "",
    "entity_name": "Program segments every 10 minutes",
    "module_name": "MODULE_RECORDINGS"
  },
  "output_format": "mp4",
  "recording_mode": "RECORDING_MODE_SPLIT_BY_TIME",
  "recording_mode_settings": {
    "hours": 0,
    "minutes": 10,
    "seconds": 0
  },
  "transcoding": {
    "video_transcoding": "Disabled",
    "output_video_bitrate": 6000,
    "preset": "ultrafast",
    "tune": "Disabled",
    "crf": "Disabled",
    "pix_fmt": "Disabled",
    "encoding_rate": "",
    "filter_fps": "",
    "gop": "Disabled",
    "force_key_frames": 2,
    "frame_width": "",
    "frame_height": "",
    "slices": "",
    "cores": "",
    "xlnx_hwdev": "0",
    "audio_transcoding": "aac",
    "output_audio_bitrate": 128,
    "sample_rate": 44100
  },
  "modify_audio": {
    "type": "DISABLED",
    "channel": "1,2",
    "track": "0"
  },
  "modify_video": {
    "type": "DISABLED"
  },
  "overlay": {
    "type": "DISABLED",
    "position": {
      "x": 1,
      "y": 1
    }
  },
  "delete_after": 0,
  "active": true
}

SRT URL to HLS recording

{
  "recording_name": "HLS archive output",
  "recording_type": "RECORDING_STREAM_TO_FILE",
  "input": {
    "input_type": "INPUT_TYPE_SRT_URL",
    "application": "IO_APPLICATION_FFMPEG",
    "input_stream_url": "srt://127.0.0.1:1935",
    "input_stream_listen_port": {},
    "input_settings": {},
    "input_module_id": "",
    "input_stream_id": "",
    "entity_name": "HLS archive output",
    "module_name": "MODULE_RECORDINGS"
  },
  "output_format": "m3u8",
  "recording_mode": "RECORDING_MODE_INFINITY",
  "recording_mode_settings": {
    "hours": 0,
    "minutes": 0,
    "seconds": 0
  },
  "transcoding": {
    "video_transcoding": "Disabled",
    "output_video_bitrate": 6000,
    "preset": "ultrafast",
    "tune": "Disabled",
    "crf": "Disabled",
    "pix_fmt": "Disabled",
    "encoding_rate": "",
    "filter_fps": "",
    "gop": "Disabled",
    "force_key_frames": 2,
    "frame_width": "",
    "frame_height": "",
    "slices": "",
    "cores": "",
    "xlnx_hwdev": "0",
    "audio_transcoding": "aac",
    "output_audio_bitrate": 128,
    "sample_rate": 44100
  },
  "modify_audio": {
    "type": "DISABLED",
    "channel": "1,2",
    "track": "0"
  },
  "modify_video": {
    "type": "DISABLED"
  },
  "overlay": {
    "type": "DISABLED",
    "position": {
      "x": 1,
      "y": 1
    }
  },
  "delete_after": 0,
  "active": true
}

Workflow examples

These scenarios frame why a recording job exists in a production design, not only how the request body is shaped.

Use a recording job when a live contribution should become a durable archive

Create a recording when the main goal is to preserve a source stream as a file rather than forward it to another live destination.

  • Why it helps: the recorder keeps the source, processing settings, output format, and produced files under one managed job.
  • Typical fit: event archive capture, program backup, and operational compliance recording.

Use a recording job when file segmentation matters as much as the source

Recording mode changes the way files are produced. Some workflows need one continuous file, while others need predictable time-based segments for storage, post-production, or downstream automation.

  • Key controls: recording_mode, recording_mode_settings, and output_format
  • Typical fit: long events, auto-rotated archive windows, and HLS-style capture workflows.

This matters in production because some teams need one continuous archive while others need predictable clip boundaries they can review, move, or publish quickly after the event.

Use a recording job when operations need both live process status and stored file management

The module is not only about creating files. It also has lifecycle controls and file cleanup actions through start, stop, getStat, and removeFile.

  • Why it helps: one API object covers capture, running state, progress polling, and the resulting recorded files.
  • Operational fit: recurring productions, rolling capture jobs, and post-event file housekeeping.

That same workflow also includes auto deletion after N days and a product-facing seamless recording feature for maintaining one continuous recording even when a source is interrupted and resumed.

Create recording
Collapse
POST
/api/recording/create

Creates a new recording job in Callaba Engine.

This method creates one managed recording job. In practice, that means choosing the live source, the file shape you need at the end, and the recording behavior that fits the event you are trying to capture.

The payload is intentionally broad because recording decisions are rarely just about starting capture. Teams also decide file format, clip strategy, optional processing, and how much they want the stored output shaped before it lands.

The key production decisions here are easy to state even if the payload is large: what file should come out, whether capture should run continuously or in clips, and how long the result should stay around afterward.

Although the examples below keep the source on SRT Stream URL (srt://) for readability, the same method also supports product-facing inputs such as SRT server, RTMP server, video call room or participant, and URL-driven inputs like HLS, MPEG-DASH, RTSP, RTP, UDP, and RIST.

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

Examples by preset

The examples below are grouped by recording presets rather than by one oversized payload. That makes them easier to reuse for real archive and capture workflows.

Workflow-oriented use cases

Use a recording job when the destination should be stored media, not another live endpoint.

  • Good fit for: event archives, backup captures, split recordings, HLS recording outputs, and file-based post-event workflows.
  • Not the same as: a live transport bridge like Restreams or a stable ingest boundary like SRT servers.

Once the job is running, operators usually care about three things first: whether recording is active, what bitrate and FPS the process is reporting, and how many files have already been produced.

Continuous archive

Use this preset when the main goal is one stable archive file from a live SRT contribution.

SRT URL to MP4 archive

This is the most common recording shape: preserve the incoming stream as one continuous archive and keep the processing layer minimal.

SRT URL to MP4 archive
curl --request POST \
--url http://localhost/api/recording/create \
--header 'x-access-token: <your_api_token>' \
--header 'Content-Type: application/json' \
--data '{
"recording_name": "Main program archive",
"recording_type": "RECORDING_STREAM_TO_FILE",
"input": {
"input_type": "INPUT_TYPE_SRT_URL",
"application": "IO_APPLICATION_FFMPEG",
"input_stream_url": "srt://127.0.0.1:1935",
"input_stream_listen_port": {},
"input_settings": {},
"input_module_id": "",
"input_stream_id": "",
"entity_name": "Main program archive",
"module_name": "MODULE_RECORDINGS"
},
"output_format": "mp4",
"recording_mode": "RECORDING_MODE_INFINITY",
"recording_mode_settings": {
"hours": 0,
"minutes": 0,
"seconds": 0
},
"transcoding": {
"video_transcoding": "Disabled",
"output_video_bitrate": 6000,
"preset": "ultrafast",
"tune": "Disabled",
"crf": "Disabled",
"pix_fmt": "Disabled",
"encoding_rate": "",
"filter_fps": "",
"gop": "Disabled",
"force_key_frames": 2,
"frame_width": "",
"frame_height": "",
"slices": "",
"cores": "",
"xlnx_hwdev": "0",
"audio_transcoding": "aac",
"output_audio_bitrate": 128,
"sample_rate": 44100
},
"modify_audio": {
"type": "DISABLED",
"channel": "1,2",
"track": "0"
},
"modify_video": {
"type": "DISABLED"
},
"overlay": {
"type": "DISABLED",
"position": {
"x": 1,
"y": 1
}
},
"delete_after": 0,
"active": true
}'
Segmented archive

Use this preset when long captures should be cut into predictable time windows for storage, automation, or post-production.

SRT URL to split-by-time archive

The recording mode changes from one continuous file to rolling segments while keeping the rest of the capture pipeline largely the same.

SRT URL to split-by-time archive
curl --request POST \
--url http://localhost/api/recording/create \
--header 'x-access-token: <your_api_token>' \
--header 'Content-Type: application/json' \
--data '{
"recording_name": "Program segments every 10 minutes",
"recording_type": "RECORDING_STREAM_TO_FILE",
"input": {
"input_type": "INPUT_TYPE_SRT_URL",
"application": "IO_APPLICATION_FFMPEG",
"input_stream_url": "srt://127.0.0.1:1935",
"input_stream_listen_port": {},
"input_settings": {},
"input_module_id": "",
"input_stream_id": "",
"entity_name": "Program segments every 10 minutes",
"module_name": "MODULE_RECORDINGS"
},
"output_format": "mp4",
"recording_mode": "RECORDING_MODE_SPLIT_BY_TIME",
"recording_mode_settings": {
"hours": 0,
"minutes": 10,
"seconds": 0
},
"transcoding": {
"video_transcoding": "Disabled",
"output_video_bitrate": 6000,
"preset": "ultrafast",
"tune": "Disabled",
"crf": "Disabled",
"pix_fmt": "Disabled",
"encoding_rate": "",
"filter_fps": "",
"gop": "Disabled",
"force_key_frames": 2,
"frame_width": "",
"frame_height": "",
"slices": "",
"cores": "",
"xlnx_hwdev": "0",
"audio_transcoding": "aac",
"output_audio_bitrate": 128,
"sample_rate": 44100
},
"modify_audio": {
"type": "DISABLED",
"channel": "1,2",
"track": "0"
},
"modify_video": {
"type": "DISABLED"
},
"overlay": {
"type": "DISABLED",
"position": {
"x": 1,
"y": 1
}
},
"delete_after": 0,
"active": true
}'
Format-specific capture

Use this preset when the output side should be written as HLS-style media instead of one classic archive container.

SRT URL to HLS recording

This is useful when the stored output format matters for later playback or downstream delivery tooling.

SRT URL to HLS recording
curl --request POST \
--url http://localhost/api/recording/create \
--header 'x-access-token: <your_api_token>' \
--header 'Content-Type: application/json' \
--data '{
"recording_name": "HLS archive output",
"recording_type": "RECORDING_STREAM_TO_FILE",
"input": {
"input_type": "INPUT_TYPE_SRT_URL",
"application": "IO_APPLICATION_FFMPEG",
"input_stream_url": "srt://127.0.0.1:1935",
"input_stream_listen_port": {},
"input_settings": {},
"input_module_id": "",
"input_stream_id": "",
"entity_name": "HLS archive output",
"module_name": "MODULE_RECORDINGS"
},
"output_format": "m3u8",
"recording_mode": "RECORDING_MODE_INFINITY",
"recording_mode_settings": {
"hours": 0,
"minutes": 0,
"seconds": 0
},
"transcoding": {
"video_transcoding": "Disabled",
"output_video_bitrate": 6000,
"preset": "ultrafast",
"tune": "Disabled",
"crf": "Disabled",
"pix_fmt": "Disabled",
"encoding_rate": "",
"filter_fps": "",
"gop": "Disabled",
"force_key_frames": 2,
"frame_width": "",
"frame_height": "",
"slices": "",
"cores": "",
"xlnx_hwdev": "0",
"audio_transcoding": "aac",
"output_audio_bitrate": 128,
"sample_rate": 44100
},
"modify_audio": {
"type": "DISABLED",
"channel": "1,2",
"track": "0"
},
"modify_video": {
"type": "DISABLED"
},
"overlay": {
"type": "DISABLED",
"position": {
"x": 1,
"y": 1
}
},
"delete_after": 0,
"active": true
}'
Request body parameters
Identity
recording_name
string

Dashboard label: Name.

Human-readable job name. The dashboard validates this as a required field and uses the same character guidance shown in the UI: A-Z, a-z, 0-9, and -.

recording_type
string

The current recording flow uses RECORDING_STREAM_TO_FILE.

Input
input
object

Input definition built from the source form. It determines which live source is being captured.

Output
output_format
string

Dashboard label: Output format.

Real product options include mp4, avi, flv, mp3, m3u8, mpegts, and mkv, depending on the selected input protocol.

recording_mode
string

Dashboard label: Auto Clip Mode.

Controls whether the recorder writes one continuous file or splits output by time. The real modes are RECORDING_MODE_INFINITY and RECORDING_MODE_SPLIT_BY_TIME.

recording_mode_settings
object

Used with split-by-time mode. The dashboard sends hours, minutes, and seconds, and presents this as a drag-and-drop timing control.

Processing
transcoding
object

Optional transcoding profile for the FFmpeg worker. The dashboard still sends this block when transcoding is disabled.

modify_audio
object

Optional audio modification settings. Disabled-state objects are still part of the normal payload shape.

modify_video
object

Optional video modification settings.

overlay
object

Optional overlay settings for branded or annotated recordings.

Runtime
delete_after
integer

Dashboard label: Auto deletion after.

Optional auto-deletion horizon in days. 0 means no automatic deletion, and the default UI guidance keeps 0 as the normal disabled state.

active
boolean

Dashboard label: Enable once created.

Controls whether the recording worker should be active after provisioning.

Create recording
curl --request POST \
--url http://localhost/api/recording/create \
--header 'x-access-token: <your_api_token>' \
--header 'Content-Type: application/json' \
--data '{
"recording_name": "Main program archive",
"recording_type": "RECORDING_STREAM_TO_FILE",
"input": {
"input_type": "INPUT_TYPE_SRT_URL",
"application": "IO_APPLICATION_FFMPEG",
"input_stream_url": "srt://127.0.0.1:1935",
"input_stream_listen_port": {},
"input_settings": {},
"input_module_id": "",
"input_stream_id": "",
"entity_name": "Main program archive",
"module_name": "MODULE_RECORDINGS"
},
"output_format": "mp4",
"recording_mode": "RECORDING_MODE_INFINITY",
"recording_mode_settings": {
"hours": 0,
"minutes": 0,
"seconds": 0
},
"transcoding": {
"video_transcoding": "Disabled",
"output_video_bitrate": 6000,
"preset": "ultrafast",
"tune": "Disabled",
"crf": "Disabled",
"pix_fmt": "Disabled",
"encoding_rate": "",
"filter_fps": "",
"gop": "Disabled",
"force_key_frames": 2,
"frame_width": "",
"frame_height": "",
"slices": "",
"cores": "",
"xlnx_hwdev": "0",
"audio_transcoding": "aac",
"output_audio_bitrate": 128,
"sample_rate": 44100
},
"modify_audio": {
"type": "DISABLED",
"channel": "1,2",
"track": "0"
},
"modify_video": {
"type": "DISABLED"
},
"overlay": {
"type": "DISABLED",
"position": {
"x": 1,
"y": 1
}
},
"delete_after": 0,
"active": true
}'
Response
Identity
_id
string

Mongo-style identifier of the recording job.

id
string

Convenience alias for _id.

recording_name
string

Name stored for the recording job.

recording_type
string

Recording type returned by the backend.

Input
input[]
array

Linked input object or objects used by the capture pipeline.

Output
output_format
string

Stored output format for the recording.

recording_mode / recording_mode_settings
object

Recording mode and any split-by-time settings stored on the job object.

Processing
transcoding / modify_audio / modify_video / overlay
object

Processing settings attached to the recording job.

Files
recordedFiles[]
array

Recorded files already linked to the job. This becomes especially important for finished or segmented captures.

Runtime
delete_after
integer

Auto-deletion setting in days.

active
boolean

Current running-state flag for the recording job.

created / modified
string

Timestamps managed by the backend.

Operation result
success
boolean

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

Response: Create recording
JSON
{
"_id": "66004d2997300f9385d32b00",
"id": "66004d2997300f9385d32b00",
"recording_name": "Main program archive",
"recording_type": "RECORDING_STREAM_TO_FILE",
"input": [
{
"_id": "66004d2997300f9385d32b01",
"id": "66004d2997300f9385d32b01",
"input_type": "INPUT_TYPE_SRT_URL",
"application": "IO_APPLICATION_FFMPEG",
"input_stream_url": "srt://127.0.0.1:1935",
"input_stream_listen_port": {},
"input_settings": {},
"input_module_id": "",
"input_stream_id": "",
"entity_name": "Main program archive",
"module_name": "MODULE_RECORDINGS"
}
],
"output_format": "mp4",
"recording_mode": "RECORDING_MODE_INFINITY",
"recording_mode_settings": {
"hours": 0,
"minutes": 0,
"seconds": 0
},
"transcoding": {
"video_transcoding": "Disabled",
"output_video_bitrate": 6000,
"preset": "ultrafast",
"tune": "Disabled",
"crf": "Disabled",
"pix_fmt": "Disabled",
"encoding_rate": "",
"filter_fps": "",
"gop": "Disabled",
"force_key_frames": 2,
"frame_width": "",
"frame_height": "",
"slices": "",
"cores": "",
"xlnx_hwdev": "0",
"audio_transcoding": "aac",
"output_audio_bitrate": 128,
"sample_rate": 44100
},
"modify_audio": {
"type": "DISABLED",
"channel": "1,2",
"track": "0"
},
"modify_video": {
"type": "DISABLED"
},
"overlay": {
"type": "DISABLED",
"position": {
"x": 1,
"y": 1
}
},
"delete_after": 0,
"active": true,
"recordedFiles": [
{
"_id": "66004d2997300f9385d32b10",
"id": "66004d2997300f9385d32b10",
"file_name": "main-program-archive-2026-03-24_12-00-00.mp4",
"file_path": "/recordings/main-program-archive-2026-03-24_12-00-00.mp4",
"module_name": "MODULE_RECORDINGS",
"file_visibility": "FILE_VISIBILITY_PUBLIC",
"output_format": "mp4",
"entity_name": "Main program archive",
"entity_id": "66004d2997300f9385d32b00",
"size_bytes": 184320000,
"duration_ms": 1800000,
"created": "2026-03-24T12:30:00.000Z"
}
],
"created": "2026-03-24T12:00:00.000Z",
"modified": "2026-03-24T12:00:00.000Z",
"success": true
}
Get recordings count
Expand
POST
/api/recording/getCount

Returns the number of recording jobs visible to the authenticated user.

This is the lightweight companion to getAll when the dashboard or your integration needs pagination, list counters, or filtered archive counts.

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

Total number of recording jobs currently visible to the authenticated user.

Response: Get recordings count
JSON
{
"count": 1
}
Get all recordings
Expand
POST
/api/recording/getAll

Returns the list of recording jobs visible to the authenticated user.

The backend populates related recordedFiles, so this method is useful when you need a list view that includes the file lifecycle rather than only job ids and names.

This is the natural companion to the dashboard listing, where teams scan job name, current live bitrate, current FPS, creation time, and the number of files already attached to each recording.

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 { created: 1 }.

filter
object

Optional filter object forwarded to the backend query.

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

The backend returns a bare array of recording jobs, not a wrapped object.

Response: Get all recordings
JSON
[
{
"_id": "66004d2997300f9385d32b00",
"id": "66004d2997300f9385d32b00",
"recording_name": "Main program archive",
"recording_type": "RECORDING_STREAM_TO_FILE",
"input": [
{
"_id": "66004d2997300f9385d32b01",
"id": "66004d2997300f9385d32b01",
"input_type": "INPUT_TYPE_SRT_URL",
"application": "IO_APPLICATION_FFMPEG",
"input_stream_url": "srt://127.0.0.1:1935",
"input_stream_listen_port": {},
"input_settings": {},
"input_module_id": "",
"input_stream_id": "",
"entity_name": "Main program archive",
"module_name": "MODULE_RECORDINGS"
}
],
"output_format": "mp4",
"recording_mode": "RECORDING_MODE_INFINITY",
"recording_mode_settings": {
"hours": 0,
"minutes": 0,
"seconds": 0
},
"transcoding": {
"video_transcoding": "Disabled",
"output_video_bitrate": 6000,
"preset": "ultrafast",
"tune": "Disabled",
"crf": "Disabled",
"pix_fmt": "Disabled",
"encoding_rate": "",
"filter_fps": "",
"gop": "Disabled",
"force_key_frames": 2,
"frame_width": "",
"frame_height": "",
"slices": "",
"cores": "",
"xlnx_hwdev": "0",
"audio_transcoding": "aac",
"output_audio_bitrate": 128,
"sample_rate": 44100
},
"modify_audio": {
"type": "DISABLED",
"channel": "1,2",
"track": "0"
},
"modify_video": {
"type": "DISABLED"
},
"overlay": {
"type": "DISABLED",
"position": {
"x": 1,
"y": 1
}
},
"delete_after": 0,
"active": true,
"recordedFiles": [
{
"_id": "66004d2997300f9385d32b10",
"id": "66004d2997300f9385d32b10",
"file_name": "main-program-archive-2026-03-24_12-00-00.mp4",
"file_path": "/recordings/main-program-archive-2026-03-24_12-00-00.mp4",
"module_name": "MODULE_RECORDINGS",
"file_visibility": "FILE_VISIBILITY_PUBLIC",
"output_format": "mp4",
"entity_name": "Main program archive",
"entity_id": "66004d2997300f9385d32b00",
"size_bytes": 184320000,
"duration_ms": 1800000,
"created": "2026-03-24T12:30:00.000Z"
}
],
"created": "2026-03-24T12:00:00.000Z",
"modified": "2026-03-24T12:00:00.000Z",
"success": true
}
]
Get recording by id
Expand
POST
/api/recording/getById

Returns one recording job with its linked input object and recorded files populated.

This is the method to use when you need the fully expanded job shape before editing, troubleshooting, or cleaning up one file from the recording output.

Request body parameters
id
string

Identifier of the recording job you want to load.

Get recording by id
curl --request POST \
--url http://localhost/api/recording/getById \
--header 'x-access-token: <your_api_token>' \
--header 'Content-Type: application/json' \
--data '{
"id": "66004d2997300f9385d32b00"
}'
Response
recording job object
object

The backend returns the populated recording job object with linked input and recorded files.

Response: Get recording by id
JSON
{
"_id": "66004d2997300f9385d32b00",
"id": "66004d2997300f9385d32b00",
"recording_name": "Main program archive",
"recording_type": "RECORDING_STREAM_TO_FILE",
"input": [
{
"_id": "66004d2997300f9385d32b01",
"id": "66004d2997300f9385d32b01",
"input_type": "INPUT_TYPE_SRT_URL",
"application": "IO_APPLICATION_FFMPEG",
"input_stream_url": "srt://127.0.0.1:1935",
"input_stream_listen_port": {},
"input_settings": {},
"input_module_id": "",
"input_stream_id": "",
"entity_name": "Main program archive",
"module_name": "MODULE_RECORDINGS"
}
],
"output_format": "mp4",
"recording_mode": "RECORDING_MODE_INFINITY",
"recording_mode_settings": {
"hours": 0,
"minutes": 0,
"seconds": 0
},
"transcoding": {
"video_transcoding": "Disabled",
"output_video_bitrate": 6000,
"preset": "ultrafast",
"tune": "Disabled",
"crf": "Disabled",
"pix_fmt": "Disabled",
"encoding_rate": "",
"filter_fps": "",
"gop": "Disabled",
"force_key_frames": 2,
"frame_width": "",
"frame_height": "",
"slices": "",
"cores": "",
"xlnx_hwdev": "0",
"audio_transcoding": "aac",
"output_audio_bitrate": 128,
"sample_rate": 44100
},
"modify_audio": {
"type": "DISABLED",
"channel": "1,2",
"track": "0"
},
"modify_video": {
"type": "DISABLED"
},
"overlay": {
"type": "DISABLED",
"position": {
"x": 1,
"y": 1
}
},
"delete_after": 0,
"active": true,
"recordedFiles": [
{
"_id": "66004d2997300f9385d32b10",
"id": "66004d2997300f9385d32b10",
"file_name": "main-program-archive-2026-03-24_12-00-00.mp4",
"file_path": "/recordings/main-program-archive-2026-03-24_12-00-00.mp4",
"module_name": "MODULE_RECORDINGS",
"file_visibility": "FILE_VISIBILITY_PUBLIC",
"output_format": "mp4",
"entity_name": "Main program archive",
"entity_id": "66004d2997300f9385d32b00",
"size_bytes": 184320000,
"duration_ms": 1800000,
"created": "2026-03-24T12:30:00.000Z"
}
],
"created": "2026-03-24T12:00:00.000Z",
"modified": "2026-03-24T12:00:00.000Z",
"success": true
}
Update recording
Expand
POST
/api/recording/update

Updates an existing recording job by id.

The backend reuses the same validation path as create, so the update payload mirrors the create payload with the addition of id.

Request body parameters
id
string

Identifier of the recording job being updated.

recording payload fields
mixed

The update contract mirrors create and reuses the same validation plus worker-regeneration path.

Update recording
curl --request POST \
--url http://localhost/api/recording/update \
--header 'x-access-token: <your_api_token>' \
--header 'Content-Type: application/json' \
--data '{
"recording_name": "Main program archive updated",
"recording_type": "RECORDING_STREAM_TO_FILE",
"input": {
"input_type": "INPUT_TYPE_SRT_URL",
"application": "IO_APPLICATION_FFMPEG",
"input_stream_url": "srt://127.0.0.1:1935",
"input_stream_listen_port": {},
"input_settings": {},
"input_module_id": "",
"input_stream_id": "",
"entity_name": "Main program archive",
"module_name": "MODULE_RECORDINGS"
},
"output_format": "mp4",
"recording_mode": "RECORDING_MODE_INFINITY",
"recording_mode_settings": {
"hours": 0,
"minutes": 0,
"seconds": 0
},
"transcoding": {
"video_transcoding": "Disabled",
"output_video_bitrate": 6000,
"preset": "ultrafast",
"tune": "Disabled",
"crf": "Disabled",
"pix_fmt": "Disabled",
"encoding_rate": "",
"filter_fps": "",
"gop": "Disabled",
"force_key_frames": 2,
"frame_width": "",
"frame_height": "",
"slices": "",
"cores": "",
"xlnx_hwdev": "0",
"audio_transcoding": "aac",
"output_audio_bitrate": 128,
"sample_rate": 44100
},
"modify_audio": {
"type": "DISABLED",
"channel": "1,2",
"track": "0"
},
"modify_video": {
"type": "DISABLED"
},
"overlay": {
"type": "DISABLED",
"position": {
"x": 1,
"y": 1
}
},
"delete_after": 0,
"active": false,
"id": "66004d2997300f9385d32b00"
}'
Response
updated recording job object
object

The backend returns the updated job object together with success: true.

Response: Update recording
JSON
{
"_id": "66004d2997300f9385d32b00",
"id": "66004d2997300f9385d32b00",
"recording_name": "Main program archive updated",
"recording_type": "RECORDING_STREAM_TO_FILE",
"input": [
{
"_id": "66004d2997300f9385d32b01",
"id": "66004d2997300f9385d32b01",
"input_type": "INPUT_TYPE_SRT_URL",
"application": "IO_APPLICATION_FFMPEG",
"input_stream_url": "srt://127.0.0.1:1935",
"input_stream_listen_port": {},
"input_settings": {},
"input_module_id": "",
"input_stream_id": "",
"entity_name": "Main program archive",
"module_name": "MODULE_RECORDINGS"
}
],
"output_format": "mp4",
"recording_mode": "RECORDING_MODE_INFINITY",
"recording_mode_settings": {
"hours": 0,
"minutes": 0,
"seconds": 0
},
"transcoding": {
"video_transcoding": "Disabled",
"output_video_bitrate": 6000,
"preset": "ultrafast",
"tune": "Disabled",
"crf": "Disabled",
"pix_fmt": "Disabled",
"encoding_rate": "",
"filter_fps": "",
"gop": "Disabled",
"force_key_frames": 2,
"frame_width": "",
"frame_height": "",
"slices": "",
"cores": "",
"xlnx_hwdev": "0",
"audio_transcoding": "aac",
"output_audio_bitrate": 128,
"sample_rate": 44100
},
"modify_audio": {
"type": "DISABLED",
"channel": "1,2",
"track": "0"
},
"modify_video": {
"type": "DISABLED"
},
"overlay": {
"type": "DISABLED",
"position": {
"x": 1,
"y": 1
}
},
"delete_after": 0,
"active": false,
"recordedFiles": [
{
"_id": "66004d2997300f9385d32b10",
"id": "66004d2997300f9385d32b10",
"file_name": "main-program-archive-2026-03-24_12-00-00.mp4",
"file_path": "/recordings/main-program-archive-2026-03-24_12-00-00.mp4",
"module_name": "MODULE_RECORDINGS",
"file_visibility": "FILE_VISIBILITY_PUBLIC",
"output_format": "mp4",
"entity_name": "Main program archive",
"entity_id": "66004d2997300f9385d32b00",
"size_bytes": 184320000,
"duration_ms": 1800000,
"created": "2026-03-24T12:30:00.000Z"
}
],
"created": "2026-03-24T12:00:00.000Z",
"modified": "2026-03-24T13:00:00.000Z",
"success": true
}
Start recording
Expand
POST
/api/recording/start

Starts a recording job by id.

The service marks the job as active, stops any previous worker for the same recording id, and then runs the recording pipeline again using the current input, format, and processing configuration.

Request body parameters
id
string

Identifier of the recording job to start.

Start recording
curl --request POST \
--url http://localhost/api/recording/start \
--header 'x-access-token: <your_api_token>' \
--header 'Content-Type: application/json' \
--data '{
"id": "66004d2997300f9385d32b00"
}'
Response
started recording job object
object

The backend marks the job as active and returns the recording object.

Response: Start recording
JSON
{
"_id": "66004d2997300f9385d32b00",
"id": "66004d2997300f9385d32b00",
"recording_name": "Main program archive",
"recording_type": "RECORDING_STREAM_TO_FILE",
"input": [
{
"_id": "66004d2997300f9385d32b01",
"id": "66004d2997300f9385d32b01",
"input_type": "INPUT_TYPE_SRT_URL",
"application": "IO_APPLICATION_FFMPEG",
"input_stream_url": "srt://127.0.0.1:1935",
"input_stream_listen_port": {},
"input_settings": {},
"input_module_id": "",
"input_stream_id": "",
"entity_name": "Main program archive",
"module_name": "MODULE_RECORDINGS"
}
],
"output_format": "mp4",
"recording_mode": "RECORDING_MODE_INFINITY",
"recording_mode_settings": {
"hours": 0,
"minutes": 0,
"seconds": 0
},
"transcoding": {
"video_transcoding": "Disabled",
"output_video_bitrate": 6000,
"preset": "ultrafast",
"tune": "Disabled",
"crf": "Disabled",
"pix_fmt": "Disabled",
"encoding_rate": "",
"filter_fps": "",
"gop": "Disabled",
"force_key_frames": 2,
"frame_width": "",
"frame_height": "",
"slices": "",
"cores": "",
"xlnx_hwdev": "0",
"audio_transcoding": "aac",
"output_audio_bitrate": 128,
"sample_rate": 44100
},
"modify_audio": {
"type": "DISABLED",
"channel": "1,2",
"track": "0"
},
"modify_video": {
"type": "DISABLED"
},
"overlay": {
"type": "DISABLED",
"position": {
"x": 1,
"y": 1
}
},
"delete_after": 0,
"active": true,
"recordedFiles": [
{
"_id": "66004d2997300f9385d32b10",
"id": "66004d2997300f9385d32b10",
"file_name": "main-program-archive-2026-03-24_12-00-00.mp4",
"file_path": "/recordings/main-program-archive-2026-03-24_12-00-00.mp4",
"module_name": "MODULE_RECORDINGS",
"file_visibility": "FILE_VISIBILITY_PUBLIC",
"output_format": "mp4",
"entity_name": "Main program archive",
"entity_id": "66004d2997300f9385d32b00",
"size_bytes": 184320000,
"duration_ms": 1800000,
"created": "2026-03-24T12:30:00.000Z"
}
],
"created": "2026-03-24T12:00:00.000Z",
"modified": "2026-03-24T12:00:00.000Z",
"success": true
}
Stop recording
Expand
POST
/api/recording/stop

Stops a recording job by id.

The backend marks the job as inactive and stops the running recording worker. This is the operational counterpart to start.

Request body parameters
id
string

Identifier of the recording job to stop.

Stop recording
curl --request POST \
--url http://localhost/api/recording/stop \
--header 'x-access-token: <your_api_token>' \
--header 'Content-Type: application/json' \
--data '{
"id": "66004d2997300f9385d32b00"
}'
Response
stopped recording job object
object

The backend marks the job as inactive and returns the recording object.

Response: Stop recording
JSON
{
"_id": "66004d2997300f9385d32b00",
"id": "66004d2997300f9385d32b00",
"recording_name": "Main program archive",
"recording_type": "RECORDING_STREAM_TO_FILE",
"input": [
{
"_id": "66004d2997300f9385d32b01",
"id": "66004d2997300f9385d32b01",
"input_type": "INPUT_TYPE_SRT_URL",
"application": "IO_APPLICATION_FFMPEG",
"input_stream_url": "srt://127.0.0.1:1935",
"input_stream_listen_port": {},
"input_settings": {},
"input_module_id": "",
"input_stream_id": "",
"entity_name": "Main program archive",
"module_name": "MODULE_RECORDINGS"
}
],
"output_format": "mp4",
"recording_mode": "RECORDING_MODE_INFINITY",
"recording_mode_settings": {
"hours": 0,
"minutes": 0,
"seconds": 0
},
"transcoding": {
"video_transcoding": "Disabled",
"output_video_bitrate": 6000,
"preset": "ultrafast",
"tune": "Disabled",
"crf": "Disabled",
"pix_fmt": "Disabled",
"encoding_rate": "",
"filter_fps": "",
"gop": "Disabled",
"force_key_frames": 2,
"frame_width": "",
"frame_height": "",
"slices": "",
"cores": "",
"xlnx_hwdev": "0",
"audio_transcoding": "aac",
"output_audio_bitrate": 128,
"sample_rate": 44100
},
"modify_audio": {
"type": "DISABLED",
"channel": "1,2",
"track": "0"
},
"modify_video": {
"type": "DISABLED"
},
"overlay": {
"type": "DISABLED",
"position": {
"x": 1,
"y": 1
}
},
"delete_after": 0,
"active": false,
"recordedFiles": [
{
"_id": "66004d2997300f9385d32b10",
"id": "66004d2997300f9385d32b10",
"file_name": "main-program-archive-2026-03-24_12-00-00.mp4",
"file_path": "/recordings/main-program-archive-2026-03-24_12-00-00.mp4",
"module_name": "MODULE_RECORDINGS",
"file_visibility": "FILE_VISIBILITY_PUBLIC",
"output_format": "mp4",
"entity_name": "Main program archive",
"entity_id": "66004d2997300f9385d32b00",
"size_bytes": 184320000,
"duration_ms": 1800000,
"created": "2026-03-24T12:30:00.000Z"
}
],
"created": "2026-03-24T12:00:00.000Z",
"modified": "2026-03-24T13:10:00.000Z",
"success": true
}
Remove recording
Expand
DELETE
/api/recording/remove

Removes a recording job by id.

This operation also stops the worker, removes the linked input object, and deletes the files produced by the recording process.

Query parameters
id
string

Identifier of the recording job to delete.

Remove recording
curl --request DELETE \
--url http://localhost/api/recording/remove \
--header 'x-access-token: <your_api_token>' \
--header 'Content-Type: application/json' \
--data '{
"id": "66004d2997300f9385d32b00"
}'
Response
removed recording job object
object

The backend stops the worker, removes linked input and file records, and returns the previously loaded recording object.

Response: Remove recording
JSON
{
"_id": "66004d2997300f9385d32b00",
"id": "66004d2997300f9385d32b00",
"recording_name": "Main program archive",
"recording_type": "RECORDING_STREAM_TO_FILE",
"input": [
{
"_id": "66004d2997300f9385d32b01",
"id": "66004d2997300f9385d32b01",
"input_type": "INPUT_TYPE_SRT_URL",
"application": "IO_APPLICATION_FFMPEG",
"input_stream_url": "srt://127.0.0.1:1935",
"input_stream_listen_port": {},
"input_settings": {},
"input_module_id": "",
"input_stream_id": "",
"entity_name": "Main program archive",
"module_name": "MODULE_RECORDINGS"
}
],
"output_format": "mp4",
"recording_mode": "RECORDING_MODE_INFINITY",
"recording_mode_settings": {
"hours": 0,
"minutes": 0,
"seconds": 0
},
"transcoding": {
"video_transcoding": "Disabled",
"output_video_bitrate": 6000,
"preset": "ultrafast",
"tune": "Disabled",
"crf": "Disabled",
"pix_fmt": "Disabled",
"encoding_rate": "",
"filter_fps": "",
"gop": "Disabled",
"force_key_frames": 2,
"frame_width": "",
"frame_height": "",
"slices": "",
"cores": "",
"xlnx_hwdev": "0",
"audio_transcoding": "aac",
"output_audio_bitrate": 128,
"sample_rate": 44100
},
"modify_audio": {
"type": "DISABLED",
"channel": "1,2",
"track": "0"
},
"modify_video": {
"type": "DISABLED"
},
"overlay": {
"type": "DISABLED",
"position": {
"x": 1,
"y": 1
}
},
"delete_after": 0,
"active": true,
"recordedFiles": [
{
"_id": "66004d2997300f9385d32b10",
"id": "66004d2997300f9385d32b10",
"file_name": "main-program-archive-2026-03-24_12-00-00.mp4",
"file_path": "/recordings/main-program-archive-2026-03-24_12-00-00.mp4",
"module_name": "MODULE_RECORDINGS",
"file_visibility": "FILE_VISIBILITY_PUBLIC",
"output_format": "mp4",
"entity_name": "Main program archive",
"entity_id": "66004d2997300f9385d32b00",
"size_bytes": 184320000,
"duration_ms": 1800000,
"created": "2026-03-24T12:30:00.000Z"
}
],
"created": "2026-03-24T12:00:00.000Z",
"modified": "2026-03-24T12:00:00.000Z",
"success": true
}
Remove recording file
Expand
POST
/api/recording/removeFile

Removes one recorded file from a recording job.

Use this when you want to keep the recording job itself but delete a specific file that was produced by it.

Request body parameters
record_id
string

Identifier of the parent recording job.

file_id
string

Identifier of the recorded file that should be deleted.

Remove recording file
curl --request POST \
--url http://localhost/api/recording/removeFile \
--header 'x-access-token: <your_api_token>' \
--header 'Content-Type: application/json' \
--data '{
"record_id": "66004d2997300f9385d32b00",
"file_id": "66004d2997300f9385d32b10"
}'
Response
success
boolean

The backend returns { success: true } when the file was removed from storage and detached from the recording job.

Response: Remove recording file
JSON
{
"success": true
}
Get recording stat
Expand
POST
/api/recording/getStat

Returns current process statistics for active recording jobs.

The dashboard uses this method to poll live FFmpeg progress data every 3 seconds. Depending on the worker state, the response can include fields such as bitrate, bitrate_kbits, fps, out_time_ms, speed, and progress.

In practice, this is the method behind the operator-facing live recording indicators: current bitrate, current FPS, and whether the worker is still progressing through output time as expected.

Request body parameters
This method has no parameters
Get recording stat
curl --request POST \
--url http://localhost/api/recording/getStat \
--header 'x-access-token: <your_api_token>' \
--header 'Content-Type: application/json' \
--data '{}'
Response
processData[]
array

Current per-process statistics used by the dashboard polling layer.

processData[].bitrate / bitrate_kbits
mixed

Current FFmpeg-reported bitrate and a normalized integer bitrate_kbits field.

processData[].fps
string

Current frames-per-second progress value when FFmpeg reports it.

processData[].out_time_ms
string

Current processed output time in milliseconds.

processData[].speed
string

Current FFmpeg processing speed, for example 1.00x.

processData[].progress
string

FFmpeg progress status such as continue or end.

Response: Get recording stat
JSON
[
{
"processData": {
"id": "66004d2997300f9385d32b00",
"frame": "1532",
"fps": "25.0",
"bitrate": "1842.1kbits/s",
"bitrate_kbits": 1842,
"total_size": "414832640",
"out_time_ms": "61200000",
"speed": "1.00x",
"progress": "continue"
}
}
]