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

> ## Agent Instructions
> Before reading these docs, install the relevant Circle Skill to get pre-loaded context — skills are LLM-optimized and cover architecture decisions, correct flows, and common pitfalls. In Claude Code: run /plugin marketplace add circlefin/skills then /plugin install circle-skills@circle. With Vercel Skills CLI: run npx skills add circlefin/skills. Available skills: use-usdc https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-usdc/SKILL.md (balances, transfers, approvals on EVM and Solana); EURC has no skill — see https://developers.circle.com/stablecoins/what-is-eurc.md; bridge-stablecoin https://github.com/circlefin/skills/blob/master/plugins/circle/skills/bridge-stablecoin/SKILL.md (crosschain transfers via CCTP, USDC, EURC, and third-party assets); use-arc https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-arc/SKILL.md (Arc chain config, contract deployment, USDC bridging — Arc docs: https://docs.arc.io/llms.txt); use-circle-wallets https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-circle-wallets/SKILL.md (choose wallet type); use-developer-controlled-wallets https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-developer-controlled-wallets/SKILL.md (custodial wallets for payouts and treasury); use-user-controlled-wallets https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-user-controlled-wallets/SKILL.md (embedded wallets with Web2 login); use-modular-wallets https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-modular-wallets/SKILL.md (smart contract wallets with passkeys and ERC-4337); use-gateway https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-gateway/SKILL.md (unified USDC balance, nanopayments); use-smart-contract-platform https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-smart-contract-platform/SKILL.md (deploy, interact, monitor contracts). Pair any skill with the Circle MCP server for live SDK signatures, contract addresses, and chain IDs: {"mcpServers":{"circle":{"url":"https://api.circle.com/v1/codegen/mcp"}}}.
> Read the product overview first. Each product has an overview explaining when and why to use it. Read it before quickstarts.
> Pick the right wallet type. Developer-controlled (you hold keys), user-controlled (end user holds keys via PIN/social login), or modular (smart contract wallets with passkeys). See https://developers.circle.com/wallets.md.
> Use CCTP V2 for crosschain transfers. CCTP natively transfers USDC and EURC via burn-and-mint, and supports permissionless wrapping of third-party assets via lock-and-mint. V1 is legacy; always use V2 unless V1 is specified or the chain requires it (Noble, Sui, and Aptos still require V1). Migration guide: https://developers.circle.com/cctp/migration-from-v1-to-v2.md.
> Use Bridge Kit for frontend bridging. Wraps CCTP with a simpler SDK for user-facing apps. Use CCTP directly for backend transfers.
> Gas Station vs Paymaster. Gas Station sponsors gas for Circle Wallet transactions. Paymaster lets users pay gas in USDC. Different use cases — read both overviews.
> Gateway Nanopayments for sub-cent payments. Gasless USDC micropayments down to $0.000001 via x402 and batched settlement. For pay-per-request APIs, AI agent payments, streaming.
> Look up USDC addresses per chain. Never hardcode — use https://developers.circle.com/stablecoins/usdc-contract-addresses.md.
> Prefer SDKs over raw API calls. Node.js and Python SDKs handle auth, retries, and errors.
> API key required. Bearer token in Authorization header. Testnet and mainnet use separate keys and may use different base URLs depending on the product.
> Set up webhooks when available. Most operations are async. Webhooks deliver transaction confirmations and state changes.
> When calling list endpoints, paginate using pageSize and pageAfter until no nextPageAfter cursor is returned—stopping at the first page silently misses records.
> Building an AI agent? Start with the Agent Stack—Circle CLI, agent wallets, and nanopayments built for autonomous use cases: https://developers.circle.com/agent-stack.md.

# Authentication methods

> Choose the right way to authenticate users in your user-controlled wallets app.

Circle supports three ways to authenticate users when creating user-controlled
wallets: social logins, email OTP, and PIN. Each method shapes how users sign
in, how they sign transactions, and how they recover access if they lose
credentials.

This page helps you pick the right method. For implementation steps, follow the
Build a Wallet App tutorial for the method you choose.

## Method comparison

The following table compares each method on the criteria that matter most when
picking:

| Method | Best for | Onboarding | Recovery |
| - | - | - | - |
| **Social logins** | Consumer apps using familiar sign-ins | User signs in with Google, Apple, or Facebook through the provider OAuth flow. | Through the provider. Circle cannot recover lost provider credentials. |
| **Email OTP** | Apps preferring email-based verification | User enters their email. Circle sends a one-time password to verify. | Through email account access. |
| **PIN** | Apps with user-only custody of credentials | User sets a 6-digit PIN and security-question answers during sign-up. | Through security-question answers. Circle cannot recover a lost PIN. |

