> ## Documentation Index
> Fetch the complete documentation index at: https://docs.guile.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication overview

> Sign someone in with OTP or a passkey, then keep their tokens fresh

Use the Authentication API to prove who is calling. You challenge with a
one-time passcode (email or SMS) or a passkey, then you get JWT access and
refresh tokens for protected calls.

```mermaid theme={null}
sequenceDiagram
 participant User
 participant Client
 participant API
 participant Authenticator

 User->>Client: Sign in
 alt Prefer passkey
 Client->>API: Create challenge (method: passkey)
 API->>Client: WebAuthn options
 Client->>Authenticator: Request assertion
 Authenticator-->>Client: Assertion or failure
 alt Assertion ok
 Client->>API: Verify authentication
 API->>Client: Access and refresh tokens
 else Passkey fails
 Client->>API: Create challenge (method: otp)
 API->>User: Send OTP
 User->>Client: Enter code
 Client->>API: Verify authentication
 API->>Client: Access and refresh tokens
 end
 else OTP path
 Client->>API: Create challenge (method: otp)
 API->>User: Send OTP
 User->>Client: Enter code
 Client->>API: Verify authentication
 API->>Client: Access and refresh tokens
 end
```

## What you do first

1. Pick a method: passkey when the person already registered one; OTP when they
   have no passkey, biometrics fail, or you need a fallback.
2. [Create an authentication challenge](/api-reference/challenges/create-an-authentication-challenge)
   with `method` set to `otp` or `passkey`.
3. [Verify authentication](/api-reference/challenges/verify-authentication) with
   the OTP code or passkey assertion.
4. Put the access token in the `Authorization` header. When it expires,
   [exchange the refresh token](/api-reference/token-management/exchange-an-offline-refresh-token).

For a first-time customer, issue a phone OTP before they have a Guile account,
[verify customer registration](/api-reference/registration/verify-customer-registration),
then
[complete customer registration](/api-reference/registration/complete-customer-registration)
with profile fields. Returning users still get tokens from verify authentication.

For calls that do not need a signed-in person,
[issue an anonymous token](/api-reference/token-management/issue-an-anonymous-token).

After a barber signs in, call
[get authenticated session context](/api-reference/token-management/get-authenticated-session-context)
for the barber and business ids. Do not decode token claims for those ids.

## States that matter

| Token or challenge   | Lifetime       | What happens next                                                                           |
| -------------------- | -------------- | ------------------------------------------------------------------------------------------- |
| Access token         | 15 minutes     | Authorize API calls; refresh when it expires                                                |
| Refresh token        | 4 weeks        | Exchange for a new access and refresh pair                                                  |
| OTP challenge        | 5 minutes      | Verify with the code before it expires                                                      |
| OTP resend wait      | 30-300 seconds | Cooldown grows with each send (30s, then 60s, 120s, 300s); registration challenges wait 60s |
| Registration session | 10 minutes     | Complete registration before the session expires                                            |

If the refresh token is invalid or expired, you get
[Invalid Refresh Token](/problems/invalidRefreshToken) and must run the challenge
flow again.

## When a call fails

Failures come back as problem documents. Open the `type` link for the cause, the
fix, and whether retrying is safe.

Common ones on this path:

* [Challenge Expired](/problems/challengeExpired): create a new challenge
* [Invalid Refresh Token](/problems/invalidRefreshToken): sign in again
* [Invalid Passkey Assertion](/problems/invalidPasskeyAssertion): fall back to OTP
* [Registration Session Consumed](/problems/registrationSessionConsumed): replay the identical complete call, or start a new session for a new account
* [Too Many Requests](/problems/tooManyRequests): wait for the rate limit

## Related paths

* [Passkeys](/api-reference/Authentication/passkeys): register and manage WebAuthn credentials
* [Idempotency keys](/api-reference/idempotency): registration and other writes that accept a key
* [Problem types](/api-reference/problems): how to read a failure
