Flashpoint.AIFlashpoint.AIdocs

Authentication

Flashpoint.AI has no API keys. Every request carries a short-lived bearer JWT, and the JWT shape depends on which surface you're calling and who you are.

SurfaceCallerAuth mechanism
Chat UI (app.flashpoint.ai)A human researcherAuth0 OAuth → Flashpoint.AI RS256 JWT
MCP server (mcp.flashpoint.ai)A human via Claude Desktop / Cursor / etc.OAuth 2.1 redirect to Auth0 → mcp-issued user JWT
MCP server (mcp.flashpoint.ai)An autonomous agentWallet JWT — EIP-191 signature on a nonce

All bearers go in a standard Authorization header:

Authorization: Bearer <token>

No cookies, no signed requests, no session state on the server.

Chat UI (humans via Auth0)

The chat UI signs you in through Auth0. The browser handles the redirect dance; you don't write code for this. Auth0 issues an id_token which io exchanges for a Flashpoint.AI user JWT — RS256, 180-day expiry, payload {id, kind: "user", expires}. The JWT goes into localStorage and rides on every WebSocket and REST call from the UI.

You won't typically interact with this token directly. If you're building a custom integration that needs to act as a Flashpoint.AI user (rather than an autonomous agent), use MCP via Claude Desktop instead — it's faster to set up and gives you the same identity binding.

MCP humans (OAuth 2.1 via Claude Desktop)

Claude Desktop and other MCP clients discover and complete a standard OAuth 2.1 flow against the Flashpoint.AI MCP server.

The flow

  1. Client calls POST /mcp with no bearer → server returns 401 + a WWW-Authenticate: Bearer resource_metadata=… header.
  2. Client fetches the RFC 9728 protected-resource metadata at /.well-known/oauth-protected-resource and the RFC 8414 authorization-server metadata at /.well-known/oauth-authorization-server.
  3. Client posts a Dynamic Client Registration (RFC 7591) request to /oauth/register, gets back a client_id.
  4. Client opens the browser to /oauth/authorize?…&code_challenge=…&code_challenge_method=S256 with its registered redirect URI (loopback for CLI clients like Claude Code, a hosted https://claude.ai/… or https://chatgpt.com/… callback for Desktop / web / ChatGPT). mcp-server 302s to Auth0.
  5. You log in with Auth0 (the same account you'd use in the chat UI). Auth0 302s back to mcp-server's /oauth/callback.
  6. mcp-server renders an HTML team picker listing every team you belong to. You click one.
  7. mcp-server mints an HS256 JWT bound to (user_id, team_id) with a 24-hour expiry, 302s back to the client's loopback callback with a single-use authorization code.
  8. Client posts /oauth/token with the code + the PKCE verifier; gets back the JWT as access_token.

After that, the client uses the JWT on every /mcp request. To switch teams, re-run the connection — the picker shows again.

What you do

Per-client setup instructions (Claude Desktop, Claude.ai web, Claude Code CLI, ChatGPT custom connector) live in Connect from your AI assistant. For all of them the OAuth dance is handled automatically — you just paste the server URL and sign in. See Quickstart for the full first-call walkthrough.

Token shape

The access token is opaque from the client's perspective. For the curious:

{
  "iss": "flashpoint-mcp",
  "kind": "user",
  "user_id": "<uuid>",
  "team_id": "<uuid>",
  "iat": 1779700000,
  "exp": 1779786400
}

24-hour TTL. No refresh token — re-OAuth when it expires.

MCP wallet JWT (autonomous agents)

If you're an autonomous agent without a human in the loop, you authenticate by signing an EIP-191 message with your wallet's private key. mcp-server provisions a Flashpoint.AI user + team for your wallet on first contact (idempotent on the address).

The flow

  1. POST /auth/wallet/challenge → server returns {nonce, message_to_sign, expires_at}. The message_to_sign is namespaced (flashpoint-mcp-auth:<nonce>) so a signature for us is not reusable elsewhere.
  2. Sign the message with personal_sign (EIP-191).
  3. POST /auth/wallet/token with {address, nonce, signature} → server recovers the signer, checks it matches address, consumes the nonce, provisions users(kind='agent') + teams(kind='agent') if needed, and returns a 1-hour wallet JWT.
  4. Use the JWT on every /mcp request: Authorization: Bearer <token>.

Token shape

{
  "iss": "flashpoint-mcp",
  "kind": "wallet",
  "address": "0x…",
  "user_id": "<uuid>",
  "team_id": "<uuid>",
  "iat": 1779700000,
  "exp": 1779703600
}

1-hour TTL. Get a new nonce and re-sign when it expires.

Per-call payment (x402)

Wallet agents pay per tool call in USDC on Base. When you hit a paid tool without an X-PAYMENT header, the server returns 402 with the payment terms — payTo address, asset, amount, network — encoded for the x402 protocol. Pay through the x402 facilitator, retry with the X-PAYMENT header, and the server settles on-chain after a successful tool result.

Two important guarantees:

  • Wallet-binding. The on-chain payer address must match the wallet address in your JWT. Paying with one wallet under another wallet's bearer is rejected at the verify step (402).
  • No charge on failure. If the worker returns an error, we skip settlement — your signature is not redeemed.

Human bearers (Auth0 or OAuth) are not gated by x402 — your subscription covers per-call usage.

Errors

Every auth failure returns one of:

StatusWhen
401Bearer missing, malformed, expired, or signature invalid
403Account suspended (rare)
402Wallet agent hit a paid tool without payment (see above)

See Errors for the canonical error envelope.