Trader vs operator credentials
Two very different integrations use this API, and they need different credentials:
- a trader — a person or bot acting on their own account: placing orders, reading their positions, streaming their fills;
- an operator (partner / tenant) — a business acting on its tenant: creating traders, prop firms, challenge templates, risk profiles and trading groups, approving payouts.
A credential is minted for exactly one of these. The audience is fixed at mint and never changes, and one credential can never be both.
What each can do
Section titled “What each can do”| Trader credential | Operator credential | |
|---|---|---|
| Acts on | Its own account | Your tenant |
| Minted from | The account, in the browser — Settings → API Clients | The admin console — API Clients |
| Carries | A tier (readonly / fullTrading), a risk envelope, venue + symbol allowlists, and an agent wallet |
Scopes: prop:manage, firm:operate, tenant:config, accounts:intervene |
| Can place orders | Yes | No — never |
| Can administer a tenant | No — scopes are rejected at mint | Yes, and only its own tenant |
Why an operator can’t trade
Section titled “Why an operator can’t trade”Not a missing feature, and not something to work around. Authority over an account comes from that account, never from a credential: a trader credential can place orders because the account’s own wallet signed an agent authorization for it, in the browser, where the wallet is. An operator has no access to that wallet and cannot forge that signature — the constraint is cryptographic.
So an operator credential holds no agent wallet by design. Presenting one on the
trading surface returns 403 wrong_credential_audience.
In the SDK
Section titled “In the SDK”Use the client that matches your credential. Calling the other surface then fails at compile time instead of at runtime.
import { TronChartsTrader, TronChartsOperator } from '@tronchartsxyz/api-client'
// Acting on your own accountconst trader = new TronChartsTrader({ baseUrl, token: traderToken, tenantSlug })await trader.oms.place({ /* … */ })await trader.accounts.state(accountId)
// Administering your tenantconst ops = new TronChartsOperator({ baseUrl, token: operatorToken, tenantSlug })const { user } = await ops.users.create({ externalId: 'crm-4471' })await ops.propTemplates.create({ /* … */ })| Client | Resources |
|---|---|
TronChartsTrader |
oms · accounts · propAccounts · market · reports · sor · venues · kyc · referrals · analytics · indicators · backtests · copyTrading |
TronChartsOperator |
users · firms · propTemplates · riskProfiles · tradingGroups · tenant · sandbox · propAccounts (read-only oversight) · reports · analytics |
TronCharts still exposes both surfaces on one object. It works, and it tells
you nothing about which half your token can reach — prefer the scoped clients.
When you get it wrong
Section titled “When you get it wrong”{ "error": "wrong_credential_audience", "detail": "this endpoint is for operator credentials, but this is a trader credential. …", "expected": "operator", "actual": "trader"}HTTP 403. The fix is never to change the credential you have — audiences are
immutable — but to mint the other one and keep both.
You may still meet the older, less direct errors underneath this gate:
| Error | What it actually means |
|---|---|
wrong_credential_audience |
Wrong kind of credential. Mint the other one. |
credential_missing_agent_wallet |
A trader credential minted without an agent wallet. Re-mint it from the account it should trade. |
tier_insufficient |
A trader credential whose tier is too low — readonly cannot open positions. |
forbidden on an operator route |
Right audience, missing that specific scope. An operator grants scopes per credential. |
Browser sessions
Section titled “Browser sessions”A cookie session (your own logged-in user in the FE) carries no credential and no audience, so this gate does not apply to it. Each route handles it on its own terms: the operator surface refuses it outright — tenant administration is an explicit, audited credential capability — while the trading surface accepts it as the trader it represents.
Next: Credentials & tokens · Scopes & tiers · How an account is configured