<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>LIGR Developer Docs changelog</title><description>Changes to the LIGR REST API, webhooks and Graphics SDK.</description><link>https://docs.ligr.live/</link><item><title>Publish a theme version from the command line (beta)</title><link>https://docs.ligr.live/changelog/#2026-09-30-cli-theme-publish</link><guid isPermaLink="true">https://docs.ligr.live/changelog/#2026-09-30-cli-theme-publish</guid><description>API 0.0.22. Tags: added.</description><pubDate>Wed, 30 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;ul&gt;
&lt;li&gt;Added &lt;code&gt;ligr-graphic theme publish --theme &amp;#x3C;id&gt;&lt;/code&gt; to &lt;code&gt;@ligrsystems/graphics-cli&lt;/code&gt;. It publishes one theme version and does not publish a graphic version. See &lt;a href=&quot;https://docs.ligr.live/graphics-sdk/push-and-publish/&quot;&gt;Push and publish&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Every graphic takes its latest published version. A graphic with no published version is not in the theme version.&lt;/li&gt;
&lt;li&gt;The command prints the new version, each pinned graphic version, and whether the new version is active.&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;--activate&lt;/code&gt; to set the new version active. Add &lt;code&gt;--dry-run&lt;/code&gt; to print the version and the graphic versions, and write nothing.&lt;/li&gt;
&lt;li&gt;The command uses the same &lt;code&gt;POST /themes/{themeId}/versions&lt;/code&gt; endpoint as &lt;code&gt;publish --theme-version&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Graphics creation stays in &lt;strong&gt;beta&lt;/strong&gt;. Shapes can change between minor versions. See &lt;a href=&quot;https://docs.ligr.live/graphics-sdk/#beta-status&quot;&gt;Beta status&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>added</category></item><item><title>Control room update action and full room read</title><link>https://docs.ligr.live/changelog/#2026-09-30-control-room-update-and-read</link><guid isPermaLink="true">https://docs.ligr.live/changelog/#2026-09-30-control-room-update-and-read</guid><description>API 0.0.22. Tags: added.</description><pubDate>Wed, 30 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;code&gt;POST /v2/overlays/{overlayId}/control-room/graphics&lt;/code&gt; accepts &lt;code&gt;action: &quot;update&quot;&lt;/code&gt;. The action sends the preset values and your &lt;code&gt;variableValues&lt;/code&gt; 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 &lt;code&gt;/graphics/commands&lt;/code&gt; to change a live preset.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;GET /v2/control-rooms/{roomId}&lt;/code&gt; now returns the theme and every preset with its &lt;code&gt;graphicId&lt;/code&gt;, &lt;code&gt;graphicName&lt;/code&gt; and &lt;code&gt;exposedVariables&lt;/code&gt;. When the key has &lt;code&gt;overlays:read&lt;/code&gt;, it also returns the overlays that use the room, each with &lt;code&gt;monitoringUrl&lt;/code&gt;. You can check a prepared room without a dashboard login. See &lt;a href=&quot;https://docs.ligr.live/control-room/setup/&quot;&gt;Set up through REST&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>added</category></item><item><title>Fact update and delete check the match</title><link>https://docs.ligr.live/changelog/#2026-09-30-fact-routes-match-scope</link><guid isPermaLink="true">https://docs.ligr.live/changelog/#2026-09-30-fact-routes-match-scope</guid><description>API 0.0.22. Tags: changed.</description><pubDate>Wed, 30 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;code&gt;POST /v2/matches/{matchId}/facts/{factId}&lt;/code&gt; and &lt;code&gt;DELETE /v2/matches/{matchId}/facts/{factId}&lt;/code&gt; now check that the fact belongs to the match in the path. If the fact belongs to another match, the API returns &lt;code&gt;404&lt;/code&gt;, the same as for a missing fact. The fact does not change.&lt;/p&gt;
&lt;p&gt;Before this change, the API ignored &lt;code&gt;matchId&lt;/code&gt; and acted on the fact of any match in your organization.&lt;/p&gt;</content:encoded><category>changed</category></item><item><title>The overlay no longer sends SCHEMAS to code graphics</title><link>https://docs.ligr.live/changelog/#2026-09-30-graphics-no-runtime-schemas</link><guid isPermaLink="true">https://docs.ligr.live/changelog/#2026-09-30-graphics-no-runtime-schemas</guid><description>API 0.0.21. Tags: changed.</description><pubDate>Wed, 30 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;ligr.gfx.v1&lt;/code&gt; handshake is now &lt;code&gt;HELLO&lt;/code&gt;, &lt;code&gt;READY&lt;/code&gt;, then &lt;code&gt;LOAD_GRAPHIC&lt;/code&gt;. The overlay no longer sends &lt;code&gt;SCHEMAS&lt;/code&gt;. No graphic used it at runtime.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HELLO&lt;/code&gt; now carries &lt;code&gt;{ width, height }&lt;/code&gt; only. &lt;code&gt;sport&lt;/code&gt; is still in every &lt;code&gt;LOAD_GRAPHIC&lt;/code&gt; and &lt;code&gt;GRAPHIC_UPDATE&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@ligrsystems/graphics-sdk&lt;/code&gt; 0.3.0 removes &lt;code&gt;onSchemas&lt;/code&gt; and the &lt;code&gt;GraphicSchemasPayload&lt;/code&gt; type. If your graphic passes &lt;code&gt;onSchemas&lt;/code&gt;, remove it. A graphic built with 0.2.0 keeps working without changes.&lt;/li&gt;
&lt;li&gt;Get the schemas during development: &lt;code&gt;GET /v2/schemas/sports/{sport}&lt;/code&gt; and &lt;code&gt;GET /v2/schemas/control-variables&lt;/code&gt;. See &lt;a href=&quot;https://docs.ligr.live/graphics-sdk/data/#schemas&quot;&gt;Data binding&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>changed</category></item><item><title>Clarify competitorsType and entityType on matches</title><link>https://docs.ligr.live/changelog/#2026-09-30-match-competitors-type-docs</link><guid isPermaLink="true">https://docs.ligr.live/changelog/#2026-09-30-match-competitors-type-docs</guid><description>API 0.0.23. Tags: changed.</description><pubDate>Wed, 30 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The REST reference and the guides now explain the two competitor fields on &lt;code&gt;POST /v2/matches&lt;/code&gt; and &lt;code&gt;POST /v2/matches/{matchId}&lt;/code&gt;. &lt;code&gt;competitorsType&lt;/code&gt; is the match format: &lt;code&gt;singles&lt;/code&gt;, &lt;code&gt;doubles&lt;/code&gt;, &lt;code&gt;teams&lt;/code&gt; or &lt;code&gt;group&lt;/code&gt;. &lt;code&gt;entityType&lt;/code&gt; is the kind of each row in &lt;code&gt;competitors&lt;/code&gt;: &lt;code&gt;team&lt;/code&gt; or &lt;code&gt;player&lt;/code&gt;. For example, a doubles match has &lt;code&gt;competitorsType: doubles&lt;/code&gt; and four &lt;code&gt;entityType: player&lt;/code&gt; rows. The API behaviour does not change.&lt;/p&gt;</content:encoded><category>changed</category></item><item><title>Provider syncs keep team edits</title><link>https://docs.ligr.live/changelog/#2026-09-30-provider-team-edits</link><guid isPermaLink="true">https://docs.ligr.live/changelog/#2026-09-30-provider-team-edits</guid><description>API 0.0.22. Tags: changed.</description><pubDate>Wed, 30 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The docs now say what happens when you edit a team that a data provider supplies. A provider team has &lt;code&gt;dataProvider&lt;/code&gt; in &lt;code&gt;GET /v1/teams/{teamId}&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Your organization has its own copy of each provider team. &lt;code&gt;PATCH /v1/teams/{teamId}&lt;/code&gt; and the logo routes change only that copy. Other organizations that use the same provider team keep their values.&lt;/p&gt;
&lt;p&gt;A provider sync keeps these fields:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;name&lt;/code&gt;, &lt;code&gt;gfxName&lt;/code&gt;, &lt;code&gt;gfxFullName&lt;/code&gt; and &lt;code&gt;abbreviation&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;primaryBackgroundColor&lt;/code&gt;, &lt;code&gt;primaryTextColor&lt;/code&gt;, &lt;code&gt;secondaryBackgroundColor&lt;/code&gt; and &lt;code&gt;secondaryTextColor&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;age&lt;/code&gt;, &lt;code&gt;gender&lt;/code&gt;, &lt;code&gt;gradeId&lt;/code&gt; and &lt;code&gt;defaultVenueId&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;the logo&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nonPlayerStaff&lt;/code&gt;, with one exception&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The exception: when an admin connects &lt;code&gt;SPORT_RADAR_FOOTBALL&lt;/code&gt; to your organization, the initial load replaces &lt;code&gt;nonPlayerStaff&lt;/code&gt; with the provider manager. Set the staff again after the initial load if you need other values.&lt;/p&gt;
&lt;p&gt;The API behaviour does not change.&lt;/p&gt;</content:encoded><category>changed</category></item><item><title>Bench players have starting set to false</title><link>https://docs.ligr.live/changelog/#2026-09-30-sport-data-starting-flag</link><guid isPermaLink="true">https://docs.ligr.live/changelog/#2026-09-30-sport-data-starting-flag</guid><description>API 0.0.22. Tags: changed.</description><pubDate>Wed, 30 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Every lineup player in the sport data now has &lt;code&gt;starting&lt;/code&gt; as a boolean. This applies to football, Australian rules, rugby league and volleyball. A starter has &lt;code&gt;starting: true&lt;/code&gt;. A bench player has &lt;code&gt;starting: false&lt;/code&gt;. Before this change, a bench player had no &lt;code&gt;starting&lt;/code&gt; value, so &lt;code&gt;$d.1.benchLineup[0].starting&lt;/code&gt; returned &lt;code&gt;null&lt;/code&gt;. To find bench players, use &lt;code&gt;benchLineup&lt;/code&gt;, or test &lt;code&gt;starting&lt;/code&gt; for &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;</content:encoded><category>changed</category></item><item><title>Update a team player over REST</title><link>https://docs.ligr.live/changelog/#2026-09-30-team-player-update</link><guid isPermaLink="true">https://docs.ligr.live/changelog/#2026-09-30-team-player-update</guid><description>API 0.0.22. Tags: added.</description><pubDate>Wed, 30 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;code&gt;PATCH /v1/teams/{teamId}/players/{playerId}&lt;/code&gt; changes a player on the roster of a team in your organization. It needs the &lt;code&gt;teams:write&lt;/code&gt; scope. Send only the fields to change: &lt;code&gt;firstName&lt;/code&gt;, &lt;code&gt;lastName&lt;/code&gt;, &lt;code&gt;number&lt;/code&gt;, &lt;code&gt;position&lt;/code&gt;, &lt;code&gt;positionType&lt;/code&gt;, &lt;code&gt;gfxFirstName&lt;/code&gt;, &lt;code&gt;gfxLastName&lt;/code&gt;, &lt;code&gt;defaultStarter&lt;/code&gt;, &lt;code&gt;defaultBench&lt;/code&gt; and &lt;code&gt;captain&lt;/code&gt;. Fields that you omit keep their current value.&lt;/p&gt;
&lt;p&gt;Use &lt;code&gt;gfxFirstName&lt;/code&gt; and &lt;code&gt;gfxLastName&lt;/code&gt; to set shorter names for graphics, 1 to 16 characters each. &lt;code&gt;firstName&lt;/code&gt; and &lt;code&gt;lastName&lt;/code&gt; 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.&lt;/p&gt;
&lt;p&gt;If a data provider supplies the player, the next provider sync replaces &lt;code&gt;firstName&lt;/code&gt;, &lt;code&gt;lastName&lt;/code&gt;, &lt;code&gt;number&lt;/code&gt;, &lt;code&gt;position&lt;/code&gt; and &lt;code&gt;positionType&lt;/code&gt;. The sync does not change the graphics names, the default starter flags or &lt;code&gt;captain&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The response has the shape of an item of &lt;code&gt;GET /v1/teams/{teamId}/players&lt;/code&gt;.&lt;/p&gt;</content:encoded><category>added</category></item><item><title>Data source templates accept empty cells</title><link>https://docs.ligr.live/changelog/#2026-09-29-data-source-template-csv-types</link><guid isPermaLink="true">https://docs.ligr.live/changelog/#2026-09-29-data-source-template-csv-types</guid><description>API 0.0.20. Tags: changed.</description><pubDate>Tue, 29 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;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 &lt;code&gt;null&lt;/code&gt;. The inferred schema marks every column &lt;code&gt;nullable: true&lt;/code&gt;. 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.&lt;/p&gt;
&lt;p&gt;Existing templates keep their stored schema. To accept empty cells in an existing template, send a new sample with &lt;code&gt;PATCH&lt;/code&gt;.&lt;/p&gt;</content:encoded><category>changed</category></item><item><title>Find entities by data provider id</title><link>https://docs.ligr.live/changelog/#2026-09-29-filter-by-provider-id</link><guid isPermaLink="true">https://docs.ligr.live/changelog/#2026-09-29-filter-by-provider-id</guid><description>API 0.0.20. Tags: added.</description><pubDate>Tue, 29 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The list routes take two new filters: &lt;code&gt;providerName&lt;/code&gt; and &lt;code&gt;providerIds&lt;/code&gt;. Use them to find the entities that a data provider supplies, by the ids that the provider uses.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;GET /v2/matches&lt;/code&gt;, &lt;code&gt;GET /v1/matches&lt;/code&gt;, &lt;code&gt;GET /v1/competitions&lt;/code&gt; and &lt;code&gt;GET /v1/venues&lt;/code&gt; take the filters.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GET /v1/teams&lt;/code&gt; and &lt;code&gt;GET /v1/players&lt;/code&gt; are new. They list the teams and the players of your organization, sorted by id, and take the same filters.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GET /v1/officials&lt;/code&gt; and &lt;code&gt;GET /v1/officials/{officialId}&lt;/code&gt; are new. They return the match officials of your organization, such as referees and umpires. They use the &lt;code&gt;players:read&lt;/code&gt; scope. The list takes the same filters.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;providerIds&lt;/code&gt; is a comma-separated list of up to 100 ids. It needs &lt;code&gt;providerName&lt;/code&gt;, because provider ids are unique only within one provider. An id that your organization does not have is not in the results.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;providerName&lt;/code&gt; without &lt;code&gt;providerIds&lt;/code&gt; lists all the entities from that provider.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Teams, players, competitions, venues and officials carry &lt;code&gt;dataProvider&lt;/code&gt; (&lt;code&gt;id&lt;/code&gt; and &lt;code&gt;name&lt;/code&gt;), as matches already do. The field is absent when no data provider supplies the entity.&lt;/p&gt;</content:encoded><category>added</category></item><item><title>Set a match lineup over REST</title><link>https://docs.ligr.live/changelog/#2026-09-29-match-lineup-write</link><guid isPermaLink="true">https://docs.ligr.live/changelog/#2026-09-29-match-lineup-write</guid><description>API 0.0.20. Tags: added.</description><pubDate>Tue, 29 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;code&gt;PUT /v2/matches/{matchId}/lineup&lt;/code&gt; sets the starting players and the substitutes of one or both teams. It needs the &lt;code&gt;matches:write&lt;/code&gt; 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 &lt;code&gt;details&lt;/code&gt; entry for each bad value.&lt;/p&gt;
&lt;p&gt;Each lineup player now carries &lt;code&gt;teamId&lt;/code&gt;. The field is in &lt;code&gt;GET /v1/matches/{matchId}/lineup&lt;/code&gt; and in the &lt;code&gt;p&lt;/code&gt; include of &lt;code&gt;GET /v1/matches/{matchId}&lt;/code&gt; and &lt;code&gt;GET /v2/matches/{matchId}&lt;/code&gt;.&lt;/p&gt;</content:encoded><category>added</category></item><item><title>Match requests no longer take matchTier</title><link>https://docs.ligr.live/changelog/#2026-09-29-match-tier-removed</link><guid isPermaLink="true">https://docs.ligr.live/changelog/#2026-09-29-match-tier-removed</guid><description>API 0.0.20. Tags: changed.</description><pubDate>Tue, 29 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;code&gt;POST /v1/matches&lt;/code&gt;, &lt;code&gt;POST /v2/matches&lt;/code&gt; and the match update routes no longer take &lt;code&gt;matchTier&lt;/code&gt;. Leave it out. If a request still sends it, the API ignores it.&lt;/p&gt;</content:encoded><category>changed</category></item><item><title>Overlay responses return the monitoring URL</title><link>https://docs.ligr.live/changelog/#2026-09-29-overlay-monitoring-url</link><guid isPermaLink="true">https://docs.ligr.live/changelog/#2026-09-29-overlay-monitoring-url</guid><description>API 0.0.21. Tags: added.</description><pubDate>Tue, 29 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Overlay responses now carry &lt;code&gt;monitoringUrl&lt;/code&gt;. The URL opens the read-only monitoring view of the overlay on the overlay host of the environment. The field is in &lt;code&gt;POST /v1/overlays&lt;/code&gt;, &lt;code&gt;GET /v1/overlays/{overlayId}&lt;/code&gt;, &lt;code&gt;GET /v2/overlays/{overlayId}&lt;/code&gt; and the &lt;code&gt;o&lt;/code&gt; include of &lt;code&gt;GET /v1/matches/{matchId}&lt;/code&gt; and &lt;code&gt;GET /v2/matches/{matchId}&lt;/code&gt;. Read the field instead of building the URL from &lt;code&gt;key&lt;/code&gt;. Staging and other environments do not use &lt;code&gt;overlay.ligr.live&lt;/code&gt;.&lt;/p&gt;</content:encoded><category>added</category></item><item><title>Rive color bindings ignore values that are not colors</title><link>https://docs.ligr.live/changelog/#2026-09-29-rive-color-binding-values</link><guid isPermaLink="true">https://docs.ligr.live/changelog/#2026-09-29-rive-color-binding-values</guid><description>API 0.0.21. Tags: changed.</description><pubDate>Tue, 29 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A Rive color binding now applies only a &lt;code&gt;#rgb&lt;/code&gt;, &lt;code&gt;#rrggbb&lt;/code&gt; or &lt;code&gt;#rrggbbaa&lt;/code&gt; 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 &lt;code&gt;&apos;&apos;&lt;/code&gt; became ARGB &lt;code&gt;0&lt;/code&gt; and hid the shape. A numeric string such as &lt;code&gt;&apos;4294901760&apos;&lt;/code&gt; is now ignored. Send a number instead. See &lt;a href=&quot;https://docs.ligr.live/graphics-sdk/expressions/&quot;&gt;Expressions&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>changed</category></item><item><title>Field details in Rive configuration errors</title><link>https://docs.ligr.live/changelog/#2026-09-29-rive-error-details</link><guid isPermaLink="true">https://docs.ligr.live/changelog/#2026-09-29-rive-error-details</guid><description>API 0.0.21. Tags: added.</description><pubDate>Tue, 29 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A Rive &lt;code&gt;4xx&lt;/code&gt; error can now have a &lt;code&gt;details&lt;/code&gt; array. Each entry has &lt;code&gt;field&lt;/code&gt; and &lt;code&gt;reason&lt;/code&gt;. &lt;code&gt;field&lt;/code&gt; is the path of the value that failed, for example &lt;code&gt;controlVariables[stage].defaultValue&lt;/code&gt;. &lt;code&gt;reason&lt;/code&gt; states what is wrong, for example &lt;code&gt;must be a JSON number&lt;/code&gt;. A &lt;code&gt;500&lt;/code&gt; error has no &lt;code&gt;details&lt;/code&gt;. See &lt;a href=&quot;https://docs.ligr.live/rive-graphics/edit-through-rest/#errors&quot;&gt;Edit through REST&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ligr-graphic&lt;/code&gt; prints each detail on its own line as &lt;code&gt;field: reason&lt;/code&gt;.&lt;/p&gt;</content:encoded><category>added</category></item><item><title>Evaluate checks Rive user expressions</title><link>https://docs.ligr.live/changelog/#2026-09-29-rive-evaluate-user-expressions</link><guid isPermaLink="true">https://docs.ligr.live/changelog/#2026-09-29-rive-evaluate-user-expressions</guid><description>API 0.0.21. Tags: changed.</description><pubDate>Tue, 29 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;code&gt;POST /v2/themes/{themeId}/rive-graphics/{graphicId}/evaluate&lt;/code&gt; now checks every user expression, not only the data bindings. The response has a new &lt;code&gt;userExpressions&lt;/code&gt; array with one row per user expression. &lt;code&gt;unresolved&lt;/code&gt; counts the failed rows in &lt;code&gt;bindings&lt;/code&gt; and in &lt;code&gt;userExpressions&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The graphics runtime now reads backslash escapes in expressions correctly. &lt;code&gt;&quot;a\nb&quot;&lt;/code&gt; holds a line break, &lt;code&gt;{&quot;\&quot;&quot;: 1}&lt;/code&gt; is a valid object, and &lt;code&gt;/\d+/.test(&quot;12&quot;)&lt;/code&gt; returns &lt;code&gt;true&lt;/code&gt;. Before this change, the runtime removed each backslash, so these expressions failed or returned a wrong value.&lt;/p&gt;</content:encoded><category>changed</category></item><item><title>Set a team logo over REST</title><link>https://docs.ligr.live/changelog/#2026-09-29-team-logo-upload</link><guid isPermaLink="true">https://docs.ligr.live/changelog/#2026-09-29-team-logo-upload</guid><description>API 0.0.21. Tags: added.</description><pubDate>Tue, 29 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;code&gt;POST /v1/teams/{teamId}/logo/uploads&lt;/code&gt; 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.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;PUT /v1/teams/{teamId}/logo&lt;/code&gt; sets the logo from the upload. The API checks the size, the SHA-256, and the image type before it stores the logo. &lt;code&gt;DELETE /v1/teams/{teamId}/logo&lt;/code&gt; removes the logo. All three routes need the &lt;code&gt;teams:write&lt;/code&gt; scope.&lt;/p&gt;
&lt;p&gt;Team responses now carry &lt;code&gt;logoUrl&lt;/code&gt;. The field is in &lt;code&gt;GET /v1/teams/{teamId}&lt;/code&gt;, &lt;code&gt;PATCH /v1/teams/{teamId}&lt;/code&gt;, and the logo routes. A team without a logo returns the club logo, if the club has one.&lt;/p&gt;</content:encoded><category>added</category></item><item><title>Add a player to a team roster over REST</title><link>https://docs.ligr.live/changelog/#2026-09-29-team-player-create</link><guid isPermaLink="true">https://docs.ligr.live/changelog/#2026-09-29-team-player-create</guid><description>API 0.0.21. Tags: added, changed.</description><pubDate>Tue, 29 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;code&gt;POST /v1/teams/{teamId}/players&lt;/code&gt; creates a player and adds the player to the roster of a team in your organization. It needs the &lt;code&gt;teams:write&lt;/code&gt; scope. Send &lt;code&gt;firstName&lt;/code&gt; and &lt;code&gt;lastName&lt;/code&gt;. You can also send &lt;code&gt;number&lt;/code&gt;, &lt;code&gt;position&lt;/code&gt;, &lt;code&gt;positionType&lt;/code&gt;, &lt;code&gt;gfxFirstName&lt;/code&gt;, &lt;code&gt;gfxLastName&lt;/code&gt;, &lt;code&gt;defaultStarter&lt;/code&gt; and &lt;code&gt;defaultBench&lt;/code&gt;. &lt;code&gt;gfxFirstName&lt;/code&gt; and &lt;code&gt;gfxLastName&lt;/code&gt; take 1 to 16 characters. The response has the shape of an item of &lt;code&gt;GET /v1/teams/{teamId}/players&lt;/code&gt;. Use the returned &lt;code&gt;id&lt;/code&gt; as a &lt;code&gt;playerId&lt;/code&gt; in &lt;code&gt;PUT /v2/matches/{matchId}/lineup&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In the &lt;code&gt;TeamPlayer&lt;/code&gt; and &lt;code&gt;MatchPlayer&lt;/code&gt; schemas, &lt;code&gt;number&lt;/code&gt; and &lt;code&gt;position&lt;/code&gt; are now nullable. A roster or lineup entry without a squad number or a position returns &lt;code&gt;null&lt;/code&gt; for that field.&lt;/p&gt;</content:encoded><category>added</category><category>changed</category></item><item><title>Set the team coach over REST</title><link>https://docs.ligr.live/changelog/#2026-09-29-team-staff</link><guid isPermaLink="true">https://docs.ligr.live/changelog/#2026-09-29-team-staff</guid><description>API 0.0.21. Tags: added.</description><pubDate>Tue, 29 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;code&gt;PATCH /v1/teams/{teamId}&lt;/code&gt; accepts &lt;code&gt;nonPlayerStaff&lt;/code&gt;. The field is a list of staff members. Each member has &lt;code&gt;firstName&lt;/code&gt;, &lt;code&gt;lastName&lt;/code&gt; and &lt;code&gt;role&lt;/code&gt;. The role is &lt;code&gt;manager&lt;/code&gt; or &lt;code&gt;assistantManager&lt;/code&gt;. The list replaces the stored staff. Send an empty list to remove all staff.&lt;/p&gt;
&lt;p&gt;Graphics show the &lt;code&gt;manager&lt;/code&gt; entry as the coach, for example on line-up graphics. If no entry has the &lt;code&gt;manager&lt;/code&gt; role, graphics show the first entry.&lt;/p&gt;
&lt;p&gt;The team response now carries &lt;code&gt;nonPlayerStaff&lt;/code&gt; when the team has staff. The field is in &lt;code&gt;GET /v1/teams/{teamId}&lt;/code&gt; and in the &lt;code&gt;PATCH&lt;/code&gt; response.&lt;/p&gt;</content:encoded><category>added</category></item><item><title>Update a team over REST</title><link>https://docs.ligr.live/changelog/#2026-09-29-team-update</link><guid isPermaLink="true">https://docs.ligr.live/changelog/#2026-09-29-team-update</guid><description>API 0.0.21. Tags: added.</description><pubDate>Tue, 29 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;code&gt;PATCH /v1/teams/{teamId}&lt;/code&gt; updates a team in your organization. It needs the &lt;code&gt;teams:write&lt;/code&gt; scope. Send only the fields you change. Omitted fields keep their stored value. You can send &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;gfxName&lt;/code&gt;, &lt;code&gt;gfxFullName&lt;/code&gt;, &lt;code&gt;abbreviation&lt;/code&gt;, &lt;code&gt;age&lt;/code&gt;, &lt;code&gt;gender&lt;/code&gt;, &lt;code&gt;gradeId&lt;/code&gt;, &lt;code&gt;defaultVenueId&lt;/code&gt;, &lt;code&gt;primaryBackgroundColor&lt;/code&gt;, &lt;code&gt;primaryTextColor&lt;/code&gt;, &lt;code&gt;secondaryBackgroundColor&lt;/code&gt; and &lt;code&gt;secondaryTextColor&lt;/code&gt;. A request with no field, or with a blank &lt;code&gt;name&lt;/code&gt;, returns 400. The response is the updated team.&lt;/p&gt;
&lt;p&gt;The route uses the same update as the dashboard. The team history records the API key that made the change.&lt;/p&gt;</content:encoded><category>added</category></item><item><title>Verify graphic assets before publication</title><link>https://docs.ligr.live/changelog/#2026-09-25-publish-asset-verification</link><guid isPermaLink="true">https://docs.ligr.live/changelog/#2026-09-25-publish-asset-verification</guid><description>API 0.0.19. Tags: changed.</description><pubDate>Fri, 25 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;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 &lt;code&gt;409 GRAPHIC_ASSET_MISSING&lt;/code&gt;. An unreadable or changed file returns &lt;code&gt;409 GRAPHIC_ASSET_INVALID&lt;/code&gt;. Repair the file before publishing again.&lt;/p&gt;</content:encoded><category>changed</category></item><item><title>Stream video bitrate is stored in whole megabits</title><link>https://docs.ligr.live/changelog/#2026-09-23-stream-video-bitrate-range</link><guid isPermaLink="true">https://docs.ligr.live/changelog/#2026-09-23-stream-video-bitrate-range</guid><description>API 0.0.18. Tags: changed, breaking.</description><pubDate>Wed, 23 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;ul&gt;
&lt;li&gt;&lt;code&gt;videoBitrateKbps&lt;/code&gt; on &lt;code&gt;POST /v1/streams&lt;/code&gt; and &lt;code&gt;POST /v1/streams/{streamSettingsId}&lt;/code&gt; 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.&lt;/li&gt;
&lt;li&gt;Stream responses return &lt;code&gt;videoBitrateKbps&lt;/code&gt; as whole thousands, for example &lt;code&gt;6000&lt;/code&gt;, converted from the stored value. A stream that was created before this change reads back the same way; nothing needs to be resent.&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>changed</category><category>breaking</category></item><item><title>Control-room presets expose entity variables and accept updates (beta)</title><link>https://docs.ligr.live/changelog/#2026-09-22-control-room-presets-expose-and-update</link><guid isPermaLink="true">https://docs.ligr.live/changelog/#2026-09-22-control-room-presets-expose-and-update</guid><description>API 0.0.17. Tags: added.</description><pubDate>Tue, 22 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;ul&gt;
&lt;li&gt;&lt;code&gt;POST /v2/control-rooms/{roomId}/presets&lt;/code&gt; accepts &lt;code&gt;exposeVariables&lt;/code&gt;: 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.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PUT /v2/control-rooms/{roomId}/presets/{presetId}&lt;/code&gt; 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 &lt;code&gt;exposeVariables&lt;/code&gt; 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.&lt;/li&gt;
&lt;li&gt;Preset responses carry &lt;code&gt;exposedVariables&lt;/code&gt;: every variable the operator can see, with or without a stored value.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;See &lt;a href=&quot;https://docs.ligr.live/control-room/setup/&quot;&gt;Set up through REST&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>added</category></item><item><title>Rive graphics from the command line (beta)</title><link>https://docs.ligr.live/changelog/#2026-09-16-rive-graphics-command-line</link><guid isPermaLink="true">https://docs.ligr.live/changelog/#2026-09-16-rive-graphics-command-line</guid><description>API 0.0.16. Tags: added.</description><pubDate>Wed, 16 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;ul&gt;
&lt;li&gt;Added the &lt;code&gt;rive&lt;/code&gt; command group to &lt;code&gt;@ligrsystems/graphics-cli&lt;/code&gt; 0.2.0. It imports a Rive file, edits the working draft, and publishes it, without a browser and without a dashboard session. See &lt;a href=&quot;https://docs.ligr.live/rive-graphics/command-line/&quot;&gt;Command line&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ligr-graphic rive import &amp;#x3C;file&gt;&lt;/code&gt; uploads a &lt;code&gt;.riv&lt;/code&gt;, a &lt;code&gt;.rev&lt;/code&gt; or a project ZIP, waits for preparation, and creates the graphic. It writes &lt;code&gt;rive.json&lt;/code&gt;, which holds the theme id and the graphic id. Add &lt;code&gt;--retain-source&lt;/code&gt; to keep the editable source. &lt;code&gt;rive replace &amp;#x3C;file&gt;&lt;/code&gt; replaces the Rive asset of an existing draft.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rive control&lt;/code&gt;, &lt;code&gt;rive bind&lt;/code&gt;, &lt;code&gt;rive input&lt;/code&gt;, &lt;code&gt;rive asset&lt;/code&gt;, &lt;code&gt;rive expr&lt;/code&gt;, &lt;code&gt;rive schema&lt;/code&gt; and &lt;code&gt;rive settings&lt;/code&gt; change one value at a time. Each command sends one REST operation, and the server validates the whole configuration on every write.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rive pull&lt;/code&gt; writes the working configuration into &lt;code&gt;rive.json&lt;/code&gt;. &lt;code&gt;rive push&lt;/code&gt; compares that file with the draft and sends one operation for each change. Add &lt;code&gt;--dry-run&lt;/code&gt; to print the operations and send none. A push is not atomic: if one operation fails, run &lt;code&gt;rive pull&lt;/code&gt;, then push again.&lt;/li&gt;
&lt;li&gt;Every write carries the timestamp of the last read. A draft that changed answers &lt;code&gt;409 TARGET_CHANGED&lt;/code&gt;, and the CLI reads it again and retries once. A draft that a builder session holds answers &lt;code&gt;409 LOCKED&lt;/code&gt;, and the message names the editor.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rive publish&lt;/code&gt; creates a graphic version. Add &lt;code&gt;--theme-version&lt;/code&gt; to publish a theme version that pins it, and &lt;code&gt;--activate&lt;/code&gt; to make that theme version active.&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;--json&lt;/code&gt; to any command to print one JSON document and no human lines.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@ligrsystems/graphics-sdk&lt;/code&gt; moves to 0.2.0 with the CLI. The two packages must hold the same version.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Graphics creation stays in &lt;strong&gt;beta&lt;/strong&gt;. Shapes can change between minor versions. See &lt;a href=&quot;https://docs.ligr.live/graphics-sdk/#beta-status&quot;&gt;Beta status&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>added</category></item><item><title>Graphics SDK package and the ligr-graphic CLI (beta)</title><link>https://docs.ligr.live/changelog/#2026-09-08-graphics-sdk-package-and-cli</link><guid isPermaLink="true">https://docs.ligr.live/changelog/#2026-09-08-graphics-sdk-package-and-cli</guid><description>API 0.0.15. Tags: added.</description><pubDate>Tue, 08 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;ul&gt;
&lt;li&gt;Graphics creation is in &lt;strong&gt;beta&lt;/strong&gt;: the Graphics SDK, the CLI, and the theme and code graphics REST routes. You create the theme. Shapes can change between minor versions. See &lt;a href=&quot;https://docs.ligr.live/graphics-sdk/#beta-status&quot;&gt;Beta status&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Added &lt;code&gt;@ligrsystems/graphics-sdk&lt;/code&gt; on npm: &lt;code&gt;createGraphic(options)&lt;/code&gt; runs the &lt;code&gt;ligr.gfx.v1&lt;/code&gt; protocol in the browser, and &lt;code&gt;useLigrGraphic(onHide)&lt;/code&gt; does the same for React. The protocol types ship under &lt;code&gt;@ligrsystems/graphics-sdk/protocol&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Added &lt;code&gt;@ligrsystems/graphics-cli&lt;/code&gt; on npm. &lt;code&gt;ligr-graphic init&lt;/code&gt; scaffolds a graphic, &lt;code&gt;dev&lt;/code&gt; runs a local harness with real match scenarios, &lt;code&gt;validate&lt;/code&gt; applies the API rules locally, and &lt;code&gt;create&lt;/code&gt;, &lt;code&gt;push&lt;/code&gt; and &lt;code&gt;publish&lt;/code&gt; drive the code graphics REST routes.&lt;/li&gt;
&lt;li&gt;Added &lt;code&gt;POST /v2/themes&lt;/code&gt;, &lt;code&gt;GET /v2/themes&lt;/code&gt; and &lt;code&gt;DELETE /v2/themes/{themeId}&lt;/code&gt;: create, list and delete the themes your organization owns. An organization can own up to five themes (&lt;code&gt;409 THEME_LIMIT_REACHED&lt;/code&gt;). A theme a competition uses cannot be deleted (&lt;code&gt;409 THEME_IN_USE&lt;/code&gt;). The CLI drives them with &lt;code&gt;ligr-graphic theme create|list|delete&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The Graphics SDK pages now start from the CLI. The REST calls stay documented under “Without the CLI” on &lt;a href=&quot;https://docs.ligr.live/graphics-sdk/push-and-publish/&quot;&gt;Push and publish&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;See &lt;a href=&quot;https://docs.ligr.live/graphics-sdk/quick-start/&quot;&gt;Quick start&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>added</category></item><item><title>Scoped API keys with expiry</title><link>https://docs.ligr.live/changelog/#2026-09-08-scoped-api-keys-with-expiry</link><guid isPermaLink="true">https://docs.ligr.live/changelog/#2026-09-08-scoped-api-keys-with-expiry</guid><description>API 0.0.14. Tags: added, changed.</description><pubDate>Tue, 08 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;ul&gt;
&lt;li&gt;Added per-resource scopes to API keys. A scope is &lt;code&gt;&amp;#x3C;resource&gt;:read&lt;/code&gt; or &lt;code&gt;&amp;#x3C;resource&gt;:write&lt;/code&gt;. Each operation in the &lt;a href=&quot;https://docs.ligr.live/rest/&quot;&gt;REST reference&lt;/a&gt; names the scope it needs. See &lt;a href=&quot;https://docs.ligr.live/get-started/authentication/&quot;&gt;Authentication&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Added an expiry date to API keys. The dashboard offers 7, 30, 60, 90 days, one year, a custom date, or no expiration.&lt;/li&gt;
&lt;li&gt;Added &lt;code&gt;401&lt;/code&gt; with &lt;code&gt;code: &quot;API_KEY_EXPIRED&quot;&lt;/code&gt; for an expired key. Every &lt;code&gt;401&lt;/code&gt; body now carries a &lt;code&gt;code&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Changed the &lt;code&gt;403 INSUFFICIENT_SCOPE&lt;/code&gt; message. It names the missing scope, for example &lt;code&gt;matches:write&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Changed key format. A new key starts with &lt;code&gt;ligr_&lt;/code&gt;. LIGR stores a hash and shows the key once.&lt;/li&gt;
&lt;li&gt;Existing keys keep working as legacy keys with &lt;code&gt;read&lt;/code&gt; or &lt;code&gt;write&lt;/code&gt; on every resource and no expiry. You cannot create a new legacy key.&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>added</category><category>changed</category></item><item><title>Stream start, stop and monitor routes</title><link>https://docs.ligr.live/changelog/#2026-09-08-stream-commands-start-and-stop</link><guid isPermaLink="true">https://docs.ligr.live/changelog/#2026-09-08-stream-commands-start-and-stop</guid><description>API 0.0.13. Tags: added, deprecated, breaking.</description><pubDate>Tue, 08 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;ul&gt;
&lt;li&gt;Added &lt;code&gt;POST /v1/streams/{streamSettingsId}/start&lt;/code&gt; and &lt;code&gt;POST /v1/streams/{streamSettingsId}/stop&lt;/code&gt;. Start takes an optional &lt;code&gt;destinationIds&lt;/code&gt; list. Without it the stream runs and publishes nowhere until an operator starts the destinations, which is how you preview.&lt;/li&gt;
&lt;li&gt;Added the stream monitor operations for a running stream: &lt;code&gt;POST …/destinations/start&lt;/code&gt; and &lt;code&gt;POST …/destinations/stop&lt;/code&gt; with a &lt;code&gt;destinationIds&lt;/code&gt; list, &lt;code&gt;POST …/input/refresh&lt;/code&gt;, and &lt;code&gt;POST …/input/latency&lt;/code&gt; with &lt;code&gt;latencyMs&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Added &lt;code&gt;POST …/automation&lt;/code&gt; with &lt;code&gt;autoStream&lt;/code&gt;, and the &lt;code&gt;autoMode&lt;/code&gt; field (Auto Graphics) on &lt;code&gt;POST /v1/overlays/{overlayId}&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Deprecated&lt;/strong&gt; &lt;code&gt;POST /v1/streams/{streamSettingsId}/manage&lt;/code&gt;. It keeps working until &lt;strong&gt;2027-09-08&lt;/strong&gt; and returns &lt;code&gt;Deprecation&lt;/code&gt; and &lt;code&gt;Sunset&lt;/code&gt; headers. It accepts &lt;code&gt;GoLive&lt;/code&gt; and &lt;code&gt;StopStream&lt;/code&gt; only.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Removed&lt;/strong&gt; the &lt;code&gt;StartPreview&lt;/code&gt;, &lt;code&gt;PauseStream&lt;/code&gt; and &lt;code&gt;IdlyStream&lt;/code&gt; values from &lt;code&gt;manage&lt;/code&gt;. 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 &lt;code&gt;StartPreview&lt;/code&gt; from an idle stream got a 400.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;See &lt;a href=&quot;https://docs.ligr.live/guides/automate-a-stream/&quot;&gt;Automate a stream&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>added</category><category>deprecated</category><category>breaking</category></item><item><title>Stream configuration over REST, and overlay webhooks</title><link>https://docs.ligr.live/changelog/#2026-09-08-stream-configuration-and-overlay-webhooks</link><guid isPermaLink="true">https://docs.ligr.live/changelog/#2026-09-08-stream-configuration-and-overlay-webhooks</guid><description>API 0.0.14. Tags: added.</description><pubDate>Tue, 08 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;ul&gt;
&lt;li&gt;Added stream settings: &lt;code&gt;GET /v1/streams?matchId=&lt;/code&gt;, &lt;code&gt;POST /v1/streams&lt;/code&gt;, and &lt;code&gt;GET&lt;/code&gt;, &lt;code&gt;POST&lt;/code&gt;, &lt;code&gt;DELETE&lt;/code&gt; on &lt;code&gt;/v1/streams/{streamSettingsId}&lt;/code&gt;. Create takes the competition from the match.&lt;/li&gt;
&lt;li&gt;Added destinations: &lt;code&gt;GET&lt;/code&gt;, &lt;code&gt;POST&lt;/code&gt; on &lt;code&gt;/v1/streams/destinations&lt;/code&gt;, and &lt;code&gt;GET&lt;/code&gt;, &lt;code&gt;POST&lt;/code&gt;, &lt;code&gt;DELETE&lt;/code&gt; on &lt;code&gt;/v1/streams/destinations/{destinationId}&lt;/code&gt;. A pull destination answers with &lt;code&gt;pullUrl&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Added inputs: &lt;code&gt;GET&lt;/code&gt;, &lt;code&gt;POST&lt;/code&gt; on &lt;code&gt;/v1/streams/inputs&lt;/code&gt;, and &lt;code&gt;GET&lt;/code&gt;, &lt;code&gt;POST&lt;/code&gt;, &lt;code&gt;DELETE&lt;/code&gt; on &lt;code&gt;/v1/streams/inputs/{inputId}&lt;/code&gt;. LIGR generates the host, the application name and the stream key, and answers with &lt;code&gt;rtmpUrl&lt;/code&gt; and &lt;code&gt;srtUrl&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Added the &lt;code&gt;overlay&lt;/code&gt; webhook entity with &lt;code&gt;create&lt;/code&gt;, &lt;code&gt;update&lt;/code&gt; and &lt;code&gt;delete&lt;/code&gt; events. See &lt;a href=&quot;https://docs.ligr.live/webhooks/events/&quot;&gt;Events&lt;/a&gt; and &lt;a href=&quot;https://docs.ligr.live/webhooks/payloads/&quot;&gt;Payloads&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;See &lt;a href=&quot;https://docs.ligr.live/guides/configure-a-stream/&quot;&gt;Configure a stream&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>added</category></item><item><title>Themes and code graphics over REST</title><link>https://docs.ligr.live/changelog/#2026-09-07-themes-and-code-graphics-over-rest</link><guid isPermaLink="true">https://docs.ligr.live/changelog/#2026-09-07-themes-and-code-graphics-over-rest</guid><description>API 0.0.13. Tags: added, changed.</description><pubDate>Mon, 07 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;ul&gt;
&lt;li&gt;Added &lt;code&gt;GET /v2/themes/{themeId}&lt;/code&gt; and &lt;code&gt;POST /v2/themes/{themeId}/versions&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Added &lt;code&gt;/v2/themes/{themeId}/code-graphics&lt;/code&gt;: list, create, get, uploads, bundle and versions.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;UserInputError&lt;/code&gt; now returns &lt;strong&gt;400&lt;/strong&gt;. It returned 500 before. This changes overlay v2 command validation.&lt;/li&gt;
&lt;li&gt;Lock conflicts return &lt;strong&gt;409&lt;/strong&gt; with &lt;code&gt;code: &quot;LOCKED&quot;&lt;/code&gt; and a &lt;code&gt;holder&lt;/code&gt; object.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;See &lt;a href=&quot;https://docs.ligr.live/rest/operations/tags/themes/&quot;&gt;Themes&lt;/a&gt; and &lt;a href=&quot;https://docs.ligr.live/rest/operations/tags/code-graphics/&quot;&gt;Code graphics&lt;/a&gt; in the REST reference, and the &lt;a href=&quot;https://docs.ligr.live/graphics-sdk/&quot;&gt;Graphics SDK&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>added</category><category>changed</category></item></channel></rss>