Authentication
Which credential each part of the Coritan API accepts, how to get and refresh an access token, and what API keys do today.
Each route of the Coritan API takes one kind of credential, and the part of the API it belongs to decides which. This page lists each credential, the header it goes in, how you get it and how long it lasts. A few routes take none, such as GET /auth/turnstile and the list of locations.
Credentials by part of the API
Section titled Credentials by part of the API| Part of the API | Paths | Credential | Header |
|---|---|---|---|
| Client API | /api/v1/..., except the paths below |
Your access token | Authorization: Bearer <token> |
| Organization API | /api/v1/orgs/{org_slug}/... |
A member's access token, or a staff console token | Authorization: Bearer <token> |
| Customer portal and storefront checkout | /api/v1/orgs/{org_slug}/portal/..., and the storefront's order and checkout routes |
A customer token | Authorization: Bearer <token> |
| Commerce API | /api/v1/orgs/{org_slug}/commerce/... |
A member's access token or staff console token, or an organization API key | Authorization: Bearer <token> or X-API-Key: <key> |
| Store API | /api/v1/orgs/{org_slug}/store/... |
The store's publishable key, plus a customer token on the routes for a signed-in shopper | x-publishable-api-key: <key>, and Authorization: Bearer <token> |
| SMTP Relay send API | /api/v1/mail/send and /api/v1/mail/send/limits |
A send API key | X-Api-Key: <key> |
Access and refresh tokens, Organization credentials and Other keys describe each credential.
Access and refresh tokens
Section titled Access and refresh tokensSign in with POST /auth/login, sending email and password as JSON. Make your first API request walks through it with curl. The answer holds access_token, refresh_token, token_type (bearer) and expires_in.
- Access token
- Proves who you are on every Client API request, and on the Organization API for each organization you are a member of. It lasts 30 minutes unless Coritan changes the setting, and
expires_ingives its lifetime in seconds. - Refresh token
- Gets a new pair from
POST /auth/refreshwith the body{"refresh_token": "..."}, with no password, verification check or second factor. It lasts 30 days unless Coritan changes the setting. Each new pair holds a refresh token with a full lifetime; the one you sent keeps working until its own expiry. - Pending token
- What the sign-in answers when two-factor authentication is on:
mfa_required: trueand anmfa_tokenthat lasts 10 minutes (expires_in: 600). Send it as the bearer token toPOST /auth/mfa/verifywith{"code": "123456"}, and the answer holds the access and refresh tokens. Every other route refuses it with401and"error": "mfa_required".
Changing or resetting the password stops every token issued before it, and a suspended or closed account cannot use any token. The API has no sign-out route. Sign out and end sessions explains how to stop a token working.
Organization credentials
Section titled Organization credentials- Member access token
- The same access token as the Client API. It reaches an organization's routes when you are its owner or a member, and your role decides what it may do. Without membership, a route answers
403Not a member of this organization. - Staff console token
- A console session for one organization, from
POST /orgs/{org_slug}/staff/auth/loginwith your Coritan email and password. Its tokens start withost_. The access token lasts 24 hours, andPOST /orgs/{org_slug}/staff/auth/refreshswaps the refresh token, which lasts 30 days, for a new pair. It reaches every route a member's access token reaches. The actions that move money or end things also need a step-up in the last 10 minutes, which only a console session has: Confirm it is you lists them. - Customer token
- A customer of an organization's storefront, from
POST /orgs/{org_slug}/auth/login. The access token lasts 24 hours and the refresh token 30 days, andPOST /orgs/{org_slug}/auth/refreshswaps them for a new pair. Sign in your storefront's customers has the details. A customer token never reaches the routes for members. - Organization API key
- Lets your own systems call the Commerce API without a person signing in. An owner or admin creates it with
POST /orgs/{org_slug}/api-keys; it starts withct_, and the answer shows it once. Its scopes decide which routes it reaches, it has an hourly request limit (4,000 by default), and it can have a list of addresses it may be used from. No route outside the Commerce API reads it. Create organization API keys lists the scopes. - Publishable key
- Names a store to the Store API, which serves shoppers, so the key can sit in your storefront's code. Create one with
POST /orgs/{org_slug}/commerce/publishable-keys. A test key starts withpk_test_. A live key starts withpk_live_, and works once the store is live.
Other keys
Section titled Other keys- Send API key
- Sends mail through one SMTP Relay service over HTTPS, and does nothing else. Create it on the relay, as Manage send API keys shows; it starts with
mk_. The send API reads it fromX-Api-Keyonly, never fromAuthorization. Send email over HTTPS has the requests. - Account API key
- The keys on the API keys tab of Settings, which start with
ct_. No route accepts them yet: sent as a bearer token, one answers401Invalid or expired token. Use an access token instead. Manage API keys explains what the keys are for today.
The verification check
Section titled The verification checkCoritan can put a verification check (Cloudflare Turnstile) on the forms that sign people in or give something away for free. GET /auth/turnstile says whether it is on:
{"enabled": true, "site_key": "..."}
While it is on, these routes also need a turnstile_token in the body. Only the check on a web page makes one, so a script cannot sign in with a password while the check is on.
| API | Routes |
|---|---|
| Client API | POST /auth/login, POST /auth/register, POST /auth/forgot-password, POST /auth/reset-password, and POST /services/order for a plan that costs nothing |
| Organization API | POST /orgs/{org_slug}/auth/register, POST /orgs/{org_slug}/staff/auth/login, POST /orgs/{org_slug}/staff/auth/forgot-password, and a storefront order for a plan that costs nothing |
Without a token, or with one that did not pass, the route answers 403 with {"detail": {"error": "turnstile_failed", "message": "Verification required"}}. The message is Verification failed for a token that did not pass.
Authentication errors
Section titled Authentication errors| Status | detail |
Meaning |
|---|---|---|
403 |
Not authenticated |
A Client API route got no Authorization header. |
403 |
Invalid authentication credentials |
The Authorization header does not start with Bearer. |
401 |
Invalid or expired token |
The token is not one Coritan issued, or it has expired. Refresh it, or sign in again. |
401 |
Invalid token type |
A refresh token was sent where an access token belongs. |
401 |
Invalid refresh token |
POST /auth/refresh was sent a token that is not a refresh token. |
401 |
{"error": "mfa_required", ...} |
A pending token was sent to a route other than the two-factor routes. Finish the sign-in first. |
401 |
Token invalidated by password change |
The password changed after the token was issued. Sign in again. |
403 |
Account is suspended or closed |
The account cannot sign in or use a token. |
401 |
Missing bearer token |
An Organization API route got no Authorization: Bearer header. |
403 |
Not a member of this organization |
The token is valid, but you are not a member of that organization. |
404 |
Organization not found |
No active organization has that slug. With an organization API key, the slug is not the key's organization. |
401 |
Token expired |
A staff console token has expired. Refresh it. |
403 |
{"error": "reauth_required", ...} |
The action needs a step-up, and the last one was more than 10 minutes ago. |
401 |
Invalid API key |
A Commerce API request sent an X-API-Key that is wrong or revoked. |
403 |
API key is not allowed from this address |
The request came from an address outside the organization API key's allow-list. |
403 |
Organization inactive |
The organization API key's organization is not active. |
403 |
{"error": "scope_required", ...} |
The organization API key lacks the scope the route needs. The message names it. |
401 |
{"error": "publishable_key_required", ...} |
A Store API request had no x-publishable-api-key header. |
401 |
{"error": "invalid_publishable_key", ...} |
The publishable key is wrong, revoked, or belongs to another store. |
401 |
X-Api-Key header required |
A send API request had no X-Api-Key header. |
Errors describes the shapes of detail, and Rate limits the 429 that too many failed sign-ins bring.
API operations on this page
| Method | Path | What it does |
|---|---|---|
POST | /api/v1/auth/login | Login |
POST | /api/v1/auth/refresh | Refresh |
GET | /api/v1/auth/turnstile | Turnstile config |