Skip to main content
Every request to the Verseodin API must carry an Authorization header with a Bearer token issued from the dashboard. There’s no OAuth flow, no per-request signing — just one header, one key.
Authorization: Bearer vso_<48 hex chars>

Where to get a key

verseodin.com/dashboard/settings/api-keysGenerate key. The plaintext key is shown exactly once in the modal. Copy it, store it somewhere your app can read it (env var, secrets manager), then dismiss the modal. If you lose it, revoke and generate a new one — there’s no way to recover the original.

One key, two surfaces

The same vso_… key authorises: There’s no separate “MCP key” or “API key” — they’re the same row in the same table. Revoking from the dashboard kills both surfaces simultaneously.

What the key authorises

A key is bound to the user who generated it. It can read:
  • Every universe owned by that user
  • Every history row, prompt, metric belonging to those universes
It cannot:
  • Modify any data (the API is GET-only)
  • Read other users’ universes (each request goes through ownership verification)
  • Issue new keys, change account settings, or do anything outside the data-read scope

Key rotation playbook

If you suspect a key is leaked (committed to git, leaked in logs, copy-pasted into a chat):
1

Generate the new key first

Open the dashboard, click Generate key, copy the new vso_… value.
2

Update your apps to use the new key

Push the new key to your secrets manager / env vars, redeploy.
3

Revoke the leaked key

In the dashboard, click Revoke on the old key. The next request that uses it gets 401 authentication_error immediately.
The order matters — revoke the old key only after every consumer is on the new one, otherwise you’ll see traffic fail in between.

Failure modes

ScenarioResponse
Missing Authorization header401 authentication_error — “Missing or malformed Authorization header.”
Header present but doesn’t start with Bearer 401 authentication_error
Key not in our table (typo, fake key)401 authentication_error — “invalid or missing api key”
Key was revoked401 authentication_error
Key exists and is valid → owns the universe200 (assuming filters are valid)
Key exists and is valid but doesn’t own the requested universe403 permission_error — “access denied: this universe does not belong to your account”
The 401 vs 403 split is intentional: 401 means “we don’t know who you are or your key is dead”; 403 means “we know who you are, you just can’t touch this resource.”