Skip to content

Changelog

One entry per change to the public API, webhooks or Graphics SDK. Subscribe with theRSS feed.

API 0.0.22added

Publish a theme version from the command line (beta)

  • Added ligr-graphic theme publish --theme <id> to @ligrsystems/graphics-cli. It publishes one theme version and does not publish a graphic version. See Push and publish.
  • Every graphic takes its latest published version. A graphic with no published version is not in the theme version.
  • The command prints the new version, each pinned graphic version, and whether the new version is active.
  • Add --activate to set the new version active. Add --dry-run to print the version and the graphic versions, and write nothing.
  • The command uses the same POST /themes/{themeId}/versions endpoint as publish --theme-version.

Graphics creation stays in beta. Shapes can change between minor versions. See Beta status.

API 0.0.22added

Control room update action and full room read

POST /v2/overlays/{overlayId}/control-room/graphics accepts action: "update". The action sends the preset values and your variableValues to a preset graphic that is already on air. It returns 400 when the graphic is not on air. You no longer need the graphic UUID and /graphics/commands to change a live preset.

GET /v2/control-rooms/{roomId} now returns the theme and every preset with its graphicId, graphicName and exposedVariables. When the key has overlays:read, it also returns the overlays that use the room, each with monitoringUrl. You can check a prepared room without a dashboard login. See Set up through REST.

API 0.0.22changed

Fact update and delete check the match

POST /v2/matches/{matchId}/facts/{factId} and DELETE /v2/matches/{matchId}/facts/{factId} now check that the fact belongs to the match in the path. If the fact belongs to another match, the API returns 404, the same as for a missing fact. The fact does not change.

Before this change, the API ignored matchId and acted on the fact of any match in your organization.

API 0.0.21changed

The overlay no longer sends SCHEMAS to code graphics

  • The ligr.gfx.v1 handshake is now HELLO, READY, then LOAD_GRAPHIC. The overlay no longer sends SCHEMAS. No graphic used it at runtime.
  • HELLO now carries { width, height } only. sport is still in every LOAD_GRAPHIC and GRAPHIC_UPDATE.
  • @ligrsystems/graphics-sdk 0.3.0 removes onSchemas and the GraphicSchemasPayload type. If your graphic passes onSchemas, remove it. A graphic built with 0.2.0 keeps working without changes.
  • Get the schemas during development: GET /v2/schemas/sports/{sport} and GET /v2/schemas/control-variables. See Data binding.
API 0.0.23changed

Clarify competitorsType and entityType on matches

The REST reference and the guides now explain the two competitor fields on POST /v2/matches and POST /v2/matches/{matchId}. competitorsType is the match format: singles, doubles, teams or group. entityType is the kind of each row in competitors: team or player. For example, a doubles match has competitorsType: doubles and four entityType: player rows. The API behaviour does not change.

API 0.0.22changed

Provider syncs keep team edits

The docs now say what happens when you edit a team that a data provider supplies. A provider team has dataProvider in GET /v1/teams/{teamId}.

Your organization has its own copy of each provider team. PATCH /v1/teams/{teamId} and the logo routes change only that copy. Other organizations that use the same provider team keep their values.

A provider sync keeps these fields:

  • name, gfxName, gfxFullName and abbreviation
  • primaryBackgroundColor, primaryTextColor, secondaryBackgroundColor and secondaryTextColor
  • age, gender, gradeId and defaultVenueId
  • the logo
  • nonPlayerStaff, with one exception

The exception: when an admin connects SPORT_RADAR_FOOTBALL to your organization, the initial load replaces nonPlayerStaff with the provider manager. Set the staff again after the initial load if you need other values.

The API behaviour does not change.

API 0.0.22changed

Bench players have starting set to false

Every lineup player in the sport data now has starting as a boolean. This applies to football, Australian rules, rugby league and volleyball. A starter has starting: true. A bench player has starting: false. Before this change, a bench player had no starting value, so $d.1.benchLineup[0].starting returned null. To find bench players, use benchLineup, or test starting for false.

API 0.0.22added

Update a team player over REST

PATCH /v1/teams/{teamId}/players/{playerId} changes a player on the roster of a team in your organization. It needs the teams:write scope. Send only the fields to change: firstName, lastName, number, position, positionType, gfxFirstName, gfxLastName, defaultStarter, defaultBench and captain. Fields that you omit keep their current value.

Use gfxFirstName and gfxLastName to set shorter names for graphics, 1 to 16 characters each. firstName and lastName change on every team of the player. All other fields change on this team only. The player must be on the roster of the team. Otherwise the call returns 404.

If a data provider supplies the player, the next provider sync replaces firstName, lastName, number, position and positionType. The sync does not change the graphics names, the default starter flags or captain.

