Statistics & Monitoring
Requires: read (viewer+) for every endpoint in this section except
POST /api/alarms/clear, which mutates live state and requires control (operator+). See the note on that endpoint.
GET /api/getstatistics
Returns a comprehensive JSON object with runtime statistics.
Parameters: None
Response: 200 OK — JSON object with fields including:
| Field | Type | Description |
|---|---|---|
DateTime |
string | Current UTC time |
MachineName |
string | Host machine name |
ApplicationVersion |
string | Composer version |
ApplicationStarted |
string | Application start time |
LastProjectFile |
string | Path to current project |
VideoFrameRate |
string | Configured frame rate |
SessionStarted |
string | Current session start time |
SessionUptime |
string | Session uptime |
PlaybackState |
string | Current playback state |
NumCongestiveFramesSinceStart |
int | Congestive frame count |
NumWorkerQueueFlushesSinceStart |
int | Queue flush count |
AverageProcessingTime |
float | Average frame processing time |
AverageProcessingTime10k |
float | Average over last 10K frames |
AverageProcessingTimePercentage |
string | Processing time as % of frame budget |
ProcessingQueueSize |
int | Current processing queue depth |
FramesProcessed |
int | Total frames processed |
GpuUtilization |
string | GPU utilization percentage |
GpuLinkWidth |
string | PCIe link width |
GpuRamUsedGb |
string | Device-wide GPU VRAM in use, in GB (queried from CUDA) |
GpuRamTotalGb |
string | Total GPU VRAM on the device, in GB |
GpuRamFreeGb |
string | Free GPU VRAM on the device, in GB |
ProcessRamBytes |
number | Process working-set RAM in bytes, read live/on-demand |
ProcessRamMb |
string | Process working-set RAM in MB, read live/on-demand |
CpuLoad |
string | CPU load percentage |
GET /api/targets/getstatistics
Returns the statistics of every streaming target in the project, in one array per target family: RtmpTargets, SrtTargets, NdiTargets, MoQTargets. Each array is flat across scenes, and every array is present even when the project has no target of that family — an absent array would be indistinguishable from an empty one, which is what tells a caller whether the family is reported at all.
Only the targets of scenes you created are reported. Composer Desktop keeps an internal scene of its own for the Live Preview panel, and that scene carries an RTMP target it manages itself; it is left out here, as it is left out of the input list, the scene layers and the audio mixer. A target you did not add does not appear in these arrays, so the entries can be matched against the project tree without filtering.
The families are kept apart because they share almost no fields: RTMP and SRT report encoder and network timings, NDI reports subscribed receivers, MoQ reports sink state and queue depths. A caller after one family does not have to filter a mixed list, and a caller after all of them still makes one request.
Whatever the family, every entry carries Name, Type, RunningIndicatorState, ExpectedState, SceneName and SceneId. Target names are only unique within a scene, so the scene is what makes an entry identifiable; Type is the concrete component class name, and is the only way to tell apart the two components that share the SrtTargets array.
Parameters: None
Response: 200 OK — JSON object:
{
"MachineName": "HOST-01",
"Project": "MyProject.prj",
"DateTimeString": "2025-01-01T00:00:00Z",
"RtmpTargets": [
{
"Name": "Main RTMP",
"Type": "RtmpTarget",
"ConnectionStatus": "Connected",
"CurrentRTMPEndPoint": "rtmp://example/app/stream",
"UpTimeSinceStartTimeSpan": "00:12:34",
"OutgoingBitRateMbitPerSecond": "6.1",
"NumAutoReconnectsperformed": "0",
"AverageVideoEncoderTimeMs": 4.2,
"MaxVideoEncoderTimeMS": 11.0,
"AverageNetworkWriteTimeMs": 0.4,
"OutputQueueSize": "0",
"ErrorCount": "0",
"LastErrorDateTime": "",
"LastErrorMessage": "",
"WarningCount": "0",
"LastWarningDateTime": "",
"LastWarningMessage": "",
"VideoFramesWritten": "22500",
"AudioFramesWritten": "22500",
"RunningIndicatorState": "Running",
"ExpectedState": "Running",
"SceneName": "Program",
"SceneId": "3f2b1c44-9a1e-4f7a-8d21-0b3c5e7d1a90"
}
],
"SrtTargets": [
{
"Name": "Backup SRT",
"Type": "SrtTarget",
"ConnectionStatus": "Connected",
"CurrentSrtEndPoint": "srt://example:9000",
"UpTimeSinceStartTimeSpan": "00:12:34",
"OutgoingBitRateMbitPerSecond": "6.0",
"NumAutoReconnectsperformed": "0",
"AverageVideoEncoderTimeMs": 4.4,
"MaxVideoEncoderTimeMS": 12.0,
"AverageNetworkWriteTimeMs": 0.5,
"OutputQueueSize": "0",
"ErrorCount": "0",
"LastErrorDateTime": "",
"LastErrorMessage": "",
"WarningCount": "0",
"LastWarningDateTime": "",
"LastWarningMessage": "",
"VideoFramesWritten": "22500",
"AudioFramesWritten": "22500",
"RunningIndicatorState": "Running",
"ExpectedState": "Running",
"SceneName": "Program",
"SceneId": "3f2b1c44-9a1e-4f7a-8d21-0b3c5e7d1a90"
}
],
"NdiTargets": [
{
"Name": "Studio NDI",
"Type": "NdiTarget",
"ConnectionStatus": "Connected",
"ChannelName": "studio-a-pgm",
"NdiChannelAlias": "",
"NumberOfAudioChannels": 2,
"NumConnectedViewers": 3,
"SentVideoFrames": 22500,
"NdiSendTime": "0.4",
"TallyProgram": true,
"TallyPreview": false,
"WarningActive": false,
"RunningIndicatorState": "Running",
"ExpectedState": "Running",
"SceneName": "Program",
"SceneId": "3f2b1c44-9a1e-4f7a-8d21-0b3c5e7d1a90"
}
],
"MoQTargets": [
{
"Name": "MoQ out",
"Type": "MoQTarget",
"ConnectionStatus": "Connected",
"IsRunning": true,
"FramesProcessed": 22500,
"PacketsSent": 45211,
"SinkInitialized": true,
"SinkType": "MOQ",
"SinkUrl": "https://example/moq/live",
"KernelExecutionTime": 0.3,
"Disposed": false,
"AverageProcessingTime": 1.2,
"AverageProcessingTimeLong": 1.3,
"LastProcessingTime": 1.1,
"MaxProcessingTime": 7.4,
"AvgVideoProcessingTime": 0.9,
"AvgEncodingTime": 3.8,
"AvgTotalTime": 4.7,
"PeakVideoProcessingTime": 2.2,
"PeakEncodingTime": 9.1,
"VideoInputQueueDepth": 0,
"EncodingInputQueueDepth": 0,
"OutputQueueDepth": 0,
"OutgoingBitrateMbps": 6.2,
"RunningIndicatorState": "Running",
"ExpectedState": "Running",
"SceneName": "Program",
"SceneId": "3f2b1c44-9a1e-4f7a-8d21-0b3c5e7d1a90"
}
]
}
Top-level fields:
| Field | Type | Description |
|---|---|---|
MachineName |
string | Host machine name |
Project |
string | Path to the current project file |
DateTimeString |
string | UTC time the snapshot was taken |
RtmpTargets |
array | One entry per RTMP target, across all scenes |
SrtTargets |
array | One entry per SRT target, across all scenes — holds both SrtTarget and SrtTarget16ChannelAudio, told apart by Type |
NdiTargets |
array | One entry per NDI target, across all scenes |
MoQTargets |
array | One entry per MoQ target, across all scenes |
On every entry, whatever the family:
| Field | Type | Description |
|---|---|---|
Name |
string | Target component name (unique within its scene only) |
Type |
string | Concrete component class name, e.g. RtmpTarget, SrtTarget16ChannelAudio |
SceneName |
string | Name of the scene that owns the target |
SceneId |
string | Guid of the scene that owns the target |
ConnectionStatus |
string | Current connection state (e.g. Connected, Disconnected) |
RunningIndicatorState |
string | Running indicator state |
ExpectedState |
string | The state the target was last explicitly asked to be in: Unknown, Running or Stopped. Compare with RunningIndicatorState to tell a target nobody started from one that was started and has failed |
Additionally on each RtmpTargets and SrtTargets entry:
| Field | Type | Description |
|---|---|---|
CurrentRTMPEndPoint |
string | RTMP only — resolved RTMP endpoint in use (macros expanded) |
CurrentSrtEndPoint |
string | SRT only — resolved SRT endpoint in use (macros expanded) |
UpTimeSinceStartTimeSpan |
string | Time connected since the last successful (re)connect |
OutgoingBitRateMbitPerSecond |
string | Measured outgoing bit rate, Mbit/s |
NumAutoReconnectsperformed |
string | Auto-reconnects performed since start |
AverageVideoEncoderTimeMs |
float | Average video encode time per frame, ms |
MaxVideoEncoderTimeMS |
float | Longest video encode time seen, ms |
AverageNetworkWriteTimeMs |
float | Average network write time per frame, ms |
OutputQueueSize |
string | Current output queue depth |
ErrorCount |
string | Errors reported by this target |
LastErrorDateTime |
string | UTC time of the last error, empty when none |
LastErrorMessage |
string | Last error message |
WarningCount |
string | Warnings reported by this target |
LastWarningDateTime |
string | UTC time of the last warning, empty when none |
LastWarningMessage |
string | Last warning message |
VideoFramesWritten |
string | Video frames written since start |
AudioFramesWritten |
string | Audio frames written since start |
Additionally on each NdiTargets entry. The NDI sender keeps no error or reconnect tally, so unlike the network targets an NDI entry has none — WarningActive is the whole health signal:
| Field | Type | Description |
|---|---|---|
ChannelName |
string | Channel name advertised on the network |
NdiChannelAlias |
string | Channel alias, empty when none is set |
NumberOfAudioChannels |
int | Number of audio channels sent |
NumConnectedViewers |
int | NDI receivers currently subscribed to this source |
SentVideoFrames |
int | Video frames sent since the target was started |
NdiSendTime |
string | Time spent on the most recent send call, ms |
TallyProgram |
bool | A downstream receiver reports the source on program |
TallyPreview |
bool | A downstream receiver reports the source on preview |
WarningActive |
bool | Whether the target is currently reporting a warning |
Additionally on each MoQTargets entry:
| Field | Type | Description |
|---|---|---|
IsRunning |
bool | Whether the target's send loop is running |
FramesProcessed |
int | Frames handed to the target since start |
PacketsSent |
int | Packets sent to the sink since start |
SinkInitialized |
bool | Whether the sink has completed initialization |
SinkType |
string | Sink kind, e.g. MOQ, RTMP |
SinkUrl |
string | Sink URL, or Not Set |
KernelExecutionTime |
float | CUDA kernel time for the target's own work, ms |
Disposed |
bool | Whether the component has been disposed |
AverageProcessingTime |
float | Average per-frame time for the target's own work, ms |
AverageProcessingTimeLong |
float | Average per-frame time over the long window, ms |
LastProcessingTime |
float | Time the most recent frame took, ms |
MaxProcessingTime |
float | Longest per-frame time seen, ms |
AvgVideoProcessingTime |
float | Encoder-only — average video pre-processing time per frame, ms |
AvgEncodingTime |
float | Encoder-only — average encode time per frame, ms |
AvgTotalTime |
float | Encoder-only — average total time per frame, ms |
PeakVideoProcessingTime |
float | Encoder-only — longest video pre-processing time seen, ms |
PeakEncodingTime |
float | Encoder-only — longest encode time seen, ms |
VideoInputQueueDepth |
int | Encoder-only — frames queued for video pre-processing |
EncodingInputQueueDepth |
int | Encoder-only — frames queued for encoding |
OutputQueueDepth |
int | Encoder-only — packets queued for the sink |
OutgoingBitrateMbps |
float | Encoder-only — measured outgoing bit rate, Mbit/s |
The fields marked encoder-only exist only while the target has an encoder allocated, which happens when it starts. They are absent from the entry on a MoQ target that has not been started — not reported as zero — so read them defensively.
The alarm mail Composer sends when an alarm is raised carries its own payload and stays RTMP-only: it reports MachineName, Project, DateTimeString and RtmpTargets (with SceneName/SceneId) and nothing else. Widening this endpoint deliberately did not widen the mail.
GET /api/decklink/metrics
Returns arrival timing and capture counters for every DeckLink input. The Desktop Windows → DeckLink manager… window reads the same measurements. Collection continues while the window is closed. Requires Read permission.
GET /api/decklink/metrics
GET /api/decklink/metrics?reference=active
GET /api/decklink/metrics?reference=1fcecca5-0725-4c15-abcd-c00045ee6dfc
Omit reference or use active to follow the active project sync source, including system-clock fallback. Supply a GUID from AvailableReferences to select a specific source. Selection applies to this request only; it does not change project synchronization or another reader's reference. Malformed values return 400; an unknown GUID returns 404, with a JSON Error message. Measurements and counters are JSON numbers; unavailable values are null. An empty project returns an empty Inputs array.
| Top-level field | Meaning |
|---|---|
ObservedAtUtc |
UTC estimate when the snapshot began |
WindowSeconds |
Rolling measurement window: 10 seconds |
ActiveSyncSourceId, PreferredSyncSourceId |
Project source identities; may differ during fallback |
Reference |
Selected source: Id, Name, Running, Basis; null if unavailable |
ReferenceStatus |
Running, Waiting, Stopped, Stale or Unavailable |
ReferenceAgeMs, ReferencePeriodMs |
Latest reference event's age and nominal frame period |
ReferenceSamplesMissed |
Reference samples omitted because diagnostic storage was busy, since its timing epoch began |
AvailableReferences |
Registered sources, with the same fields as Reference |
Inputs |
One row per DeckLink input, including stopped inputs and legacy capture versions |
Each input row contains:
| Field | Meaning |
|---|---|
Id, Name, Device, Format |
Input identity, device/connection and detected format |
Status, SyncRole |
Capture health and role in project synchronization |
ExpectedFps, MeasuredFps |
Detected frame rate and valid-video arrival rate over the available window |
TimingEpochUtc |
Start of this input's timing measurements |
LastCallbackAtUtc, LastCallbackAgeMs |
Latest notification, including notifications without valid video |
LastVideoAtUtc, LastVideoAgeMs |
Latest notification containing valid video |
ArrivalDeltaMs |
Latest finalized phase: input arrival minus nearest reference event; positive means later |
MeanDeltaMs, DeltaVariationMs |
Circular mean and standard deviation of phase; undefined values are null |
MaximumGapMs |
Largest completed interval between valid-video arrivals in the window |
VideoSamples, MatchedSamples |
Valid-video samples available and samples with usable reference brackets |
WindowTruncated |
Storage capacity prevented retaining the complete requested window |
DiagnosticSamplesMissed |
Input timing samples omitted because diagnostic storage was busy |
Callbacks, NoSignalCallbacks, NoVideoCallbacks |
Notification counts since the input timing epoch began |
LastCallbackDurationMs |
Last completed callback's duration, including synchronous subscribers; zero before completion |
LastCallbackToSyncMs |
Delay from callback entry to its sync notification; zero before first emission |
QueuedFrames, RetainedFrames |
Queued pictures and all pictures still owned by the capture |
DiscardedFrames, RepeatedIterations, HeldIterations, Recoveries |
Capture-session totals: discarded pictures, unplanned repeats, intentional holds and genlock recoveries |
DiscardReasons |
Breakdown of discarded pictures by reason |
Timing uses a shared monotonic clock. UTC estimates are anchored when that clock initializes; later system-clock corrections do not change deltas. A DeckLink reference uses callback-entry time; other built-in sources use notification-emission time, sampled before subscribers run. Older custom sources that do not supply an emission timestamp use notification-observation time instead, which can include earlier subscribers' work. Reference.Basis states which applies.
An arrival needs reference events on both sides before its phase is finalized. Reference gaps exceeding 1.5 nominal periods are not interpolated. A reference becomes stale after the larger of 250 ms or three nominal periods without an event, and phase values become null. Stopped, waiting or stale captures also have null phase values. Different frame rates can cause phase to move continuously.
Phase wraps at half a reference period. Circular statistics handle this boundary, but a whole-frame slip can preserve phase: inspect gaps, sample counts and discard/repeat counters as well. Host phase does not establish optical frame correspondence or physical genlock. Missed diagnostic samples can affect FPS and gap measurements; they do not count as discarded pictures.
Capture start/stop, format changes and Reset timing statistics start new input timing epochs. Reference restart/rate changes start new reference epochs. Following an active-source switch excludes measurements from before that switch. Resetting timing affects diagnostic readers only; capture-session accounting and playback are unchanged. V3-only queue, discard, repeat, hold and recovery fields are null for legacy captures.
This endpoint is additive: /api/getstatistics and /api/inputs/getstatistics retain their existing response shapes.
GET /api/inputs/getstatistics
Returns the statistics of every input in the project, in one array per input family: RtmpInputs, SrtInputs, NdiInputs, MoQInputs, and OtherInputs for everything else. This is the input counterpart of /api/targets/getstatistics, and like it every array is present even when the project has no input of that family.
This is where a component's own measurements are reported — buffer depths, reconnects, decode errors, measured frame rate, drift corrections. /api/inputs/get/status remains the endpoint for identity and connection state across every input; use this one when you want what the input is measuring.
OtherInputs holds every input outside the four streaming families — media files, capture cards, still images, generators, web pages, switchers, audio strips. It is the complement of the other four, so an input appears in exactly one array and reading all five gives every input once. Scenes are not reported: a scene appears in the project's input list so it can be used as a source, but nothing starts or stops one and it measures nothing, so there is no entry a caller could act on. Composer Desktop's internal Live Preview scene is left out for the same reason.
Whatever the family, every entry carries Name, Id, Type and RunningIndicatorState. Id is the stable identity — key on it, not on Name. Nothing stops two inputs sharing a name: /api/input/create applies the name it is given without checking the project, and a project file or a script can do the same. Inputs belong to the project rather than to a scene, so unlike a target entry there is no scene tag to disambiguate them either. Type is the concrete component class name, and is both the only way to tell apart the two components that share the SrtInputs array and what identifies an entry in OtherInputs.
ExpectedState is on every entry for an input that can be commanded, and omitted from the entries of the inputs that cannot — Still image input, Rectangle, Text input, Switcher, Batch Processor, Interactive Button, Audio Channel Strip and the channel splits generated for an input's extra stereo pairs. Nothing starts or stops any of them, so the only value they could report is Unknown, which elsewhere means "nobody has started this yet". This is the same rule /api/inputs/get/status applies, so the two endpoints agree about which inputs have an expected state; the entry itself is still reported, with its identity and everything the component measures.
The component-reported values are strings. Unlike the four target families, which report typed numbers, inputs report through the same string-keyed call the logs use — so a counter arrives as text and a caller parses it. Parse with an invariant culture, and be aware that a few components format decimals in the machine's locale, so a float can arrive with a comma separator on a non-English host.
Parameters: None
Response: 200 OK — JSON object:
{
"MachineName": "HOST-01",
"Project": "MyProject.prj",
"DateTimeString": "2025-01-01T00:00:00Z",
"RtmpInputs": [
{
"Name": "Remote guest",
"Id": "6d9a1e10-5b2f-4c8d-9a31-77e4b0c2d113",
"Type": "RtmpInput",
"RunningIndicatorState": "Running",
"ExpectedState": "Running",
"ConnectionStatus": "Connected",
"NumAutoReconnectsPerformed": "0",
"RtmpBufferState": "Normal",
"VideoBufferSizeFrames": "6",
"VideoBufferSizeMs": "240",
"AudioBufferSizeMs": "250",
"NumFlushesPerformed": "0",
"NumDriftCorrections": "0",
"VideoTimeStamp": "00:12:34.500",
"AudioTimeStamp": "00:12:34.480",
"StreamTime": "00:12:34",
"VideoDecoderRenderTargets": "4/8",
"AudioDecoderRenderTargets": "2/8"
}
],
"SrtInputs": [
{
"Name": "Camera 1",
"Id": "b31c7f92-40a6-4d2e-b6a7-2c4e9f0d5a71",
"Type": "SrtInput",
"RunningIndicatorState": "Running",
"ExpectedState": "Running",
"ConnectionStatus": "Connected",
"NumAutoReconnectsPerformed": "0",
"SrtBufferState": "Normal",
"VideoAudioSync": "0.00",
"VideoBufferSizeFrames": "8",
"VideoBufferSizeMs": "320",
"AudioBufferSizeMs": "300",
"AudioDiscardedSourceSamples": "240",
"AudioInsertedSilenceSamples": "0",
"AudioRejectedAlignments": "0",
"AudioConsecutiveRejections": "0",
"AudioUnderrunRequests": "0",
"AudioInvalidRequests": "0",
"AudioAlignmentDeficitMs": "0.4",
"NumFlushesPerformed": "0",
"StreamTime": "00:12:34",
"CapturedTimeCode": "10:00:12:10",
"NumBufferUnderRuns": "0",
"NumVideoDecodeErrors": "0",
"NumPacketsReceived": "184220",
"RenderedFramesCounter": "22500",
"Synchronize": "True",
"SyncLockState": "Locked",
"SyncOffsetMs": "0.40",
"SyncBufferUsedMs": "120",
"SyncBufferUsedFrames": "3",
"SyncBufferTargetMs": "200",
"SyncBufferUsedVramMb": "24.9"
}
],
"NdiInputs": [
{
"Name": "Studio return",
"Id": "0f5b8a44-93c1-4a77-9de2-1b6c8e3f2a05",
"Type": "NdiInput",
"RunningIndicatorState": "Running",
"ExpectedState": "Running",
"PlaybackState": "Playing",
"SelectedSource": "STUDIO-A (Program)",
"LastRunningSource": "STUDIO-A (Program)",
"NumberOfAudioChannels": "2",
"ReceivedAudioChannels": "2",
"NumReceivedVideoFrames": "22500",
"NumReceivedAudioFrames": "22500",
"VideoQueueSize": "2",
"AudioQueueSizeMs": "80",
"NdiBufferFrames": "2",
"SourceFrameRate": "50",
"NumDriftCorrections": "0",
"NumServoHolds": "0",
"NumServoSkips": "0",
"NumRecycleDrops": "0",
"MeasuredFps": "50.000",
"RateDeviationPpm": "0.4",
"ArrivalJitterMs": "0.35",
"SdkTotalAudioFrames": "22500",
"SdkDroppedAudioFrames": "0",
"SdkTotalVideoFrames": "22500",
"SdkDroppedVideoFrames": "0",
"SdkVideoQueueDepth": "0"
}
],
"MoQInputs": [
{
"Name": "MoQ feed",
"Id": "a7e3c051-2d84-4f19-8b60-5c9a1e7d4f38",
"Type": "MoQInput",
"RunningIndicatorState": "Running",
"ExpectedState": "Running",
"SourceType": "MOQ",
"ConnectionStatus": "Connected",
"NumAutoReconnectsPerformed": "0",
"VideoFramesDecoded": "22500",
"AudioFramesDecoded": "22500",
"VideoBufferFrames": "4",
"VideoBufferSizeMs": "160",
"AudioBufferMs": "180",
"RenderedFramesCounter": "22500",
"AudioTrackCount": "1",
"NumPacketsReceived": "91044",
"NumBufferUnderRuns": "0",
"NumVideoDecodeErrors": "0",
"StreamTime": "00:12:34"
}
],
"OtherInputs": [
{
"Name": "Camera 2 SDI",
"Id": "c4d21a88-6e17-4b3f-90ac-3f5e7b2d6c14",
"Type": "BlackMagicCaptureV3",
"RunningIndicatorState": "Running",
"ExpectedState": "Running",
"PlaybackState": "Running",
"CapturedFrames": "22504",
"PlaybackFrames": "22500",
"LatestDetectedDisplayMode": "DecklinkModeHD1080p50",
"CaptureHasStopped": "False",
"GenlockStatus": "Inactive",
"CaptureFault": "",
"AdmittedVideoFrames": "22504",
"PublishedVideoFrames": "22500",
"RejectedVideoFrames": "0",
"DiscardedVideoFrames": "2",
"DiscardedVideoFramesByReason": "Startup=2, Capacity=0, Recovery=0, Pacing=0, FormatChange=0, Stop=0, StillStore=0, IntentionalHold=0, NotRendered=0, Admission=0",
"VideoRenderIterations": "22508",
"LiveVideoRenderIterations": "22500",
"RepeatedVideoRenderIterations": "2",
"HeldVideoRenderIterations": "3",
"EmptyVideoRenderIterations": "3",
"CaptureRecoveryCount": "0",
"RecoveryDroppedFrames": "0",
"LastCaptureRecoveryReason": "",
"RecentDiscontinuityRecoveries": "0",
"LastConsumedCaptureSequence": "22551",
"RetainedFrames": "2",
"QueueHighWaterMark": "3",
"QueuedCaptureFrames": "2",
"HostAllocatorRequests": "-1",
"HostAllocatorReleases": "-1",
"HostAllocatorFreeBuffers": "-1",
"HostAllocatorOutOfMemoryCount": "-1",
"HostAllocatorMinimumFreeBuffers": "-1",
"AudioQueueFrames": "0",
"AudioQueueSamples": "0",
"AudioDiscardedSourceSamples": "0",
"AudioInsertedSilenceSamples": "0",
"AudioSampleCountErrors": "0",
"ZeroSampleAudioFrames": "0",
"CaptureTimeWarnings": "0",
"CaptureTimeDelta": "20.00 ms"
},
{
"Name": "Opening clip",
"Id": "9b7e2f36-18c0-4a5d-b2e9-64f1a3d80c27",
"Type": "MediaFileInput",
"RunningIndicatorState": "Running",
"ExpectedState": "Unknown"
}
]
}
The second OtherInputs entry is not truncated: MediaFileInput reports no statistics of its own, so its entry is the five identity fields and nothing more. It is still listed — an input missing from a monitoring payload cannot be told apart from one that is silently gone.
Top-level fields:
| Field | Type | Description |
|---|---|---|
MachineName |
string | Host machine name |
Project |
string | Path to the current project file |
DateTimeString |
string | UTC time the snapshot was taken |
RtmpInputs |
array | One entry per RTMP input |
SrtInputs |
array | One entry per SRT input — holds both SrtInput and SrtInput16ChannelAudio, told apart by Type |
NdiInputs |
array | One entry per NDI input |
MoQInputs |
array | One entry per MoQ input |
OtherInputs |
array | Every input outside those four families, told apart by Type. Scenes are not reported |
On every entry, whatever the family:
| Field | Type | Description |
|---|---|---|
Name |
string | Input component name. Not guaranteed unique — two inputs may carry the same name |
Id |
string | The input's Guid. The stable identity; key on this rather than on Name |
Type |
string | Concrete component class name, e.g. SrtInput, SrtInput16ChannelAudio, MediaFileInput |
RunningIndicatorState |
string | The state the input is actually in |
ExpectedState |
string | The state the input was last explicitly asked to be in: Unknown, Running or Stopped. Compare with RunningIndicatorState to tell an input nobody started from one that was started and has failed |
Everything else on an entry is what the component itself reports, so the fields follow the component rather than this endpoint. The four streaming families report the sets shown above; an entry in OtherInputs carries whatever its component measures, which for several input types is nothing beyond the five fields above. Treat every component-reported field as optional and read it by name.
Both SRT input types report audio alignment measurements. AudioAlignmentDeficitMs is the signed difference between the requested audio time and the next queued sample before correction; a positive value means audio is late. It is NaN when the most recent audio request had no timestamp comparison, including positional playback and audio-only streams. AudioDiscardedSourceSamples and AudioInsertedSilenceSamples count samples removed or filled during alignment. AudioRejectedAlignments, AudioUnderrunRequests, and AudioInvalidRequests count failed requests; AudioConsecutiveRejections resets after a successful request. These counters reset when the audio queue is flushed or the input reconnects.
DeckLink Capture v3 renders each frame's sound with the picture it was embedded in. AudioQueueSamples is the few samples carried between ticks to reconcile the card's per-frame sample count with the project's (1601 and 1602 alternate at 29.97, not necessarily in the same phase), and stays at two or fewer. AudioDiscardedSourceSamples counts sound older than that, dropped rather than rendered behind its picture, and AudioInsertedSilenceSamples counts samples a frame was short of the tick. Both reset when the capture starts and when it loses its input. AudioDiscardedSourceSamples may take a single step in the first frame after a start and then hold: a card can start its audio before its first video frame and deliver that earlier sound together with the first frame's, and it is discarded because no picture goes with it (1,453–2,543 samples, 30–53 ms, measured on a DeckLink Duo 2). A start with no such step is equally healthy, and AudioInsertedSilenceSamples takes at most one sample. What matters is that neither keeps climbing while the capture runs: that means frames are arriving with more or less sound than their rate carries. These three fields are -1 while the capture is stopped, and they are not maintained when the capture is the project's sync source, because its sound then plays straight through.
DeckLink Capture v3 field migration (R3 2026): update monitoring clients that use the former statistics keys:
This migration applies to DeckLink entries in /api/inputs/getstatistics and statistics logs. The project-wide /api/getstatistics response is unchanged.
| Former key | Current key or replacement |
|---|---|
AvQueueDepth |
QueuedCaptureFrames |
FramesFlushed |
DiscardedVideoFrames — actual discarded pictures, including startup, shutdown and intentional still-store discards; see DiscardedVideoFramesByReason |
FramesRepeated |
RepeatedVideoRenderIterations — excludes intentional holds and empty output |
AllocAllocateCount |
HostAllocatorRequests |
AllocReleaseCount |
HostAllocatorReleases |
AllocFreePool |
HostAllocatorFreeBuffers |
AllocOutOfMemory |
HostAllocatorOutOfMemoryCount |
AllocMinFreePool |
HostAllocatorMinimumFreeBuffers |
CapturedMinusPlayed |
Removed. Use the separate capture and render counters; their populations differ. |
The former keys are no longer emitted by this endpoint or the statistics log. Public script properties such as NumAudioVideoFramesFlushed and NumAudioVideoFramesRepeated remain aliases for the corrected counters. PlaybackFrames remains available but now counts only newly selected live video, excluding still-store substitution, intentional holds and empty output.
DiscardedVideoFrames includes valid pictures rejected before retention (RejectedVideoFrames) and retained pictures released without live video selection. Audio received without video and frames with no input signal are excluded. Each input render call contributes to exactly one of LiveVideoRenderIterations, RepeatedVideoRenderIterations, HeldVideoRenderIterations or EmptyVideoRenderIterations; their sum is VideoRenderIterations. Project iterations that skip input rendering are not counted. These fields measure input video selection, not presentation by an output device.
Counters reset when capture starts, and lease counts settle when frames are released. At rest, AdmittedVideoFrames = PublishedVideoFrames + DiscardedVideoFrames - RejectedVideoFrames + RetainedFrames. Individual reads are atomic, but the response is not a simultaneous snapshot of all counters. HostAllocator* values are -1 when no custom host allocator is active, as in Classic capture.
GET /api/lasterror/get
Returns the last 20 entries with severity Error from the in-memory log cache, oldest first. Useful for surfacing recent failures in a monitoring dashboard without parsing log files.
Parameters: None
Response: 200 OK — JSON array of LogEventInfo entries:
[
{
"LoggerName": "Composer",
"Properties": {},
"Level": 4,
"Message": "RTMP target connection refused: rtmp://example/app/stream",
"TimeStamp": "2026-04-18T10:30:00.000",
"Extra": "EventId=3502"
}
]
Level follows the LogEventLevel enum (4 = Error). The cache holds only entries that occurred since process start; older errors live on disk under Logs/.
GET /api/alarms/get
Returns the current alarm state.
Parameters: None
Response: 200 OK — JSON object:
{
"AlarmActive": "True",
"AlarmActivatedDateTime": "01/15/2025 10:30:00",
"AlarmCreatedCount": "3",
"AlarmClearedDateTime": "01/15/2025 10:35:00",
"AlarmClearedCount": "2"
}
POST /api/alarms/clear
Requires: control (operator+)
Clears all currently active alarms in one shot — equivalent to clicking the "Clear alarms" button in Composer Desktop. Idempotent: returns 200 OK even when no alarm is active.
Parameters: None
Response: 200 OK — OK
GET /api/reports/getperformancereport
Generates and returns the same performance report Composer Desktop produces under Analysis → Performance Report, served as HTML. Includes application info, project info, system info, GPU info, settings snapshot, performance metrics, lifetime statistics, and per-component processing-time breakdowns. Generation runs synchronously on the calling thread and typically completes in under a second on a healthy host.
Parameters: None
Response: 200 OK — text/html page with the full report.
GET /api/performance/get
Deprecated. Returns 501 Not Implemented.
GET /api/systeminfo/get
Returns OS-level host hardware and platform information collected from the .NET ComputerInfo API. Available on Windows hosts (the underlying API is Windows-only); Linux hosts return 501 Not Implemented.
For richer GPU-side detail (CUDA devices, NVENC / NVDEC capabilities, Decklink devices, FFmpeg status), use /api/capabilities instead.
Parameters: None
Response:
200 OK— JSON object with the OS / hardware fields:{ "OSPlatform": "Win32NT", "OSVersion": "10.0.26200.0", "TotalPhysicalMemory": 68649984000, "TotalVirtualMemory": 137299968000, "AvailablePhysicalMemory": 35420000000, "AvailableVirtualMemory": 90000000000, "InstalledUICulture": "en-US", "MachineName": "STUDIO-01" }Field set is whatever
ComputerInfoexposes; the subset above is representative.501 Not Implemented—ComputerInfois unavailable on the host (typically Linux).
GET /api/srtsync/status
Returns the live status of the SRT input synchronization group — every SRT input that has Synchronize enabled — in a single response, so a caller can see whether all genlocked sources are frame-aligned without scraping each input's statistics.
Parameters: None
Response: 200 OK — JSON object:
{
"DateTime": "2026-07-13T19:12:02.4782434Z",
"Locked": true,
"MemberCount": 2,
"LockedMemberCount": 2,
"TargetFrameNo": 2289642,
"GroupLatencyFrames": 5,
"CongestionPolicy": "HoldSync",
"Members": [
{
"Id": "92442724-ace6-4b2b-b344-673026004c8f",
"Name": "SRT input",
"TimeCode": "21:12:01:12f",
"State": "Locked",
"OffsetFrames": 0,
"BufferedFrames": 6,
"UsingFallback": false
}
]
}
- Group fields:
Locked(the group has agreed a common timecode),MemberCount/LockedMemberCount,TargetFrameNo(the shared source frame number all members emit),GroupLatencyFrames(freshest buffered frame minus the target),CongestionPolicy(HoldSyncorLowLatency). - Per member:
Name,TimeCode(the source timecode this input is currently emitting — identical across in-sync members),State(NotSynchronized/Locking/Locked/OutOfSync/Fallback),OffsetFrames(vs the group target),BufferedFrames,UsingFallback(locked via the PTS/cadence fallback because no embedded timecode was present).
With no inputs synchronizing, MemberCount is 0 and Members is empty. See also the ComposerTestSDK helper GetSrtSyncStatusAsync() and the ScriptEngine helpers (IsSrtSyncGroupLocked, GetSrtSyncTimeCode).