> ## Documentation Index
> Fetch the complete documentation index at: https://docs.omnichar.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Using licensed characters

> How a licensed Omnichar character is protected: who can generate with it, how every run and download is checked against the license, and what a licensee can and cannot do.

A character is **protected** once it was built with a `provider_receipt` or any license has been issued for it. Every image, video and download with a protected character is checked against a license. Characters with neither behave as before: no checks, no context, no usage records.

## Who can use a protected character

| Team | Can generate | Notes |
| - | - | - |
| The provider that built it | Always | For checking its own work. Each run is logged as usage with no license key. |
| A team holding a license for it in the same environment | While the license allows it | Every run is checked; see below. A team holds a license it was named on, or a [secret license](https://docs.omnichar.org/api/licenses.md#secret-licenses) whose secret it entered. |
| Anyone else | No | `403` with the reason `no_license`. |

A sandbox license works only with sandbox keys and a production license only with live ones.

## What is checked

Each run is checked when you start it, and again when it leaves the queue for a renderer, so a license revoked or expired while the run waited still stops it. In order:

1. Your team has a license for this character in this environment.
2. Its signature is valid, it is not revoked, and now is between `starts_at` and `ends_at`.
3. The run's output type (`image` or `video`) is in `scope.media`.
4. Your `use` matches `scope.use`.
5. Your `territory` is in `scope.territories`, or the license is `worldwide`.
6. If `scope.allow_list` is set, it allows where the run comes from and your team.
7. If `scope.max_generations` is set, it has not been reached.

`use` and `territory` come from you: see [License context](https://docs.omnichar.org/api/license-context.md). The first check that fails is the reason you get back; the [reasons are listed here](https://docs.omnichar.org/api/errors.md#license-checks). A blocked run never holds or charges credits. Runs that are not images or videos, such as training, are the provider's alone.

## Generating with the API

You need a key with `runs:write`. Name the character by `char_id` and send `license_context`:

```bash theme={null}
curl -s -X POST https://api.omnichar.org/v1/runs \
  -H "Authorization: Bearer $OMNICHAR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "slug": "default-flux-2-klein-4b",
    "characters": { "character": { "char_id": "7f1c2a9e-..." } },
    "license_context": { "use": "advertising", "territory": "SE" }
  }'
# -> {"runId":"0b6e...","status":"queued"}
```

`inputs` and `files` work as on any other run. Read it back with `GET /v1/runs/{id}` and its files with `GET /v1/runs/{id}/outputs`, both with `runs:read`.

## The licensee's library

`GET /v1/characters/licensed` (scope `chars:read`) lists the characters licensed to your team, one per character, with its best license:

```json theme={null}
{
  "items": [
    {
      "char_id": "7f1c2a9e-...",
      "character_id": "a2b4...",
      "name": "Ada Lind",
      "provider": { "team_id": "2c0d...", "name": "Northlight Talent" },
      "license": {
        "key": "lic_live_Q2x8...",
        "status": "active",
        "use": "advertising",
        "media": ["image", "video"],
        "territories": ["SE", "NO"],
        "starts_at": "2026-12-01T00:00:00.000Z",
        "ends_at": "2027-06-01T00:00:00.000Z"
      }
    }
  ]
}
```

In Omnichar Cloud the same characters appear under **Characters → Licensed**, with the provider's name, what the license allows and when it ends. A character whose license is pending, revoked or expired is shown greyed out with the reason, and cannot be cast.

## Downloading the .char

`POST /v1/licenses/{key}/download` (scope `chars:read` or `licenses:read`) returns a link to your own copy of the latest version, valid for 15 minutes:

```json theme={null}
{ "download_url": "https://...", "version": 2, "expires_at": "2026-11-10T10:15:00.000Z" }
```

Your copy carries your license in its manifest under `reserved.license`, so it can be checked offline; see [The license in a .char](https://docs.omnichar.org/api/char-license-format.md). The provider's own file is not changed. A download works only while the license is active and only where its `allow_list` allows, and each one is recorded as usage.

## What a licensee cannot do

A licensee cannot retrain, rename or delete the character, publish it to the community gallery, or issue licenses for it. Uploading a downloaded copy as a new character file does not get around any of this: the copy is recognised by its weight files and reference pictures, even renamed or with files added, and checked like the original. The same goes for a reference picture taken out of the file and uploaded on its own, as an input to a run or as a photo for a new character. A build whose photos change after it starts fails before it runs.

When a character becomes protected, any community gallery listing that carries it, the provider's own or a copy someone else published, is taken down. Contact us if a listing was taken down by mistake.

## Tagged outputs

Every image and video made with a protected character carries the license in its metadata: a PNG `tEXt` chunk named `omnichar`, or an MP4 or MOV metadata tag, holding

```json theme={null}
{ "env": "production", "characters": [{ "char_id": "7f1c2a9e-...", "license_key": "lic_live_Q2x8..." }] }
```

`license_key` is `null` on the provider's own runs. The tag is written within about a minute of the run finishing, so an output fetched the moment it appears may not carry it yet. Outputs in other formats are not tagged. Outputs of characters that are not protected are never changed.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.