Skip to main content

API Keys

API keys are the primary authentication mechanism for the PolySimulator API. Each key is tied to a user account, has configurable permissions, and can be revoked instantly.

Create a Key

curl -X POST https://api.polysimulator.com/v1/keys \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-trading-bot",
    "permissions": ["read", "trade"],
    "tier": "free"
  }'
Response (201 Created):
{
  "id": 1,
  "raw_key": "ps_live_kJ9mNx2pQrStUvWxYz01Ab3CdEfGhI4j...",
  "key_prefix": "ps_live_kJ9mNx2p",
  "name": "my-trading-bot",
  "rate_limit_tier": "free",
  "permissions": ["read", "trade"],
  "created_at": "2026-02-06T12:00:00Z"
}
The raw_key field is shown exactly once. Store it securely — it cannot be retrieved again. Only the SHA-256 hash is stored in the database.
FieldDescription
idNumeric key ID (used for revocation)
raw_keyFull API key — save this immediately
key_prefixFirst 16 chars (used for identification in listings)
nameYour label for this key
rate_limit_tierfree, pro, or enterprise
permissionsArray of granted permissions
created_atISO 8601 timestamp

List Keys

Returns all keys for your account. Only prefixes are shown — never the full key.
curl -H "X-API-Key: $API_KEY" https://api.polysimulator.com/v1/keys
[
  {
    "id": 1,
    "key_prefix": "ps_live_kJ9mNx2p",
    "name": "my-trading-bot",
    "permissions": ["read", "trade"],
    "rate_limit_tier": "free",
    "is_active": true,
    "created_at": "2026-02-06T12:00:00Z",
    "expires_at": null
  }
]

Revoke a Key

Permanently deactivates a key. This action cannot be undone.
curl -X DELETE -H "X-API-Key: $API_KEY" \
  https://api.polysimulator.com/v1/keys/1
{
  "message": "Key revoked successfully"
}

Key Limits

ConstraintValue
Max keys per user5
Key formatps_live_<64 hex chars>
StorageSHA-256 hash only
ExpirationOptional expires_at field

Error Handling

StatusEndpointMeaning
201POST /v1/keysKey created — save raw_key immediately
400POST /v1/keysMax 5 keys reached, or unknown tier
400POST /v1/keys/bootstrapYou already have key(s) — use POST /v1/keys with X-API-Key
401AnyInvalid, expired, or deactivated API key
401POST /v1/keys/bootstrapInvalid or expired Supabase JWT
403POST /v1/keysAPI access restricted (allowlist)
# Robust key creation with error handling
resp = requests.post(
    f"{BASE_URL}/v1/keys",
    headers={"X-API-Key": API_KEY},
    json={"name": "my-bot", "permissions": ["read", "trade"]},
)

if resp.status_code == 201:
    key_data = resp.json()
    print(f"Save this key NOW: {key_data['raw_key']}")
elif resp.status_code == 400:
    err = resp.json()
    print(f"Cannot create key: {err.get('message', err.get('error'))}")
elif resp.status_code == 401:
    print("API key is invalid or expired — re-authenticate")
else:
    print(f"Unexpected error: {resp.status_code}")

Next Steps