ψcatstate

platform

Authentication

CatState users authenticate with a single API key — an org key or a delegated sub-key. QPU access is BYOA-only: provider credentials live in the vault, never in your code.

API keys

Two token formats exist. Org keys start with cs_live_, sub-keys with cs_sub_. Both are 32 random alphanumeric characters (~190 bits of entropy). Plaintext is never stored — only a SHA-256 hash — so copy the token when it's minted; it cannot be retrieved again.

request headersjson
{
"Authorization": "Bearer cs_sub_9fa8b7c6d5e4...",
"Idempotency-Key": "7b9a2c1f-4e5a-4b6c-8d7e-1f2a3b4c5d6e"
}

The SDK

The SDK reads CATSTATE_API_KEY from the environment. A sub-key works anywhere an org key does — scope is enforced server-side:

connect.pypy
import catstate
 
cs = catstate.connect() # org key OR sub-key
 
cs.devices() # devices visible to this key's allowlist
cs("ionq:aria") # allowed if ionq:aria is in scope

Human auth (dashboard)

The dashboard doesn't use API keys. Login screens call the dedicated auth service, which sets short-lived JWT access tokens and refresh tokens in httpOnly cookies. The core API validates JWTs statelessly — no database round-trip. Machine-to-machine traffic (SDKs, CI) always uses Bearer API keys.

Rate limits

Job submission is limited to 300 requests/minute per key; reads to 600/minute. Exceeding a limit returns 429 with a Retry-After header. The unauthenticated simulator playground is capped at 10 requests/minute per IP.