Sign customers in to your storefront
Register, sign in and verify your customers, refresh their tokens, and add two-factor authentication and social sign-in.
Your customers have accounts with your organization, separate from Coritan accounts. Your storefront creates them and signs them in through /auth/..., and gets back a customer token that every /portal/... call takes as Authorization: Bearer.
Before you begin
Section titled Before you begin- Choose how your organization's email leaves under Outgoing email (SMTP) in Settings. We send your customers welcome, verification and password reset emails. See Change organization settings.
- Set your Custom domain in the same place. Emails link to pages on it, which your storefront must serve:
/verify-email?id=...&token=...,/reset-password?token=...and/billing/invoices/{invoice_id}. Social sign-in returns to/auth/callback. - If
GET /storefront/brandingreportsturnstile.enabled, show the Cloudflare Turnstile challenge on your sign-up form and send its answer with the request.
Register a customer
Section titled Register a customercurl -X POST "https://api.coritan.com/api/v1/orgs/acme/auth/register" \
-H "Content-Type: application/json" \
-d '{"email": "alex@example.com", "password": "a long passphrase", "username": "alex_builds", "first_name": "Alex", "turnstile_token": "..."}'
email and password are required, and the password needs at least 8 characters. username, first_name, last_name, company and phone are optional. Without a username we generate one. GET /auth/username-available?username=... says whether a name is free, and why not in reason, while the customer types.
A username has 3–20 letters, digits and underscores. Names that pass for staff, and names our moderation filter refuses, are not available. A customer can change theirs once every 7 days.
The answer is 201 with the customer's tokens, as for signing in. We also send your welcome email and an email to confirm the address, and your webhooks receive customer.created. Confirming the address is optional: nothing on the account waits for it.
Sign a customer in
Section titled Sign a customer incurl -X POST "https://api.coritan.com/api/v1/orgs/acme/auth/login" \
-H "Content-Type: application/json" \
-d '{"identifier": "alex@example.com", "password": "a long passphrase"}'
identifier takes an email address or a username. The answer is one of two shapes:
- A session:
access_token,refresh_token,token_typeandexpires_in. The access token lasts 24 hours and the refresh token 30 days. - A two-factor step:
mfa_tokenwithmfa_required: truewhen the customer has two-factor authentication on, ormfa_setup_required: truewhen your organization requires it and the customer has not set it up. Continue under Two-factor authentication.
Only active customers can sign in. A customer who registered with a social account has no password until they set one.
Keep the session going
Section titled Keep the session going- Before the access token expires, send
{"refresh_token": "..."}toPOST /auth/refresh. The answer is a new pair, and the old tokens stop working at once. POST /auth/logoutsigns out the session whose token it carries.GET /auth/sessionslists where the customer is signed in, with the address, country, browser and expiry of each.currentmarks the one asking, andsupport_sessionmarks a session your staff opened to look at the account.POST /auth/sessions/revoke-otherssigns out every other session and answers with how many it ended.
GET /auth/me returns the customer's profile. PATCH /auth/me changes first_name, last_name, company, phone or chat_handle (the username). To change the password, send password with current_password.
Two-factor authentication
Section titled Two-factor authenticationCustomers turn on two-factor authentication with an authenticator app. To require it of every customer, turn it on in your staff console's settings. See Manage the staff team and console settings.
POST /auth/mfa/setupreturns asecret, anotpauth_uriand aqr_svgto show.- The customer scans it and sends a code to
POST /auth/mfa/enableas{"code": "123456"}. The answer holds 10recovery_codes, shown once. When the request carried anmfa_token, it also holds the session intokens. - From then on, signing in answers with an
mfa_token. Send it as the bearer token toPOST /auth/mfa/verifywith a code from the app or a recovery code, and the answer is the session.
An mfa_token works only on the /auth/mfa routes. It lasts 5 minutes for a sign-in, and 30 minutes for setting up when your organization requires two-factor authentication.
GET /auth/mfa says whether it is on and how many recovery codes are left. POST /auth/mfa/recovery-codes replaces the codes, given a current code. POST /auth/mfa/disable turns it off, given a code and the password when the account has one. It is refused while your organization requires two-factor authentication; your staff can reset a customer's instead.
Social sign-in
Section titled Social sign-inCoritan configures the providers. GET /auth/oauth/providers lists the ones your storefront can offer, from discord, github, google and microsoft.
- Call
GET /auth/oauth/{provider}/authorizeand send the customer to theauthorization_urlit returns. - After the provider, we send the customer back to
/auth/callbackon your storefront with the result in the URL fragment:access_token,refresh_tokenandexpires_in, ormfa_tokenand its flags, orerror.new_account=truemarks a customer we just registered.
We return the customer only to a storefront address that Coritan has registered for your organization. Contact support to register yours before you offer social sign-in.
A signed-in customer can link another provider by calling authorize with their token. When a provider's email matches an existing customer, we refuse with account_exists_login_required: the customer signs in with their password, then links the provider. GET /auth/oauth/connections lists the linked providers, and DELETE /auth/oauth/connections/{provider} removes one. POST /auth/oauth/set-password gives a social-only account a password: 8–128 characters with a lowercase letter, an uppercase letter, a digit and a symbol.
Verify an address and reset a password
Section titled Verify an address and reset a password- The confirmation email links to
/verify-email?id=...&token=.... Post both values toPOST /auth/verify-emailascustomer_idandtoken. A link works for 24 hours, and only the newest one works.POST /auth/resend-verificationsends another;sent: falsewithemail_unavailablemeans your organization cannot send email. POST /auth/forgot-passwordwithemailsends a reset link to/reset-password?token=.... The answer is the same whether or not the account exists. Post the token and the newpasswordtoPOST /auth/reset-passwordwithin 2 hours. The reset signs the customer out everywhere.
Result
Section titled ResultThe customer has a session your storefront keeps in the browser and sends to every /portal/... call. The customer appears on the Customers tab.
Troubleshooting
Section titled Troubleshooting401 Invalid credentials- The identifier or the password is wrong, or the customer is not
active. 401 This account uses social login ...- The customer registered with a social account. They sign in with it, or set a password from their account.
409 Email already registeredor409 That username is already taken.- Sign the customer in instead, or choose another username.
403 This email address cannot be used to register.- Your staff banned an account with that address.
403 Customer limit reached (100/100)- Your organization holds as many customers as it may. Ask support to raise the limit.
401 Invalid refresh tokenor401 Refresh token expired- The refresh token was already used, revoked or is older than 30 days. Sign the customer in again.
401withmfa_required- The token is still waiting for the second factor. Finish with
POST /auth/mfa/verify. 403 Account is suspended or closedor403 We have closed this account.- Your staff suspended, closed or banned the customer.
400 Invalid reset tokenor400 Reset token expired- The link is wrong, was replaced by a newer one, or is more than 2 hours old. Ask for a new one.
Related
Section titled RelatedAPI operations on this page
| Method | Path | What it does |
|---|---|---|
POST | /api/v1/orgs/{org_slug}/auth/forgot-password | Issue a password-reset token stored on the customer metadata |
POST | /api/v1/orgs/{org_slug}/auth/login | Password sign-in with an email address or a username |
POST | /api/v1/orgs/{org_slug}/auth/logout | Revoke the current access token (and its refresh twin if present) |
GET | /api/v1/orgs/{org_slug}/auth/me | Customer profile |
PATCH | /api/v1/orgs/{org_slug}/auth/me | Update customer profile |
GET | /api/v1/orgs/{org_slug}/auth/mfa | Customer MFA status |
POST | /api/v1/orgs/{org_slug}/auth/mfa/disable | Turn the factor off with a current code, and with the password when the account has one |
POST | /api/v1/orgs/{org_slug}/auth/mfa/enable | Customer MFA enable |
POST | /api/v1/orgs/{org_slug}/auth/mfa/recovery-codes | Customer MFA regenerate recovery codes |
POST | /api/v1/orgs/{org_slug}/auth/mfa/setup | Customer MFA setup |
POST | /api/v1/orgs/{org_slug}/auth/mfa/verify | Customer MFA verify |
GET | /api/v1/orgs/{org_slug}/auth/oauth/connections | List OAuth connections |
DELETE | /api/v1/orgs/{org_slug}/auth/oauth/connections/{provider} | Disconnect OAuth provider |
GET | /api/v1/orgs/{org_slug}/auth/oauth/providers | Public: which social providers are configured for storefront login |
POST | /api/v1/orgs/{org_slug}/auth/oauth/set-password | OAuth set password |
GET | /api/v1/orgs/{org_slug}/auth/oauth/{provider}/authorize | OAuth authorize |
GET | /api/v1/orgs/{org_slug}/auth/oauth/{provider}/callback | OAuth callback |
POST | /api/v1/orgs/{org_slug}/auth/refresh | Customer refresh token |
POST | /api/v1/orgs/{org_slug}/auth/register | Self-service customer signup for the org storefront |
POST | /api/v1/orgs/{org_slug}/auth/resend-verification | Send another confirmation link to the signed-in customer's own address |
POST | /api/v1/orgs/{org_slug}/auth/reset-password | Customer reset password |
GET | /api/v1/orgs/{org_slug}/auth/sessions | Where this account is currently signed in |
POST | /api/v1/orgs/{org_slug}/auth/sessions/revoke-others | Sign out everywhere except here |
GET | /api/v1/orgs/{org_slug}/auth/username-available | Whether a username can be taken at signup, and why not when it cannot |
POST | /api/v1/orgs/{org_slug}/auth/verify-email | Confirm an address from an emailed link |