The response has the shape of an item of GET /v1/teams/{teamId}/players.

API 0.0.20changed

Data source templates accept empty cells

A data source template made from a CSV sample now converts each cell the same way a data source push does. A number cell becomes a number and an empty cell becomes null. The inferred schema marks every column nullable: true. Templates made in the dashboard get the same schema. A push of the CSV that made the template no longer returns warnings for empty cells.

Existing templates keep their stored schema. To accept empty cells in an existing template, send a new sample with PATCH.

API 0.0.20added

Find entities by data provider id

The list routes take two new filters: providerName and providerIds. Use them to find the entities that a data provider supplies, by the ids that the provider uses.

  • GET /v2/matches, GET /v1/matches, GET /v1/competitions and GET /v1/venues take the filters.
  • GET /v1/teams and GET /v1/players are new. They list the teams and the players of your organization, sorted by id, and take the same filters.
  • GET /v1/officials and GET /v1/officials/{officialId} are new. They return the match officials of your organization, such as referees and umpires. They use the players:read scope. The list takes the same filters.
  • providerIds is a comma-separated list of up to 100 ids. It needs providerName, because provider ids are unique only within one provider. An id that your organization does not have is not in the results.
  • providerName without providerIds lists all the entities from that provider.

Teams, players, competitions, venues and officials carry dataProvider (id and name), as matches already do. The field is absent when no data provider supplies the entity.

API 0.0.20added

Set a match lineup over REST

PUT /v2/matches/{matchId}/lineup sets the starting players and the substitutes of one or both teams. It needs the matches:write scope. The call replaces the lineup of each team you send, and open overlays show the new lineup. Graphics use the lineup to show the teams, list the scorers and fill the player variables. Each player must be on the team roster. An invalid player returns 400 with a details entry for each bad value.

Each lineup player now carries teamId. The field is in GET /v1/matches/{matchId}/lineup and in the p include of GET /v1/matches/{matchId} and GET /v2/matches/{matchId}.

API 0.0.20changed

Match requests no longer take matchTier

POST /v1/matches, POST /v2/matches and the match update routes no longer take matchTier. Leave it out. If a request still sends it, the API ignores it.

API 0.0.21added

Overlay responses return the monitoring URL

Overlay responses now carry monitoringUrl. The URL opens the read-only monitoring view of the overlay on the overlay host of the environment. The field is in POST /v1/overlays, GET /v1/overlays/{overlayId}, GET /v2/overlays/{overlayId} and the o include of GET /v1/matches/{matchId} and GET /v2/matches/{matchId}. Read the field instead of building the URL from key. Staging and other environments do not use overlay.ligr.live.

API 0.0.21changed

Rive color bindings ignore values that are not colors

A Rive color binding now applies only a #rgb, #rrggbb or #rrggbbaa string, or a finite number read as ARGB. Any other value is ignored, and the graphic keeps its current color. Before, a value such as '' became ARGB 0 and hid the shape. A numeric string such as '4294901760' is now ignored. Send a number instead. See Expressions.

API 0.0.21added

Field details in Rive configuration errors

A Rive 4xx error can now have a details array. Each entry has field and reason. field is the path of the value that failed, for example controlVariables[stage].defaultValue. reason states what is wrong, for example must be a JSON number. A 500 error has no details. See Edit through REST.

ligr-graphic prints each detail on its own line as field: reason.

API 0.0.21changed

Evaluate checks Rive user expressions

POST /v2/themes/{themeId}/rive-graphics/{graphicId}/evaluate now checks every user expression, not only the data bindings. The response has a new userExpressions array with one row per user expression. unresolved counts the failed rows in bindings and in userExpressions.

The graphics runtime now reads backslash escapes in expressions correctly. "a\nb" holds a line break, {"\"": 1} is a valid object, and /\d+/.test("12") returns true. Before this change, the runtime removed each backslash, so these expressions failed or returned a wrong value.

API 0.0.21added

Set a team logo over REST

POST /v1/teams/{teamId}/logo/uploads opens a signed upload for one PNG or JPEG logo of 500 KB or less. Declare the type, the size, and the SHA-256 of the file. Upload the bytes with one PUT to the returned URL.

PUT /v1/teams/{teamId}/logo sets the logo from the upload. The API checks the size, the SHA-256, and the image type before it stores the logo. DELETE /v1/teams/{teamId}/logo removes the logo. All three routes need the teams:write scope.

Team responses now carry logoUrl. The field is in GET /v1/teams/{teamId}, PATCH /v1/teams/{teamId}, and the logo routes. A team without a logo returns the club logo, if the club has one.

