Overlay document format
The JSON an overlay or widget is made of, shared by the predefined overlays, the Editor and the API.
An overlay is a JSON document. The predefined overlays, the Editor and the API all use the same format. This is version 1 ("schema": 1).
{
"schema": 1,
"kind": "overlay",
"canvas": { "width": 1920, "height": 1080 },
"background": { "kind": "image", "source": { "kind": "builtin", "id": "bg-starting" }, "fit": "cover" },
"timeline": { "durationMs": 6000, "loop": true },
"vars": [ /* settings the streamer can change */ ],
"layers": [ /* bottom to top */ ]
}Top-level fields
Name
Type
Limits and safety rules
Documents are rendered inside OBS on a streamer's own computer, so the server checks them strictly. Anything that doesn't match is rejected with 400 validation_error and a path to the problem. Unknown properties are rejected at every level, colours are #RRGGBB or #RRGGBBAA, and image URLs must be public https.
Image sources
Wherever a document shows a picture, the source is one of:
{ "kind": "url", ... }: a publichttpsaddress (see the rules above);{ "kind": "builtin", "id": "bg-starting" }: art bundled with ForgeCast;{ "kind": "var", "key": "logo" }: a picture setting of the same document;{ "kind": "asset", "id": "<uuid>" }: an uploaded file (in future).
Common layer fields
Every layer has these. The props depend on its type.
Name
Type
Fills
A fill is one of:
{ "kind": "solid", "color": "#RRGGBB" }{ "kind": "gradient", "angle": 0-360, "stops": [{ "at": 0-1, "color": "#RRGGBB" }, ...] }: a linear gradient, 2–8 stops{ "kind": "radial", "stops": [...] }: a circular gradient from the centre, 2–8 stops
Colours may include an alpha channel (#RRGGBBAA), so a stop can fade to transparent.
Layer types
Open a type to see its props.
Effects
fx applies to the whole layer. Every field is optional.
Name
Type
Settings and variables
vars lists the settings a document offers. The streamer changes them in the ForgeCast app and the document shows them; the values never go into the document.
"vars": [
{ "key": "goal", "label": "Goal", "type": "number", "default": 1000, "min": 1, "max": 1000000, "hint": "How many subscribers you are aiming for" },
{ "key": "title", "label": "Title", "type": "text", "default": "Sub goal", "maxLength": 24 },
{ "key": "accent", "label": "Bar colour", "type": "color", "default": "#3C9CFC" },
{ "key": "logo", "label": "Logo", "type": "image" }
]Name
Type
At most 24 settings. A value that doesn't fit its setting (out of range, too long, not a colour) is put right or ignored; it's never trusted.
Using them in text. In any text that allows variables, {{goal}} shows the setting's value, next to the live ones ({{subscribers}}, {{viewers}}, {{likes}}, {{members}}, {{channel.name}}, {{latest.member.name}} …). Add |compact for a short number (12.5K) or |raw for one without separators.
Using a picture setting. Name it as an image source: { "kind": "var", "key": "logo" } (in an Image layer, a background, or a particle emitter's images). It must name an image setting of the same document.
Binding a property to a setting. A layer's bindings map a property path to a variable, for things a text can't reach:
{ "type": "goal", "id": "bar", "bindings": { "target": "{{goal}}", "barFill.color": "{{accent}}" }, "props": { "...": "..." } }Only some properties can be bound (anything else is ignored), and a binding that would make the layer invalid is ignored too.
Animations
animations is a list of blocks on the overlay's timeline. Each block animates one or more properties between keyframes over a window of time:
{
"id": "anim-1",
"name": "Slide in from left",
"startMs": 0,
"durationMs": 800,
"easing": "cubic-out",
"iterations": 1,
"yoyo": false,
"fill": "backwards",
"tracks": {
"x": [ { "t": 0, "v": -200 }, { "t": 1, "v": 0 } ],
"opacity": [ { "t": 0, "v": 0 }, { "t": 0.6, "v": 1 } ]
}
}Name
Type
Animated properties are always changes from the layer's own pose, so moving or resizing a layer never breaks its animation:
| Property | Range | Combines by | Meaning |
|---|---|---|---|
x, y | ±20000 | adding | Offset in pixels |
rotate | ±3600 | adding | Extra rotation, degrees |
skewX, skewY | ±80 | adding | Degrees |
blur | 0–200 | adding | Extra blur, pixels |
scale, scaleX, scaleY | 0–20 | multiplying | 1 = unchanged |
opacity | 0–1 | multiplying | 1 = unchanged |
brightness | 0–5 | multiplying | 1 = unchanged |
reveal | 0–1 | multiplying | How much is shown. Text types out character by character; other layers wipe in from the left. |
When several blocks animate the same property at once they combine (offsets add up, multipliers multiply). The result is always clamped to the allowed range.
Exchange rates (ForgeCast FX)
Daily exchange rates for 150+ currencies from any base, conversions rounded the right way, the currency list and rate history. Public, no key.
Desktop app sign-in
Sign a person in to ForgeCast from a native app with OAuth 2.0 and PKCE. For scripts and servers, use an API key instead.

