Every endpoint except login, token refresh, and the health checks needs a credential:
| Credential | Header | Use it for |
|---|---|---|
| API key | X-Api-Key: <key> | Scripts, pipelines, notebooks, MCP clients. Most endpoints. |
| Access token | Authorization: Bearer <token> | Managing API keys and using the Assistant, which refuse API keys. Works everywhere else too. |
Each endpoint in the reference is marked API key or token, Access token only, or No auth.
API keys
Create keys on your account's API keys page, or with Create an API key (which needs an access token). The secret is returned once, at creation or rotation; afterwards keys are listed by name and key_prefix only.
Options when you create a key through the API:
| Field | Meaning |
|---|---|
name | 1 to 64 characters, unique among your keys. |
scopes | ["read"], ["write"], or both (the default). |
expires_at | When the key stops working. At least one minute in the future. |
spend_ceiling_usd | The most work started with this key may reserve in a calendar month (UTC). |
allow_structure_search | Let this key send SMILES to ChEMBL for similarity and substructure search. Off by default. |
For a key you give to an AI client, use read (add write only if it should start work), an expiry, and a spend ceiling.
Scopes
read: everyGET, plus the free estimates and checks: Estimate job reservation cost, Validate a WorkflowSpec, Estimate a workflow run's cost, and the science lookups.write: anything that starts, changes, or deletes something: submits, workflow runs and definitions, cancel, resume, uploads, deletes.
A call outside the key's scopes returns 403 (insufficient-scope).
Managing keys
List, rename, rotate (new secret; the old one stops working at once), and revoke (permanent) keys with an access token. Sending an API key to these endpoints returns 403 (api-key-management-forbidden), so a leaked key can't create more keys.
Each plan allows a set number of keys (Plans and limits); at the limit, creating one returns 403 (api-key-limit-exceeded).
Access tokens
Log in with email and password takes a form-encoded username (your email) and password and returns an access_token, a refresh_token, and expires_in (seconds).
curl -X POST https://api.cognichem.com/api/v1/auth/login-email \
--data-urlencode "[email protected]" \
--data-urlencode "password=$COGNICHEM_PASSWORD"Before the access token expires, exchange the refresh token for a new pair with Refresh an access token, sending {"refresh_token": "…"} as JSON. Never put a refresh token in a URL. Log out ends the session.
In Python, client.auth.login_email(email, password) stores the token on the client.
Errors
401: the credential is missing, wrong, revoked, or expired. Log in again or use another key.403: the credential is valid but not allowed here: a missing scope, an API key on a token-only endpoint, a spend ceiling, or a plan limit. The problem'stypesays which. See Errors.