Skip to main content

Authentication

Breaking change (existing users)

sk- keys no longer have access to /v1/account/* (balance, usage, history). Issue an mk- key with the account:read scope and update your dashboard / billing code.

The Router accepts two kinds of credentials, distinguished by prefix:

Key typePrefixWhat it's for
API keysk-Call inference endpoints (/v1/chat/completions, etc.). Billed against your deposit.
Management keymk-Administer your account: list / create / revoke API keys, read balance and usage. Not billed.

Ship sk- keys to the runtime that actually calls models; use mk- keys for dashboards, audit integrations, and CI that needs to provision or rotate API keys.

Both kinds go in the Authorization header — same shape:

Authorization: Bearer sk-YOUR_API_KEY
Authorization: Bearer mk-YOUR_MANAGEMENT_KEY

No OAuth flow, no wallet signature per request, no session tokens. For the full request / response shape of every endpoint, see the Router API reference.

Permission matrix

One table covers what each credential can do and what scope it needs. = allowed, = 403 insufficient_scope.

ScenarioEndpointsk- API keymk- Management key
Run inferencePOST /v1/chat/completions (etc.)
Read balance / usage / historyGET /v1/account/*account:read
List API keysGET /v1/api-keyskeys:read
Create API keyPOST /v1/api-keyskeys:create
Edit / revoke API keyPATCH/DELETE /v1/api-keys/:idkeys:manage
Manage management keysANY /v1/management-keys/*❌ — wallet JWT only

Two guardrails worth calling out:

  • Management keys cannot manage other management keys. ANY /v1/management-keys/* requires the wallet JWT (sign-in session). A leaked mk- cannot mint replacements for itself.
  • keys:manage and keys:create are deliberately split. A read-only audit integration that should be able to revoke a compromised key but not issue replacements gets {keys:read, keys:manage} and is locked out of issuance.

API keys (sk-)

Created at pc.0g.ai → Dashboard → API Keys. From there you can:

  • Create a new key — label it so you can tell keys apart (e.g. staging, agent-bot, my-laptop). The full secret is shown once on creation; copy it immediately. The dashboard only stores a hash.
  • List existing keys with their labels, created-at, and last-used timestamps.
  • Revoke any key instantly — in-flight requests using a revoked key return 401 api_key_revoked on their next call.

Management keys (mk-)

Created at pc.0g.ai → Settings → Management Keys. Each key carries an explicit allowlist of scopes — see the matrix above.

When creating a key, pick a preset or check scopes individually:

  • Read-onlyaccount:read, keys:read. Dashboards, monitoring.
  • Key Managerkeys:read, keys:manage. Rotate / revoke existing keys, no issuance.
  • Full Admin — all four scopes. CI that provisions per-deploy API keys.
  • Custom — pick any subset.

Audit fields. Every successful request with an mk- key updates last_used_at and last_source_ip on the key. Writes are coalesced to at most one per key per 60 seconds. IPv4-mapped IPv6 addresses (::ffff:1.2.3.4) are normalized to dotted-quad so a dual-stack vs IPv4-only listener doesn't make one client look like two. (sk- keys don't record these — their audit signal is usage / billing.)

Expiration. Management keys do not expire. Rotate on a schedule by issuing a replacement and revoking the old key.

Best practices

  • One key per deployment. Separate staging / production / per-service keys so you can revoke one without touching the others.
  • Least privilege for mk-. Don't grant keys:create to an integration that only needs to read. The preset selector is there for a reason.
  • Rotate on suspicion. If a key might have leaked, revoke it and issue a new one — takes seconds.
  • Watch last_used_at on management keys. A key that hasn't been used in months is a key you can probably revoke.
Never ship keys to browsers

Whoever has your sk- key can spend the 0G tokens you deposited; whoever has your mk- key can issue more sk- keys. Keep both server-side and proxy client requests through your own backend.