API 0.0.21addedchanged

Add a player to a team roster over REST

POST /v1/teams/{teamId}/players creates a player and adds the player to the roster of a team in your organization. It needs the teams:write scope. Send firstName and lastName. You can also send number, position, positionType, gfxFirstName, gfxLastName, defaultStarter and defaultBench. gfxFirstName and gfxLastName take 1 to 16 characters. The response has the shape of an item of GET /v1/teams/{teamId}/players. Use the returned id as a playerId in PUT /v2/matches/{matchId}/lineup.

In the TeamPlayer and MatchPlayer schemas, number and position are now nullable. A roster or lineup entry without a squad number or a position returns null for that field.

API 0.0.21added

Set the team coach over REST

PATCH /v1/teams/{teamId} accepts nonPlayerStaff. The field is a list of staff members. Each member has firstName, lastName and role. The role is manager or assistantManager. The list replaces the stored staff. Send an empty list to remove all staff.

Graphics show the manager entry as the coach, for example on line-up graphics. If no entry has the manager role, graphics show the first entry.

The team response now carries nonPlayerStaff when the team has staff. The field is in GET /v1/teams/{teamId} and in the PATCH response.

API 0.0.21added

Update a team over REST

PATCH /v1/teams/{teamId} updates a team in your organization. It needs the teams:write scope. Send only the fields you change. Omitted fields keep their stored value. You can send name, gfxName, gfxFullName, abbreviation, age, gender, gradeId, defaultVenueId, primaryBackgroundColor, primaryTextColor, secondaryBackgroundColor and secondaryTextColor. A request with no field, or with a blank name, returns 400. The response is the updated team.

The route uses the same update as the dashboard. The team history records the API key that made the change.

API 0.0.19changed

Verify graphic assets before publication

Graphic and theme publication now reads each referenced asset and thumbnail from storage before creating a version. The API checks size and SHA-256 when a digest exists. A missing file returns 409 GRAPHIC_ASSET_MISSING. An unreadable or changed file returns 409 GRAPHIC_ASSET_INVALID. Repair the file before publishing again.

API 0.0.18changedbreaking

Stream video bitrate is stored in whole megabits

  • videoBitrateKbps on POST /v1/streams and POST /v1/streams/{streamSettingsId} now accepts 2000 to 10000 and is rounded to the nearest 1000 kb/s. The encoder runs at whole megabits, and the previous range (500 to 30000) was written into the setting unconverted, which produced a value the encoder could not run.
  • Stream responses return videoBitrateKbps as whole thousands, for example 6000, converted from the stored value. A stream that was created before this change reads back the same way; nothing needs to be resent.
API 0.0.17added

Control-room presets expose entity variables and accept updates (beta)

  • POST /v2/control-rooms/{roomId}/presets accepts exposeVariables: names of fact, stat, team, player and match variables to show on the preset without a value. The operator picks the value live. Before this change, only the dashboard editor exposed these variables.
  • PUT /v2/control-rooms/{roomId}/presets/{presetId} renames a preset, moves it to another section, or replaces its variable set from the active published manifest. Position, scale and other dashboard settings are kept. A variable that stays in the set keeps its dashboard display type, exit mode and hidden state; naming it in exposeVariables shows it again. REST cannot pin a value on a fact, stat, team or player variable, and cannot set display type or exit mode; use the dashboard editor for those.
  • Preset responses carry exposedVariables: every variable the operator can see, with or without a stored value.

See Set up through REST.

API 0.0.16added

Rive graphics from the command line (beta)

  • Added the rive command group to @ligrsystems/graphics-cli 0.2.0. It imports a Rive file, edits the working draft, and publishes it, without a browser and without a dashboard session. See Command line.
  • ligr-graphic rive import <file> uploads a .riv, a .rev or a project ZIP, waits for preparation, and creates the graphic. It writes rive.json, which holds the theme id and the graphic id. Add --retain-source to keep the editable source. rive replace <file> replaces the Rive asset of an existing draft.
  • rive control, rive bind, rive input, rive asset, rive expr, rive schema and rive settings change one value at a time. Each command sends one REST operation, and the server validates the whole configuration on every write.
  • rive pull writes the working configuration into rive.json. rive push compares that file with the draft and sends one operation for each change. Add --dry-run to print the operations and send none. A push is not atomic: if one operation fails, run rive pull, then push again.
  • Every write carries the timestamp of the last read. A draft that changed answers 409 TARGET_CHANGED, and the CLI reads it again and retries once. A draft that a builder session holds answers 409 LOCKED, and the message names the editor.
  • rive publish creates a graphic version. Add --theme-version to publish a theme version that pins it, and --activate to make that theme version active.
  • Add --json to any command to print one JSON document and no human lines.
  • @ligrsystems/graphics-sdk moves to 0.2.0 with the CLI. The two packages must hold the same version.

