Simulix

API

API Keys

Mint, list, revoke, and rotate API keys without ever leaving the API surface. Every key is hashed at rest — the raw value appears in the response of the create + rotate endpoints EXACTLY ONCE. Save it immediately.

Authentication

Every /v1/* request requires Authorization: Bearer sk_(live|test)_<64hex>. See Authentication for the full handshake.

Creating an API key

POST creates require an Idempotency-Key header (UUID) per CLAUDE.md API hard rules. Re-sending the same payload + key returns the cached response with the same raw key.

curl -X POST https://api.simulix.com/v1/api-keys \
  -H "Authorization: Bearer $SIMULIX_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "production-frontend",
    "scopes": ["simulations:read", "simulations:write"],
    "is_test": false
  }'

is_test true mints sk_test_* (sandbox tier); false mints sk_live_* (live tier). The calling key's tier governs which database the new key lands in.

Listing keys

Cursor-paginated. Pass ?limit=N&cursor=<next_cursor>. Maximum 100 per page; default 50. The response meta block carries "next_cursor", "has_more", and "returned".

Revoking a key

Revocation is immediate — the next request using the revoked key gets 401 "invalid_or_revoked_api_key". Re-revoking an already-revoked key is 409, not 200, so the operator UI can distinguish a fresh revoke from a no-op.

curl -X DELETE https://api.simulix.com/v1/api-keys/<key_id> \
  -H "Authorization: Bearer $SIMULIX_KEY"

Rotating a key

Atomic: a single transaction creates the new key and revokes the old one. No grace period — the old key is invalid the instant the response goes out. Plan your deploy window accordingly. The new key inherits the old key's scopes + expiry.

curl -X POST https://api.simulix.com/v1/api-keys/<key_id>/rotate \
  -H "Authorization: Bearer $SIMULIX_KEY" \
  -H "Idempotency-Key: $(uuidgen)"

Scopes

Six scopes available via the public API. Use the least-privilege scope set for each key — separate read-only keys for analytics vs. full-write keys for ingestion.

ScopeUse
simulations:readRead simulations + per-agent transcripts.
simulations:writeCreate simulations.
case_studies:readRead calibrated workflow catalog.
case_studies:writeOperator-only — promote workflows.
keys:readList API keys.
keys:writeCreate, revoke, rotate API keys.

Security

  • The raw key appears in the response of create_api_key + rotate_api_key EXACTLY ONCE. Persist it immediately — Simulix only stores SHA-256 hashes.
  • Sandbox keys (sk_test_*) and live keys (sk_live_*) live in physically separate databases per ADR-005. Sandbox traffic never consumes prod quota.
  • Cross-organization isolation is enforced at every query — knowing another org's key UUID returns 404 (not 403) so existence never leaks.
  • Recommended rotation cadence: every 90 days for live keys, on every employee offboarding for ops keys.

Endpoint reference

MethodPathScopeStatusSummary
POST/v1/api-keyskeys:write201Mint a new key. Raw value returned ONCE.
GET/v1/api-keyskeys:read200Cursor-paginated list (max 100/page).
DELETE/v1/api-keys/{key_id}keys:write200 / 404 / 409Soft-revoke. Re-revoking is 409.
POST/v1/api-keys/{key_id}/rotatekeys:write201Atomic create-new + revoke-old. No grace period.

Bootstrap (ops only)

To mint the very first key for a new environment (before any key exists to authenticate with), use the scripts/seed-org-and-key.py CLI. It writes directly to the matching tier's database. The bootstrap key carries the wildcard scope and should be replaced by least-privilege keys via POST /v1/api-keys as soon as possible.