MLCG.RestControl gives your C# application typed methods to discover published graphics sessions, update binding values and control scene animation. Use it for operator panels, newsroom integrations, scores or automation without implementing raw HTTP/JSON requests.
This guide uses public version 1.0.2. The public GitHub repository contains the source and release information.
What the client controls
The browser editor designs and publishes graphics. MLCG.RestControl discovers accessible sessions, updates their data and sends animation commands. The SDK HTML5 Overlay plugin renders an output URL locally over video. The REST package does not decode or render video, and can be used without the Video SDK. For design instructions, see the MLCG Editor documentation on GitBook.
The usual integration is: publish → discover a session → read bindings → build/load its output URL → update data and animation. Server commands address the session; your SDK application owns page readiness, local visibility, video processing and output.
Install and create a small read-only C# program
The console example below uses the .NET 9 SDK. Create a project and install the public package:
dotnet new console --framework net9.0 --name MlcgRestQuickStart
cd MlcgRestQuickStart
dotnet add package MLCG.RestControl --version 1.0.2
For an existing project, the equivalent reference is:
<PackageReference Include="MLCG.RestControl" Version="1.0.2" />
Version 1.0.2 targets .NET Framework 4.7.2 and .NET 9.0. It includes named animation controls, timing metadata, Demo Workspaces and typed errors; no private preview package or source checkout is needed.
For account mode, publish a session in the editor and generate a REST token with access to it. Store the token in secure configuration. The normal hosted REST address is https://cg.medialooks.com; use a local/on-premises address only for a service configured there.
List published sessions and binding keys
Make your account token available as the MLCG_API_TOKEN environment variable through your normal secure configuration. Do not paste it into source or a command saved in shell history. Replace Program.cs with this complete program, then run dotnet run. It lists sessions and binding keys without changing graphics or printing the token or binding values:
using System;
using System.Threading;
using System.Threading.Tasks;
using MLCG.RestControl;
internal static class Program
{
private static async Task<int> Main()
{
string token = Environment.GetEnvironmentVariable("MLCG_API_TOKEN");
if (string.IsNullOrWhiteSpace(token))
{
Console.Error.WriteLine("Configure MLCG_API_TOKEN first.");
return 1;
}
using (var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(30)))
using (var client = new MlcgRestClient("https://cg.medialooks.com"))
{
client.ApiToken = token;
try
{
var sessions = await client.GetSessionsAsync(timeout.Token);
Console.WriteLine("Published sessions: " + sessions.Count);
foreach (var session in sessions)
{
Console.WriteLine(session.Id + ": " + session.Name);
var bindings = await client.GetBindingsAsync(
session.Id, timeout.Token);
foreach (var binding in bindings)
Console.WriteLine(" Binding: " + binding.Key);
}
return 0;
}
catch (OperationCanceledException)
{
Console.Error.WriteLine("The request was canceled or timed out.");
}
catch (MlcgRestException ex)
{
Console.Error.WriteLine(ex.StatusCode.HasValue
? "MLCG request failed: HTTP " + (int)ex.StatusCode.Value
: "MLCG transport request failed.");
}
return 1;
}
}
}
Account mode returns only published sessions visible to the token, not the entire design Library. An empty list can be legitimate: check publication status and access. Server health alone does not prove authorization. Select a session ID returned by this list, not a Library template ID.
This one-shot program disposes its client. In an interactive controller, retain a client for the controller's lifetime and dispose it on shutdown. The remaining code blocks are fragments for that controller: they assume an authenticated client, a selectedSessionId chosen from the returned list and a cancellationToken. Mutating examples must target your own test session or a private Demo instance and use keys actually exposed by that design.
Keep session commands ordered in your controller. When changing selection or reconnecting, cancel obsolete work or ignore responses that belong to the old selection/connection. Await requests without blocking the UI or a synchronous SDK media callback; HTTP completion is not a rendering callback.
Update graphics data
Use keys returned by GetBindingsAsync. If the design exposes headline:
await client.UpdateBindingAsync(
sessionId: selectedSessionId,
key: "headline",
value: "Updated from our C# application",
cancellationToken: cancellationToken);
Send related changes together when the selected session exposes these keys:
using System.Collections.Generic;
await client.UpdateBindingsAsync(
selectedSessionId,
new Dictionary<string, string>
{
["player_name"] = "MARTA KOVACS",
["team_name"] = "RIVER CITY FC",
["score"] = "2 - 1"
},
cancellationToken);
Send only changed values. Normal updates use UpdateBindingAsync or UpdateBindingsAsync; ReplaceBindingsAsync replaces the entire binding list and is for applications that own that complete list.
Session-wide, not viewer-local. Data updates and animation commands affect all outputs using that session. Use separate sessions for independent graphics, operators or test runs. Account/workspace permissions still apply.
Get the HTML output URL
string outputUrl = client.BuildOverlayUrl(
outputBaseUrl: "https://cg.medialooks.com",
sessionId: selectedSessionId,
autoplay: false,
loop: false);
Load this transparent, read-only URL with the SDK HTML5 plugin's BrowserPageLoad, or another supported browser-overlay consumer. BuildOverlayUrl never includes the REST token. Read-only is not private: anyone with a usable output link may be able to view its graphics and displayed data. Keep the link within its intended audience and never share the control token.
For a clean first appearance: keep the local overlay hidden, load with autoplay disabled and wait for the actual scene, fonts and images to be ready. Then send one Restart command and reveal it:
await client.RestartAnimationAsync(
selectedSessionId, loop: false,
cancellationToken: cancellationToken);
Page loading, readiness and local visibility are SDK integration work, not wrapper methods. A completed HTTP request is not a painted-frame acknowledgement. Avoid autoplay followed immediately by Restart, which can cause two visible starts. The SDK samples implement the hidden-prepare workflow.
Control animation with named methods
// Start from zero; explicitly disable scene looping.
await client.RestartAnimationAsync(selectedSessionId, loop: false,
cancellationToken: cancellationToken);
// Pause at the current graphics position.
await client.PauseAnimationAsync(selectedSessionId,
cancellationToken: cancellationToken);
// Seek to 1.5 seconds and stay paused, in one command.
await client.SeekAnimationAsync(selectedSessionId, positionMs: 1500,
cancellationToken: cancellationToken);
// Resume without seeking back to zero.
await client.PlayAnimationAsync(selectedSessionId,
cancellationToken: cancellationToken);
// Change looping without restarting or seeking.
await client.SetAnimationLoopAsync(selectedSessionId, enabled: true,
cancellationToken: cancellationToken);
var timing = await client.GetSessionAnimationInfoAsync(
selectedSessionId, cancellationToken);
int maximumSliderPositionMs = timing.DurationMs;
Use the timing metadata for a seek slider's range and send a seek when the operator commits it, not on every UI refresh. The metadata is not a remote current-playhead or paint acknowledgement. Scene Loop does not rewrite intrinsic ticker scrolling or per-layer repeats.
These commands do not seek or pause source video and do not establish source-clock synchronization. An SDK application's video transport remains independent of animation seen by other HTML output viewers.
Local sample controls are separate. Hide, audio Mute / Unmute, fullscreen (F11 / Esc) and the Activity window belong to the application/Video SDK, not new REST client methods. See sample preview controls.
Offer an account-free private demo
A temporary Demo Workspace is appropriate for a sample that should work without an account token. It gives each launch private live copies of real catalog templates instead of sharing a user's password or editing a common public session.
// Keep this dedicated demo client for the demo controller's lifetime.
var demoClient = new MlcgRestClient("https://cg.medialooks.com");
var launchId = Guid.NewGuid().ToString("D");
var workspace = await demoClient.StartDemoWorkspaceAsync(
launchId, "my-sample", "1.0.0", cancellationToken);
demoClient.ApiToken = workspace.ApiToken;
var catalog = await demoClient.GetDemoTemplatesAsync(cancellationToken);
// selectedTemplateId is selected from catalog in your application's UI.
var instanceKey = Guid.NewGuid().ToString("D");
var instance = await demoClient.CreateDemoSessionAsync(
workspace.Id, selectedTemplateId, instanceKey, cancellationToken);
string privateSessionId = instance.Session.Id;
Use a dedicated client, not one carrying account credentials. The version string above is your application's version. Save the launch/instance UUIDs before sending creation requests: reuse the same IDs for an uncertain retry of the same creation, but generate new IDs for a new intentional launch or instance.
Your application owns the remaining lifecycle:
-
Renew: call
HeartbeatDemoWorkspaceAsyncat the returnedHeartbeatIntervalSeconds, adopting updated expiry/interval values. Keep the original token; renewal does not issue a replacement. Schedule bounded renewal independently of slow graphics preparation, with at most one renewal in flight for a workspace; ignore stale responses after reconnecting. - Handle limits and expiry: present lease and capacity errors, and disable further REST mutations when control expires. Demo edits are temporary.
-
Release on shutdown: call
ReleaseDemoWorkspaceAsyncwith a separate bounded cleanup token, then dispose the client. Read-only viewers may remain until expiry.EndDemoWorkspaceAsyncexplicitly ends the workspace and its outputs; it is not the same operation.
The wrapper does not automatically heartbeat or cache template instances. The SDK samples provide a complete lifecycle implementation.
Handle cancellation and typed failures
try
{
await client.UpdateBindingAsync(selectedSessionId, "headline",
"New headline", cancellationToken);
}
catch (OperationCanceledException)
{
// Report cancellation or timeout to the application UI.
}
catch (MlcgRestException ex)
{
string status = ex.StatusCode.HasValue
? ((int)ex.StatusCode.Value).ToString()
: "transport";
Console.WriteLine("MLCG REST request failed: " + status);
// ex.RetryAfter may provide a rate/capacity-limit delay.
}
- 401 / 403: check the token and access to the target session.
- 404: check the session ID and the service route.
-
429: handle a rate or capacity limit; inspect
RetryAfterif supplied. - No HTTP status: investigate transport failure or cancellation.
Use the typed status rather than parsing exception text. The client does not automatically retry mutating commands. When a request's outcome is uncertain, do not blindly replay an operation; apply the operation's retry/idempotency rules. Never log credentials, token-bearing configuration or sensitive binding values.
Reference implementations in the SDK
The MLCG HTML REST projects combine these public wrapper methods with the SDK HTML5 plugin. In their source, RestSessionController.cs contains REST selection/data/animation logic; SdkVideoHost.cs owns SDK video and HTML rendering. Try demo exercises private temporary instances; Connect uses an account's published sessions.
For SDK releases that include the compact samples, the default executable paths are:
MPlatform:
C:\Program Files (x86)\Medialooks\MPlatform SDK\Samples Basic\C#\MLCG HTML REST\bin\x64\Debug\MLCG HTML REST.exe
MFormats:
C:\Program Files (x86)\Medialooks\MFormats SDK\Samples\C#\MLCG HTML REST\bin\x64\Debug\MLCG HTML REST.exe
Availability is release-dependent; the older MLCG Sample x64 is not the compact sample. See full solution paths and sample availability and MLCG Editor: graphics workflow and SDK samples. Shared SDK prerequisites are in Before you start.
Further reading
Still have questions?
Tell us what didn’t work or what you’d like clarified.