Authentication

The three ways to authenticate against TRUE: a wallet session for end users, a true_sk MCP key for your own backend, and OAuth 2.1 for multi-user AI clients.

Three credentials, three jobs

TRUE issues three kinds of credential. They are not interchangeable, and the fastest way to lose a day is to send the wrong one.

CredentialLooks likeFor
Wallet sessiona JWT, issued by DynamicAn end user signed into the TRUE app on web or mobile
MCP keytrue_sk_…Your own backend, or one AI client acting as you
OAuth 2.1 grantan access tokenA product that serves many TRUE users, each acting as themselves
Trade keyapikey_…Programmatic trading against the TRUE DEX sequencer

The trade key is a different animal and lives in its own section: see Keys and Access. Everything below covers the first three.

Wallet session (Dynamic)

End users sign in with email, a social login, or by signing a message with a Solana wallet. Dynamic verifies it and issues a JWT bound to the user. TRUE is non-custodial: that session lets the app read your account and ask you to sign, it does not let TRUE move your funds.

Present it as Authorization: Bearer <jwt>. Wallet sessions are for the app, not for server-to-server integrations, because they expire on a user-facing cadence and are refreshed by the client SDK.

MCP keys

A TRUE user mints an MCP key from MCP & API → Setup in the app. It is a single secret that identifies both you and your TRUE account.

POST https://app.truefinance.ai/api/v1/mcp/keys
GET https://app.truefinance.ai/api/v1/mcp/keys
DELETE https://app.truefinance.ai/api/v1/mcp/keys/{id}
GET https://app.truefinance.ai/api/v1/mcp/keys/validate
  • Prefix: true_sk_ followed by 64 hex characters.
  • Shown once. TRUE stores a SHA-256 hash and a short preview. Nobody at TRUE can read your key back to you, including support.
  • Expiry: 90 days by default, 365 maximum. Pass expiresInDays at creation.
  • Revocation is immediate: delete the key and the next request fails.

Send it as a bearer token against the MCP endpoint:

curl https://app.truefinance.ai/api/v1/mcp \
  -H "Authorization: Bearer true_sk_..." \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Per-key IP allowlist

Every key can be pinned to a set of IP addresses or CIDR ranges. A key used from outside its allowlist is refused regardless of whether the secret is correct, which is what makes a leaked key useless to whoever leaked it. Set it in the app next to the key; changes are confirmed by an emailed code. Tiers, limits and the headers we return are on Rate Limits.

OAuth 2.1

Use OAuth when your product serves many TRUE users and each tool call should run as that user, inheriting their account rather than yours. The server publishes standard metadata, so most clients configure themselves from the discovery document alone.

GET https://app.truefinance.ai/.well-known/oauth-authorization-server
EndpointURL
Authorizationhttps://app.truefinance.ai/oauth/authorize
Tokenhttps://app.truefinance.ai/oauth/token
Dynamic client registrationhttps://app.truefinance.ai/oauth/register
Revocationhttps://app.truefinance.ai/oauth/revoke
User infohttps://app.truefinance.ai/oauth/userinfo

These live at the site root, not under /api. A request to /api/v1/oauth/authorize will 404.

Scopes

Four scopes, and the app shows the user exactly which ones an app is asking for before they approve.

ScopeAllows
read:chatRead the user’s TRUE chat context
read:pointsRead their points balance and history
read:marketMarket data, prices, asset search
trade:executePropose an order. Nothing executes on this scope alone.
trade:execute does not execute

A client holding trade:execute can stage an order and nothing more. Every trade is approved by the user inside an authenticated TRUE session, and leveraged orders never auto-approve. The scope buys an assistant the right to ask, not the right to act.

Flow

Authorization code with PKCE. S256 is the only challenge method, code the only response type, and refresh tokens are supported. Public clients register with none for token endpoint auth; confidential clients may use client_secret_post or client_secret_basic.

https://app.truefinance.ai/oauth/authorize
  ?response_type=code
  &client_id=<your client id>
  &redirect_uri=https%3A%2F%2Fexample.com%2Fcallback
  &code_challenge=<S256 challenge>
  &code_challenge_method=S256
  &scope=read:market%20read:points
  &state=<opaque>
Key handling rules
  • Never commit a key to a repo, private ones included, and never ship one in a client-side bundle. Proxy through your own backend.
  • Pin an IP allowlist. It is the only control that still protects you after the secret has leaked.
  • Ask for the narrowest scope that works. A grant without trade:execute cannot stage a trade even if it is stolen.
  • On compromise, revoke first, then rotate your consumers. Revocation is instant and does not wait for the key to expire.
  • TRUE never asks for raw key material. Any “verify your key” link asking you to paste one is a phishing attempt.
For Developers

Which one do I want

  • Wallet session — you are rendering the TRUE app or an embed and the user holds the wallet.
  • MCP key — your backend, or your own Claude/Cursor setup, talking to TRUE as you.
  • OAuth — your product talking to TRUE on behalf of each of its own users.
  • Trade key — a bot placing signed orders on the DEX. Different credential, different host, own page.

Validating a key without making a tool call

curl https://app.truefinance.ai/api/v1/mcp/keys/validate \
  -H "Authorization: Bearer true_sk_..."

Returns the key’s owner and state. Useful as a health check in your deploy pipeline, so a rotated key fails at deploy time rather than at 3am.

Failure modes worth knowing

  • 401 with a JWT-shaped error on a key you just made. You sent a trade key where an MCP key belongs, or the reverse. The prefixes are true_sk_ and apikey_ and they route to different services.
  • 403 ip_not_allowed. The key has an allowlist and your egress address is not in it. Mobile networks and VPNs change address; the app shows the address we see for you.
  • 429. Read RateLimit-Remaining and Retry-After rather than retrying blind. See Rate Limits.
  • 404 on an OAuth endpoint. You prefixed it with /api. They live at the root.

See also

  • MCP — what these credentials unlock.
  • Trading keys — the separate apikey_ credential for the DEX.
  • Rate Limits — tiers, allowlists and the headers.
Last updated: