Authentication
Create an API key in the dashboard and send it as a Bearer token.
The Sandbox API authenticates with an API key — a long-lived secret that stands in for your account. You create keys in the dashboard and send them as a Bearer token on every request.
Key format
A key is an opaque secret: the prefix omg_sk_ followed by 32 random bytes
(base64url). The server stores only a SHA-256 hash of the key and shows
you the plaintext exactly once, at creation:
omg_sk_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6...The first 12 characters (e.g. omg_sk_abc12) are the key's non-secret
prefix — that's what the dashboard shows in the key list so you can tell
keys apart. The full secret is never shown again.
API keys currently carry a single scope: sandbox. They resolve to the
better-auth user that owns them and act as a normal user principal — a key
can only create and manage sandboxes owned by that user, and a key cannot
manage API keys.
Create a key
- Open omg.dev/sandbox and sign in (signed-out visitors get a sandbox landing first, then continue into the product).
- Go to Keys (or navigate straight to
/sandbox/keys). - Click New key, give it a name (required, up to 80 characters), and Create key.
- Copy the secret immediately — it's shown exactly once and starts with
omg_sk_. If you lose it, revoke the key and make a new one.
Key creation and management happen with your dashboard session — the
POST /v1/api-keys endpoint requires a dashboard JWT, not an API key. See the
Reference for the raw
management shapes.
Limits: at most 10 active keys per account, and at most 5 key
creations per hour. Exceeding the creation rate returns 429.
Treat the key like a password. Anyone holding it can create and control sandboxes billed to your account. Store it in a secret manager or an environment variable — never commit it to git or paste it into client-side code.
Use the key
Send the key in the Authorization header as a Bearer token. Every
/v1/sandboxes* route accepts it:
curl https://infra.omg.dev/v1/sandboxes \
-H "Authorization: Bearer $OMG_API_KEY"In JavaScript:
const res = await fetch("https://infra.omg.dev/v1/sandboxes", {
headers: { Authorization: `Bearer ${process.env.OMG_API_KEY}` },
})Everything is owner-scoped: a GET /v1/sandboxes returns only your
sandboxes, and you can only control sandboxes you own. Sandboxes you create
with an API key are raw programmatic sandboxes (no project/session/app
attribution) and list with kind: "api".
Revoking a key
Revoke a key any time from Sandboxes → API keys — click the trash icon on
the row and confirm (or DELETE /v1/api-keys/{id} with your dashboard
session). Revocation is permanent and effective almost immediately: the
next request made with that key gets 401 Unauthorized. Revoking one key never
affects your others.
Rotate keys the same way: create a new key, deploy it, then revoke the old one
once nothing is using it. You can also set an expiresAt when creating a
key so it expires on its own.
Errors
| Status | Meaning |
|---|---|
401 Unauthorized | Missing, unknown, revoked, expired, or malformed key. |
403 Forbidden | The key is valid but doesn't own the target resource. |
429 Too Many Requests | Key-creation rate limit (5/hour). |
Keeping keys safe
- Prefer a per-environment key (one for CI, one for production) so you can revoke a single blast radius.
- Read the key from the environment (
process.env.OMG_API_KEY), not a literal in source. - Never ship a key to the browser. If your frontend needs a sandbox, mint it from your server and hand the client only what it needs (e.g. a preview URL).