Authentication
The credentials TRUE issues: wallet session, true_sk MCP key, OAuth 2.1 for multi-user AI products, tbk_ bot key for exchange-style trading, apikey_ venue key.
Five credentials, five jobs
TRUE issues five kinds of credential. They are not interchangeable, and the fastest way to lose a day is to send the wrong one.
| Credential | Looks like | For |
|---|---|---|
| Wallet session | a JWT, issued by Dynamic | An end user signed into the TRUE app on web or mobile |
| MCP key | true_sk_… | Your own backend, or one AI client acting as you |
| OAuth 2.1 grant | an access token | A product that serves many TRUE users, each acting as themselves |
| Bot key | tbk_… id plus a tbs_… secret | Hummingbot, ccxt, Freqtrade or your own bot, HMAC-signed calls to app.truefinance.ai/api/bot/v1 |
| Venue key | apikey_… | Orders you sign yourself with an Ed25519 key, against the sequencer directly |
The bot key and the venue key live in their own section: see Bot API and 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
expiresInDaysat 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"}'
IP allowlists
A bot key carries an allowlist you set yourself when you create it (IP addresses or CIDR ranges, in the Bots tab). A request from outside the list is refused with 403 ip_not_allowed even when the signature is correct, which is what makes a leaked key useless to whoever leaked it. For an MCP key, an allowlist and a higher rate tier are set by TRUE on request, with the addresses you will call from.
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 | Endpoint | URL |
|---|---|
| Authorization | https://app.truefinance.ai/oauth/authorize |
| Token | https://app.truefinance.ai/oauth/token |
| Dynamic client registration | https://app.truefinance.ai/oauth/register |
| Revocation | https://app.truefinance.ai/oauth/revoke |
| User info | https://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.
| Scope | Allows |
|---|---|
read:chat | Read the user’s TRUE chat context |
read:points | Read their points balance and history |
read:market | Market data, prices, asset search |
trade:execute | Propose an order. Nothing executes on this scope alone. |
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>
- 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 on every bot key. 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:executecannot 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.
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.
- Bot key: a bot trading through the Bot API with an exchange-style key and secret. Own page.
- Venue key: a bot placing orders it signs itself on the DEX sequencer. 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 venue key where an MCP key belongs, or the reverse. The prefixes are
true_sk_,tbk_andapikey_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 error names the address we saw. - 429. Read
RateLimit-RemainingandRetry-Afterrather 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.
- Bot API: the
tbk_key for exchange-style bots. - Trading keys: the separate
apikey_credential for the DEX. - Rate Limits: tiers, allowlists and the headers.