Authentication
API keys, scopes, sandbox, and rotation. Bearer tokens — no sessions, no cookies.
GenieOS uses bearer authentication on every request. There are no
sessions, no cookies, and no per-call signing — just an Authorization
header. Scopes ride on the key itself; rotation is one click.
Authorization: Bearer mg_live_8a72c0e1...Key flavours
| Prefix | Use it for | Counts toward billing | Rate-limited |
|---|---|---|---|
mg_live_* | Production traffic | Yes | Yes |
mg_test_* | CI, integration tests, local dev | No | No |
mg_mcp_* | Issued by MCP installers (Cursor etc.) | Yes (per scope) | Yes |
A key always belongs to a single workspace. There is no concept of a multi-workspace key — if you operate several workspaces, mint one per workspace.
Scopes
Each key carries a set of scopes that bound what it can do. Scopes are
additive — a key with templates:read and templates:send can read and
send, but cannot create or modify templates.
| Scope | Allows |
|---|---|
workspace:read | Read workspace settings, plan, send budget |
templates:read | Read templates and the schema contract |
templates:write | Create, update, version templates |
templates:send | Send transactional and trigger sequences |
sequences:write | Author sequences and edit transitions |
events:write | Emit events into the workspace |
events:read | Read past events / audit |
webhooks:write | Create / update / delete webhook subscriptions |
webhooks:read | List subscriptions and their delivery state |
audit:read | Read paginated audit log |
mcp:* | Used by the MCP transport — never assign manually |
The dashboard exposes presets — Send-only, Read-only, Full — that compose these for you.
Generating a key
app.genieos.pro → Settings → API keys → New key. Pick a flavour (live or sandbox), pick a scope preset, name the key for the surface that will use it (e.g. "Heroku web dyno", "Vercel preview", "GitHub Actions"), then Create. The key value is shown once.
genie keys create \
--name "ci-pipeline" \
--scope templates:send \
--scope events:write \
--sandboxThe CLI prints the key value and exits non-zero if you re-run with the same name. See the CLI docs for the full subcommand surface.
Use the Install in Cursor / Install in Claude buttons in
app.genieos.pro → Developers → MCP. The browser flow mints a
short-lived mg_mcp_* key with the scopes you tick and configures your
editor with one click. Revoke from the same dashboard at any time.
See MCP for the complete install reference.
Verifying authentication
A trivial smoke test:
curl -s https://api.genieos.pro/v1/workspace \
-H "Authorization: Bearer $GENIEOS_API_KEY" \
| jq .A successful call returns the workspace document. Failures use the standard error envelope:
{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "API key revoked or never issued.",
"request_id": "req_01JABC..."
}
}| Status | Type | Most likely cause |
|---|---|---|
| 401 | authentication_error | Missing / malformed / revoked key |
| 403 | permission_denied | Key is valid but doesn\u2019t have the required scope |
| 404 | not_found | Resource exists in another workspace |
| 429 | rate_limit_exceeded | See Rate limits |
Rotation
Keys can be rotated without downtime. The flow:
- Create a new key with the same scopes; deploy it alongside the old one.
- Verify production traffic on the new key (the dashboard shows last-used per key).
- Click Revoke on the old key. Revocation is instant — the API rejects the old key on the next request.
For SDK-based integrations the SDK reads GENIEOS_API_KEY at startup, so
a rolling deploy is enough. For long-lived workers, signal them to re-read
the env or restart.
No grace period
Revoked keys are rejected immediately. There is no soft-revoke or grace window — if a leaked key is in the wild, killing it is the right answer every time.
Storing keys safely
- Use a secrets manager (Doppler, Vault, AWS Secrets Manager, Google Secret
Manager, GitHub/GitLab Secrets) — not committed
.envfiles. - Scope keys narrowly. A worker that only sends mail should hold a key with
templates:sendand nothing else. - Per-environment keys. One per dev / staging / production. Never reuse a production key in a sandbox-shaped place.
- Watch the audit log. Every authenticated request lands in
audit.logwithkey_idso you can correlate suspicious activity.
What\u2019s next
- Send your first request: Quickstart.
- Understand the safety net under retries: Idempotency.
- Hand authentication off to your AI editor: MCP.