API authentication

How to authenticate against the SIMCOAI API and keep your keys safe.

Keys

Authenticating a request

Send your API key in the X-SIMCOAI-API-Key header on every request (an Authorization: Bearer <key> header also works, for clients that only support that convention). Keys are issued and revoked from the dashboard, and each one carries a scope list that limits exactly what it can do.

curl -sS https://api.simcoai.co.uk/calling/live-calls \
  -H "X-SIMCOAI-API-Key: $SIMCOAI_API_KEY" \
  -H "Content-Type: application/json"
Scopes

What a key can do

Every key is scoped to specific resources and read or write access - a key made for one integration cannot silently do more than it was given. A key with the blanket read or write scope, or full, clears any check; otherwise each resource has its own resource:read / resource:write pair (for example orders:read, bookings:write).

ErrorWhat it means
SIMCOAI_SECRET_KEY_REQUIREDNo key was sent on the request at all.
SIMCOAI_INVALID_KEY_FORMATThe value sent is not shaped like a real SIMCOAI key.
SIMCOAI_KEY_NOT_FOUNDThe key does not match any active key, or it has been revoked.
SIMCOAI_KEY_EXPIREDThe key has passed its own expiry date, if one was set when it was created.
SIMCOAI_SCOPE_REQUIREDThe key is valid but does not include the scope this endpoint needs. The response lists the scope required and the scopes the key actually has, so you can tell immediately which to add.
ACTIVE_SUBSCRIPTION_REQUIREDThe key is valid and scoped correctly, but the account has no active or trialing subscription - required before write operations run.

All of these return HTTP 401, except a missing scope (403) and a lapsed subscription (402) - see API errors for the full error reference.

Idempotency

Safe retries

Any request that creates something accepts an idempotency key. Send the same key on a retry and the original result is returned rather than a duplicate being created. See Idempotency and duplicates for the full mechanics.

curl -sS -X POST https://api.simcoai.co.uk/calling/live-calls/CAxxxx/commands \
  -H "X-SIMCOAI-API-Key: $SIMCOAI_API_KEY" \
  -H "X-SIMCOAI-Idempotency-Key: refund-8815-attempt-1" \
  -H "Content-Type: application/json" \
  -d '{"command":"escalate"}'
Handling keys

Keeping keys safe

Treat an API key like a password. These rules are not optional.

Server side only

Never put a SIMCOAI API key in browser JavaScript, a mobile app bundle or a public repository.

Rotate on exposure

If a key may have leaked, revoke it in the dashboard and issue a new one. Revocation takes effect immediately.

One key per integration

Separate keys per system mean you can revoke one without breaking the others.

Scope narrowly

Grant only the resource scopes an integration actually needs - a key limited to orders:read cannot be used to create refunds even if it leaks.

See also rate limits for the request ceilings that apply regardless of which key you use.