Skip to content
Coritan Docs

Authentication

Which credential each part of the Coritan API accepts, how to get and refresh an access token, and what API keys do today.

View as Markdown

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.

Sign 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_in gives its lifetime in seconds.
Refresh token
Gets a new pair from POST /auth/refresh with 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: true and an mfa_token that lasts 10 minutes (expires_in: 600). Send it as the bearer token to POST /auth/mfa/verify with {"code": "123456"}, and the answer holds the access and refresh tokens. Every other route refuses it with 401 and "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.

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 403 Not a member of this organization.
Staff console token
A console session for one organization, from POST /orgs/{org_slug}/staff/auth/login with your Coritan email and password. Its tokens start with ost_. The access token lasts 24 hours, and POST /orgs/{org_slug}/staff/auth/refresh swaps 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, and POST /orgs/{org_slug}/auth/refresh swaps 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 with ct_, 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 with pk_test_. A live key starts with pk_live_, and works once the store is live.
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 from X-Api-Key only, never from Authorization. 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 answers 401 Invalid or expired token. Use an access token instead. Manage API keys explains what the keys are for today.

Coritan 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:

JSON
{"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.

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

MethodPathWhat it does
POST/api/v1/auth/loginLogin
POST/api/v1/auth/refreshRefresh
GET/api/v1/auth/turnstileTurnstile config