Skip to content
Coritan Docs

Client API: Authentication

Register, sign in, refresh tokens and manage your profile, and see or sign out the devices signed in to your account.

View as Markdown

Register, sign in, refresh tokens and manage your profile, and see or sign out the devices signed in to your account. Send the access JWT from sign in as a Bearer token.

Base URL: https://api.coritan.com/api/v1. Paths below are complete.

To try these requests in the browser, open the interactive Client API reference.

Method Path Summary
POST /api/v1/auth/forgot-password Issue a reset link by email
POST /api/v1/auth/login Login
POST /api/v1/auth/logout Sign this device out on the server
GET /api/v1/auth/mailbox-availability Live check behind the sign-up form's username field
GET /api/v1/auth/mailbox-domain Mailbox domain
GET /api/v1/auth/me The signed-in account
PUT /api/v1/auth/me Update me
GET /api/v1/auth/me/api-keys List keys
POST /api/v1/auth/me/api-keys Create key
DELETE /api/v1/auth/me/api-keys/{key_id} Revoke key
POST /api/v1/auth/me/password Change the password
GET /api/v1/auth/me/staff-link Get staff link
POST /api/v1/auth/me/staff-link Redeem staff link
DELETE /api/v1/auth/me/staff-link Remove staff link
POST /api/v1/auth/refresh A new token pair for a refresh token, which is then used up (app/domains/auth/sessions.py)
POST /api/v1/auth/register Create an account and sign it in
POST /api/v1/auth/reset-password Reset password
GET /api/v1/auth/sessions Where this account is signed in, newest activity first
POST /api/v1/auth/sessions/revoke-others Sign out everywhere except this device
DELETE /api/v1/auth/sessions/{session_id} Sign out one device
GET /api/v1/auth/turnstile Turnstile config

POST /api/v1/auth/forgot-password

Issue a reset link by email. The answer is the same whether or not the address has an account, so the form cannot be used to probe for one.

application/json (required)

Field Type Required
email string (email) yes
turnstile_token string or null no
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

POST /api/v1/auth/login

application/json (required)

Field Type Required
email string (email) yes
password string yes
turnstile_token string or null no
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Sign this device out on the server

Section titled Sign this device out on the server

POST /api/v1/auth/logout

Sign this device out on the server.

Send the access token as the bearer, the refresh token in the body, or both: an expired access token is fine when the refresh token names the session. A refresh token from before sessions existed is recorded as signed out, so it can never refresh again.

Authentication: an access token, sent as Authorization: Bearer <token>.

application/json

Field Type Required
refresh_token string or null no
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Live check behind the sign-up form's username field

Section titled Live check behind the sign-up form's username field

GET /api/v1/auth/mailbox-availability

Live check behind the sign-up form's username field.

Name In Type Required
local_part query string yes
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

GET /api/v1/auth/mailbox-domain

Whether this storefront offers a mailbox on its own mail domain at sign-up, and which domain. Public: the form reads it before anyone has an account.

Status Meaning
200 Success.

GET /api/v1/auth/me

The signed-in account. credit_balance is in credit_currency, always USD; currency is the currency we charge the account in and never labels the balance. support_session says the token is a support session Coritan support opened as the account, with its mode and when it ends, so the page can say so; it is null for the account's own sign-in.

Authentication: an access token, sent as Authorization: Bearer <token>.

Status Meaning
200 Success.

Fields of a 200 response:

