Skip to main content
This walks through the whole API with a sandbox key. Nothing in sandbox runs on a GPU or spends your build balance, so you can repeat it as often as you like. You need:
  • A team on Omnichar Cloud where you are an owner, admin or developer.
  • A sandbox key (sk_test_...) from Settings → API keys, with your team selected. See Authentication.
  • A second team to license the character to, with its slug and a sandbox key of its own with the runs:write scope. Licenses are issued by provider teams; ask us to switch the provider flag on for your team.
1

Check the key

The answer names your team and "env": "sandbox". If it says production, you are using a live key.
2

Upload four face photos

A character needs 4 to 12 face photos. For each one, ask for an upload link, then send the bytes to it. bytes must be the file’s exact size:
Keep each upload_key: it is what you pass as a reference. An upload link lasts 10 minutes. Repeat for face-2.png to face-4.png. Uploads has the limits, the voice clip and a script that uploads a whole folder.
3

Create a character

Replace the four inputs/... values with your own upload keys.
4

Wait for char.ready

In sandbox the build finishes about 30 seconds later. If your team has a webhook for char.ready, it arrives then. Without one, poll:
5

Issue a license

Pick a starts_at that has already passed, so verify answers valid straight away.
6

Verify it

Verification needs no API key, but it needs the license’s signature, which a verifier reads from the .char the license came in. Here you take it from the issue answer:
7

Generate as the licensee

The licensee names the character by char_id and says how it will use it:
In sandbox the run renders a placeholder about 10 seconds later. Its output carries the license in its metadata:
A usage.generated event goes to both teams. Your own report shows it too:
8

Download the licensee's copy

The license in a .char shows how to check that block offline.
9

Revoke it and verify again

Both teams’ license.revoked webhooks fire at the same time. The licensee’s next run and download are refused:
and you get usage.blocked for each refusal.

Next steps