Skip to main content
A license records that your team lets another team use one of your characters, for a stated use, media and territory, between two dates. Only teams with the provider role can issue or revoke licenses; others get 403. Ask us to switch it on for your team. Once issued, the license is enforced: the character appears in the licensee’s library, and every run and download with it is checked against the license. See Using licensed characters.

Issue a license

POST /v1/licenses · scope licenses:write
The character must be yours, in the same environment as the key, and ready.

Naming the licensee

Send at most one of the fields below. Send none to issue a secret license instead. An unknown team id or slug answers 404 with the code licensee_not_found. An email with no account yet is not refused. The license is created with status pending and licensee_team_id: null, and you get license.issued straight away. The first time that address signs in to Omnichar with Google, the license attaches to the person’s personal workspace, becomes active, and the licensee gets license.issued too. Attaching signs the license again, so its signature and kid change once, and you get license.updated with the new values to replace your stored copy.

Scope

scope is stored with scope_version: 1. These fields are checked: media names output types. A license whose media lists other words, such as social, allows no runs. The cloud surface is the Omnichar Cloud dashboard and api is any API key; app is reserved for the desktop app and matches nothing yet. Any other field is kept exactly as you send it, so you can record terms we don’t model yet.

Secret licenses

A secret license names no licensee. You get a secret with it, and any Omnichar team that enters the secret holds the license, as many teams as you share it with. Use one per partner: a secret for one studio, another for the next, each with its own scope and dates. Revoking one blocks only the teams that entered it. Leave out all three licensee fields and add an optional label, your own name for who it is for:
The answer is the license with "kind": "secret", "licensee_team_id": null and one extra field, secret, which starts lsk_live_ (or lsk_test_ in sandbox). The key and the secret do different jobs: Treat the secret like a password: anyone who has it and the file can generate with the character under the license’s terms until you revoke it.

Share it by email

In the dashboard, Share via email on a license sends it from Omnichar with your team’s name and logo: a Generate button that adds the character to the recipient’s account and opens it in one click, a download of the .char (link valid 7 days, counted in the license’s downloads, and stopped once you revoke), the secret, the terms, and a button to verify the license. The headline names you by your first name, with your verified email beside it, and replies come back to you. Owners and admins set the logo under Settings → Licensing. Up to 20 emails an hour per team.

Get the secret again

GET /v1/licenses/{key}/secret · scope licenses:write Returns {"key": "...", "secret": "lsk_live_..."} for a secret license your team issued. Every reveal is recorded in your team’s audit log.

The file to send

POST /v1/licenses/{key}/share-file · scope licenses:write Returns a download link, valid for 15 minutes, to a copy of the character’s .char whose manifest carries the signed license block, so it can be verified offline. The file never contains the secret. Send the file and the secret separately.

Entering a secret

POST /v1/licenses/redeem · scope chars:read
license_key is the key in the .char the secret came with (reserved.license.key in its manifest). The secret works only with that file’s license, so the two have to arrive together. The caller’s team now holds the license: the character is in its licensed characters and its runs are checked against the license like any licensee’s. Entering it again changes nothing. A run can also carry the secret in license_context.secret, which enters it on the way, so an API caller need not redeem first. The run must name the licensed character by char_id. A wrong secret, a secret with another license’s key, a sandbox secret on a live key and the reverse all answer 404. A revoked or expired license answers 403 with the reason. Your own team cannot redeem its own secret. Redeeming is limited to 10 tries a minute per team. You get license.redeemed each time a new team enters the secret, with that team’s id as redeemer_team_id. The license’s usage shows every holder’s runs; each holder sees only its own.

List licenses

GET /v1/licenses · scope licenses:read
role is provider (licenses you issued), licensee (licenses you hold) or any, the default. The list holds the newest 200.

Revoke a license

POST /v1/licenses/{key}/revoke · scope licenses:write
A reason is required. The status changes at once, verify answers revoked from then on, and both teams get license.revoked.

In the dashboard

A provider team has a Licenses page in Omnichar Cloud. It lists every license the team issued, with tabs by status. Each row shows the character, the licensee and the runs used against max_generations. Select a license to open its usage, check it on the verify page, or revoke it with a reason. Use the Production and Sandbox switch at the top to see the licenses in each environment. To issue a secret license from the dashboard, open Characters, press the license button on one of your characters, fill in who it is for and the terms, and copy the secret. A license detail on the Licenses page shows the secret again, the file to send, and the license’s usage. Characters you built in the dashboard can be licensed this way too; the first license signs the character as yours. Named licenses are issued through the API.

Expiry

A license is expired from ends_at. Verify reports it straight away; the license.expired event follows within five minutes.