For key management details, see [Key management](/wallets/key-management). For
how signing UIs work across methods, see
[Confirmation UIs](/sdks/user-controlled/confirmation-uis).

### Social logins

Users sign in with Google, Facebook, or Apple. Circle handles the OAuth flow and
creates a wallet for the authenticated user.

**Use when:** You're building a consumer-facing app and want users to onboard
with accounts they already have. Best for low-friction sign-ups when crypto
familiarity isn't a prerequisite.

**Example use cases:** Consumer apps using Google or Apple sign-in, fintech
sign-ups tied to existing accounts, reward wallets attached to social
identities.

**Tradeoffs:**

* Circle cannot recover lost provider credentials or unblock accounts. Users
  must go through the provider directly. For example, recovering a banned
  Facebook account can take weeks.
* Each social account links to one unique user ID. Signing up with multiple
  providers (for example, Google then Apple) creates separate user IDs.

To offer a provider beyond Google, Apple, or Facebook, request it through
[Circle on Discord](https://discord.com/invite/buildoncircle).

<Accordion title="Example: Social login UX">
  <Frame>
    <img src="https://mintcdn.com/circle-167b8d39/Y3M1-hPSLXlEtSe1/w3s/images/ucw-am-koallasocial01.png?fit=max&auto=format&n=Y3M1-hPSLXlEtSe1&q=85&s=80215f3e82d4472db1cd7209e09935d1" width="2880" height="2048" data-path="w3s/images/ucw-am-koallasocial01.png" />
  </Frame>

  <Frame>
    <img src="https://mintcdn.com/circle-167b8d39/Y3M1-hPSLXlEtSe1/w3s/images/ucw-am-koallasocial02.png?fit=max&auto=format&n=Y3M1-hPSLXlEtSe1&q=85&s=350ce8bb75a4c1ed14cb536573c158bc" width="888" height="630" data-path="w3s/images/ucw-am-koallasocial02.png" />
  </Frame>
</Accordion>

The following diagram shows the OAuth 2.0 sequence when a user signs in:

```mermaid theme={null}
sequenceDiagram
    participant U as User
    participant App as Your app
    participant SDK as Circle Web SDK
    participant Provider as OAuth provider
    participant Circle as Circle backend

    U->>App: Tap "Sign in with [provider]"
    App->>Circle: POST /users/social/token (deviceId)
    Circle-->>App: deviceToken, deviceEncryptionKey
    App->>SDK: performLogin(deviceToken, deviceEncryptionKey)
    SDK->>Provider: Redirect for OAuth consent
    Note over U,Provider: User signs in and grants consent
    Provider-->>SDK: Authorization code (via redirect)
    SDK->>Circle: Exchange code for tokens
    Circle-->>SDK: userID, userToken, encryptionKey, refreshToken
    SDK-->>App: Tokens returned
```

Full walkthrough:
[Build a Wallet App with social login](/wallets/user-controlled/build-a-wallet-app#social-login).

### Email OTP

Users sign up with their email. Circle sends a one-time password (OTP) and
creates a wallet after verification.

**Use when:** You want a familiar email-based onboarding flow without a
third-party authentication provider. Works well when users may not have social
provider accounts or in regions where social login adoption is low.

**Example use cases:** Apps with existing email-based user accounts, B2B-style
flows, enterprise integrations.

**Tradeoffs:**

* Users need access to their email account to recover their wallet. Email
  account compromise means wallet compromise.
* Requires SMTP configuration through your own provider. Circle does not send
  the email.

<Accordion title="Example: Email OTP UX">
  <Frame>
    <img src="https://mintcdn.com/circle-167b8d39/Y3M1-hPSLXlEtSe1/w3s/images/ucw-am-koallaemail01.png?fit=max&auto=format&n=Y3M1-hPSLXlEtSe1&q=85&s=ebc057af27a12fc0bfcb226b9f727b43" width="933" height="660" data-path="w3s/images/ucw-am-koallaemail01.png" />
  </Frame>

  <Frame>
    <img src="https://mintcdn.com/circle-167b8d39/Y3M1-hPSLXlEtSe1/w3s/images/ucw-am-koallaemail02.png?fit=max&auto=format&n=Y3M1-hPSLXlEtSe1&q=85&s=55cc0098b41e0b702b57dd2fab5e05e9" width="933" height="661" data-path="w3s/images/ucw-am-koallaemail02.png" />
  </Frame>

  <Frame>
    <img src="https://mintcdn.com/circle-167b8d39/Y3M1-hPSLXlEtSe1/w3s/images/ucw-am-koallaemail03.png?fit=max&auto=format&n=Y3M1-hPSLXlEtSe1&q=85&s=20061412cf8a8e472c43a03ffe005d81" width="933" height="658" data-path="w3s/images/ucw-am-koallaemail03.png" />
  </Frame>
</Accordion>

The following diagram shows the email OTP sequence when a user signs in:

```mermaid theme={null}
sequenceDiagram
    participant U as User
    participant App as Your app
    participant SDK as Circle Web SDK
    participant SMTP as Your SMTP server
    participant Circle as Circle backend

    U->>App: Enter email address
    App->>Circle: POST /users/email/token (deviceId)
    Circle-->>App: otpToken, deviceToken, deviceEncryptionKey
    Circle->>SMTP: Send OTP email
    SMTP->>U: Deliver OTP to user's inbox
    U->>App: Enter OTP
    App->>SDK: verifyOTP(otp, deviceToken, deviceEncryptionKey)
    SDK->>Circle: Validate OTP
    Circle-->>SDK: userID, userToken, encryptionKey, refreshToken
    SDK-->>App: Tokens returned
```

Full walkthrough:
[Build a Wallet App with email OTP](/wallets/user-controlled/build-a-wallet-app#email-otp).

### PIN

Users set a 6-digit PIN to authorize transactions. Optional biometrics let users
sign with fingerprint or facial recognition on supported devices.
Security-question answers, also set during sign-up, are the recovery path if the
user forgets their PIN.

The PIN is encrypted on the user's device. After three incorrect PIN attempts,
PIN entry locks for 30 minutes. After three incorrect security-question answers
during recovery, recovery locks for 30 minutes.

**Use when:** You want user-side custody. Only the user holds the PIN, and
Circle has no way to recover it. Best for crypto-native users comfortable
managing their own credentials.

**Example use cases:** Self-custody-focused consumer apps, crypto-native
communities, apps emphasizing user sovereignty.

**Tradeoffs:**

* Lost PIN combined with forgotten security answers means permanent loss of
  access. Users are responsible for remembering both.
* Higher friction than social logins or email OTP at sign-up.
* No third-party dependencies, no provider account to lose.

<Accordion title="Example: Biometrics UX">
  <Frame>
    <img src="https://mintcdn.com/circle-167b8d39/Y3M1-hPSLXlEtSe1/w3s/images/ucw-am-examplebio01.png?fit=max&auto=format&n=Y3M1-hPSLXlEtSe1&q=85&s=896e389b708605dcda648fc2257841f9" width="903" height="590" data-path="w3s/images/ucw-am-examplebio01.png" />
  </Frame>
</Accordion>

<Accordion title="Example: PIN and security question setup">
  <Frame>
    <img src="https://mintcdn.com/circle-167b8d39/Y3M1-hPSLXlEtSe1/w3s/images/ucw-am-examplepinrec01.png?fit=max&auto=format&n=Y3M1-hPSLXlEtSe1&q=85&s=4e6ef754251cd034f4a87bb0994a582d" width="904" height="590" data-path="w3s/images/ucw-am-examplepinrec01.png" />
  </Frame>
</Accordion>

Full walkthrough:
[Build a Wallet App with PIN](/wallets/user-controlled/build-a-wallet-app#pin).
To restore access after a lost PIN:
[Recover an account](/wallets/user-controlled/recover-account).

## Session lifecycle

After a user authenticates with social logins or email OTP, Circle returns a
`userToken` and a `refreshToken`. PIN users don't receive session tokens. Their
PIN authorizes each action directly.

* The `userToken` is the session identifier. It expires 14 days after
  generation, after which users are logged out.
* The `refreshToken` extends the session. Before the `userToken` expires, send a
  `POST` request to
  [`/users/token/refresh`](/api-reference/wallets/user-controlled-wallets/refresh-user-token)
  with the existing user token and its refresh token. The response returns a new
  user token.

If a `userToken` expires before being refreshed, the user is logged out and must
authenticate again to receive new tokens.
