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 ComputerInfo exposes; the subset above is representative.

  • 501 Not Implemented — ComputerInfo is 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 (HoldSync or LowLatency).
  • 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).