Field Type Description
id integer
email string
first_name string or null
last_name string or null
company string or null
status string
billing_mode string
credit_balance number
credit_currency string The currency credit_balance is held in. Always USD, whatever currency says.
currency string The currency we charge this account in (its preferred pay currency). It never labels credit_balance.
country_code string or null
currency_source string
created_at string (date-time)
support_session SupportSessionInfo or null Set when the token is a support session Coritan support opened as this account (read_only or full), null for the account's own sign-in. A page that receives a support session shows whose account it is and that the session ends.
support_session.mode string read_only, servers (an organization's customer only) or full.
support_session.expires_at string (date-time) or null When the session ends. It cannot be renewed.

PUT /api/v1/auth/me

Authentication: an access token, sent as Authorization: Bearer <token>.

application/json (required)

Field Type Required
first_name string or null no
last_name string or null no
company string or null no
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Fields of a 200 response:

Field Type Description
id integer
email string
first_name string or null
last_name string or null
company string or null
status string
billing_mode string
credit_balance number
credit_currency string The currency credit_balance is held in. Always USD, whatever currency says.
currency string The currency we charge this account in (its preferred pay currency). It never labels credit_balance.
country_code string or null
currency_source string
created_at string (date-time)
support_session SupportSessionInfo or null Set when the token is a support session Coritan support opened as this account (read_only or full), null for the account's own sign-in. A page that receives a support session shows whose account it is and that the session ends.
support_session.mode string read_only, servers (an organization's customer only) or full.
support_session.expires_at string (date-time) or null When the session ends. It cannot be renewed.

GET /api/v1/auth/me/api-keys

Authentication: an access token, sent as Authorization: Bearer <token>.

Name In Type Required Description
limit query integer no Default: 200.
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

A 200 response is a list; each item has these fields:

Field Type
[].id integer
[].label string
[].permissions array of string or null
[].ip_whitelist array of string or null
[].is_active boolean
[].last_used_at string (date-time) or null
[].created_at string (date-time)

POST /api/v1/auth/me/api-keys

Permissions are <area>:read or <area>:write, and the allow-list holds addresses and CIDR ranges; anything else is a 422 that names it (app/services/api_key_auth.py).

Authentication: an access token, sent as Authorization: Bearer <token>.

application/json (required)

Field Type Required
label string yes
permissions array of string or null no
ip_whitelist array of string or null no
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Fields of a 200 response:

Field Type
id integer
label string
permissions array of string or null
ip_whitelist array of string or null
is_active boolean
last_used_at string (date-time) or null
created_at string (date-time)
raw_key string

DELETE /api/v1/auth/me/api-keys/{key_id}

Authentication: an access token, sent as Authorization: Bearer <token>.

Name In Type Required
key_id path integer yes
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

POST /api/v1/auth/me/password

Change the password. Every other session is signed out, and this device gets a new token pair in the answer, since the change makes every token issued before it invalid.

Authentication: an access token, sent as Authorization: Bearer <token>.

application/json (required)

Field Type Required
current_password string yes
new_password string yes
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

GET /api/v1/auth/me/staff-link

Authentication: an access token, sent as Authorization: Bearer <token>.

Status Meaning
200 Success.

POST /api/v1/auth/me/staff-link

Authentication: an access token, sent as Authorization: Bearer <token>.

application/json (required)

Field Type Required
code string yes
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

DELETE /api/v1/auth/me/staff-link

Authentication: an access token, sent as Authorization: Bearer <token>.

Status Meaning
200 Success.

A new token pair for a refresh token, which is then used up (app/domains/auth/sessions.py)

Section titled A new token pair for a refresh token, which is then used up (app/domains/auth/sessions.py)

POST /api/v1/auth/refresh

A new token pair for a refresh token, which is then used up (app/domains/auth/sessions.py).

application/json (required)

Field Type Required
refresh_token string yes
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Fields of a 200 response:

Field Type
access_token string
refresh_token string
token_type string
expires_in integer

Create an account and sign it in

Section titled Create an account and sign it in

POST /api/v1/auth/register

Create an account and sign it in. Send exactly one of email and mailbox_local_part. With a mailbox, the address is the local part on the storefront's sign-up domain, and the account and its mailbox are made together.

One network, an IPv4 address or an IPv6 /64, can make 3 mailboxes an hour and 5 a day, counting the ones claimed later in webmail; past that the answer is 429. A network an address rule blocks, a hosting, VPN, proxy or Tor network when the platform refuses those, and a network whose earlier mailbox was paused in the last 7 days get 403 with the reason. A taken address is 409, a name that cannot be used 422, a storefront that offers no mailbox 404, and a mail service that cannot take a new mailbox right now 503.

application/json (required)

Field Type Required
email string (email) or null no
mailbox_local_part string or null no
recovery_email string (email) or null no
password string yes
first_name string or null no
last_name string or null no
company string or null no
turnstile_token string or null no
referral_code string or null no
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Fields of a 200 response:

Field Type
access_token string
refresh_token string
token_type string
expires_in integer

POST /api/v1/auth/reset-password

application/json (required)

Field Type Required
token string yes
new_password string yes
turnstile_token string or null no
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Where this account is signed in, newest activity first

Section titled Where this account is signed in, newest activity first

GET /api/v1/auth/sessions

Where this account is signed in, newest activity first.

current marks the session this request came from. country_code is where the address places, or null when nothing can place it. A device signed in before sessions were recorded appears after its next refresh. support_session is true for a session Coritan support opened as the account, which lasts 30 minutes; support_mode is then read_only or full, and its address and device are the support agent's.

Authentication: an access token, sent as Authorization: Bearer <token>.

Status Meaning
200 Success.

Sign out everywhere except this device

Section titled Sign out everywhere except this device

POST /api/v1/auth/sessions/revoke-others

Sign out everywhere except this device.

A device whose token predates sessions has no row to keep, so it gets a new session and its token pair in the answer; the dashboard stores it.

Authentication: an access token, sent as Authorization: Bearer <token>.

Status Meaning
200 Success.

DELETE /api/v1/auth/sessions/{session_id}

Sign out one device. Signing out this device's own session works too; the dashboard then clears its tokens.

Authentication: an access token, sent as Authorization: Bearer <token>.

Name In Type Required
session_id path integer yes
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

GET /api/v1/auth/turnstile

Public: whether the platform's auth and order forms must render a check, and with which site key (no auth).

enabled and site_key are all a page on Cloudflare Turnstile gets. While wicket.platform_forms is on the answer also carries provider (wicket) and script_url (the Wicket loader, already set to explicit rendering): the page loads that script and draws the widget with the same render, reset and remove calls from window.wicket. The token it hands back goes in turnstile_token on the form's request, whichever provider made it.

Status Meaning
200 Success.