Graphics creation stays in beta. Shapes can change between minor versions. See Beta status.

API 0.0.15added

Graphics SDK package and the ligr-graphic CLI (beta)

  • Graphics creation is in beta: the Graphics SDK, the CLI, and the theme and code graphics REST routes. You create the theme. Shapes can change between minor versions. See Beta status.
  • Added @ligrsystems/graphics-sdk on npm: createGraphic(options) runs the ligr.gfx.v1 protocol in the browser, and useLigrGraphic(onHide) does the same for React. The protocol types ship under @ligrsystems/graphics-sdk/protocol.
  • Added @ligrsystems/graphics-cli on npm. ligr-graphic init scaffolds a graphic, dev runs a local harness with real match scenarios, validate applies the API rules locally, and create, push and publish drive the code graphics REST routes.
  • Added POST /v2/themes, GET /v2/themes and DELETE /v2/themes/{themeId}: create, list and delete the themes your organization owns. An organization can own up to five themes (409 THEME_LIMIT_REACHED). A theme a competition uses cannot be deleted (409 THEME_IN_USE). The CLI drives them with ligr-graphic theme create|list|delete.
  • The Graphics SDK pages now start from the CLI. The REST calls stay documented under “Without the CLI” on Push and publish.

See Quick start.

API 0.0.14addedchanged

Scoped API keys with expiry

  • Added per-resource scopes to API keys. A scope is <resource>:read or <resource>:write. Each operation in the REST reference names the scope it needs. See Authentication.
  • Added an expiry date to API keys. The dashboard offers 7, 30, 60, 90 days, one year, a custom date, or no expiration.
  • Added 401 with code: "API_KEY_EXPIRED" for an expired key. Every 401 body now carries a code.
  • Changed the 403 INSUFFICIENT_SCOPE message. It names the missing scope, for example matches:write.
  • Changed key format. A new key starts with ligr_. LIGR stores a hash and shows the key once.
  • Existing keys keep working as legacy keys with read or write on every resource and no expiry. You cannot create a new legacy key.
API 0.0.13addeddeprecatedbreaking

Stream start, stop and monitor routes

  • Added POST /v1/streams/{streamSettingsId}/start and POST /v1/streams/{streamSettingsId}/stop. Start takes an optional destinationIds list. Without it the stream runs and publishes nowhere until an operator starts the destinations, which is how you preview.
  • Added the stream monitor operations for a running stream: POST …/destinations/start and POST …/destinations/stop with a destinationIds list, POST …/input/refresh, and POST …/input/latency with latencyMs.
  • Added POST …/automation with autoStream, and the autoMode field (Auto Graphics) on POST /v1/overlays/{overlayId}.
  • Deprecated POST /v1/streams/{streamSettingsId}/manage. It keeps working until 2027-09-08 and returns Deprecation and Sunset headers. It accepts GoLive and StopStream only.
  • Removed the StartPreview, PauseStream and IdlyStream values from manage. The service treated each of them as a stop, so a client that sent one from a live stream stopped it, and one that sent StartPreview from an idle stream got a 400.

See Automate a stream.

API 0.0.14added

Stream configuration over REST, and overlay webhooks

  • Added stream settings: GET /v1/streams?matchId=, POST /v1/streams, and GET, POST, DELETE on /v1/streams/{streamSettingsId}. Create takes the competition from the match.
  • Added destinations: GET, POST on /v1/streams/destinations, and GET, POST, DELETE on /v1/streams/destinations/{destinationId}. A pull destination answers with pullUrl.
  • Added inputs: GET, POST on /v1/streams/inputs, and GET, POST, DELETE on /v1/streams/inputs/{inputId}. LIGR generates the host, the application name and the stream key, and answers with rtmpUrl and srtUrl.
  • Added the overlay webhook entity with create, update and delete events. See Events and Payloads.

See Configure a stream.

API 0.0.13addedchanged

Themes and code graphics over REST

  • Added GET /v2/themes/{themeId} and POST /v2/themes/{themeId}/versions.
  • Added /v2/themes/{themeId}/code-graphics: list, create, get, uploads, bundle and versions.
  • UserInputError now returns 400. It returned 500 before. This changes overlay v2 command validation.
  • Lock conflicts return 409 with code: "LOCKED" and a holder object.

See Themes and Code graphics in the REST reference, and the Graphics SDK.

Deprecation policy

A deprecated endpoint keeps working for at least 12 months after its changelog entry. It returns a Deprecation header and a Sunset header. Breaking changes ship only in a new path version.