Skip to content

Quickstart

Three calls, start to finish. You need a credential — { apiKey, apiSecret } — from self-serve signup or your admin console, and your tenant slug.

Terminal window
curl -s https://api.troncharts.xyz/api/auth/api-token \
-H 'content-type: application/json' \
-d '{"apiKey":"'"$TC_API_KEY"'","apiSecret":"'"$TC_API_SECRET"'"}'
# → { "token": "eyJ…", "tier": "fullTrading", "expiresAt": <epoch ms>, … }

The token is a 24-hour JWT. Send it as Authorization: Bearer <token> on every call below. Revoke early with POST /api/auth/api-token/revoke ({ token }).

The mint endpoint is one of the few that resolves without a tenant. Every /api/v1/* call below must also say which tenant it is for: send X-Tenant-Slug: <your-slug>, or call from an origin registered on your tenant. Miss it and you get 404 {"error":"unknown_tenant_origin"} — a 404 here means “no tenant”, not “no such endpoint”. See Tenancy.

Terminal window
curl -s https://api.troncharts.xyz/api/v1/accounts/$ACCOUNT_ID/state \
-H "authorization: Bearer $TOKEN" \
-H "x-tenant-slug: $TC_TENANT_SLUG"
# → { accountId, accountNumber,
# perVenue: [ { venue, exchange, equityUsd, balanceUsd, marginUsedUsd,
# marginAvailableUsd, unrealizedPnlUsd, … } ] }

There are no top-level balance or equity fields: every figure is per venue, USD-denominated, and returned as a decimal string. The account total is the sum across perVenue.

Everything readable about an account — positions, orders, trades, fills, funding — hangs off the same /api/v1/accounts/{accountId}/* prefix. See Accounts & positions.

Requires a fullTrading credential tier.

Terminal window
curl -s https://api.troncharts.xyz/api/v1/oms/intents \
-H "authorization: Bearer $TOKEN" \
-H "x-tenant-slug: $TC_TENANT_SLUG" \
-H 'content-type: application/json' \
-H "idempotency-key: $(uuidgen)" \
-d '{
"venue": "hyperliquid",
"symbol": "BTC.HL",
"side": "buy",
"type": "limit",
"qty": "0.01",
"price": "60000"
}'
# → { "intentId": "…", … }

One endpoint covers market / limit / stop / stop_limit / take_profit across every venue. An order is an intent the platform composes, signs, and dispatches; the venue-side order id and the fills arrive over /ws/risk rather than by polling.

accountId is optional — omit it and the credential’s active account is used. Always send an idempotency-key on OMS writes — /api/v1/oms/* is the surface that honours it; see Conventions.

The client is constructed with a token — there is no anonymous client, so mint the token first with a plain fetch. Pass tenantSlug and the SDK sends X-Tenant-Slug on every request for you.

import { TronCharts } from '@tronchartsxyz/api-client'
const res = await fetch('https://api.troncharts.xyz/api/auth/api-token', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ apiKey, apiSecret }),
})
const { token } = (await res.json()) as { token: string }
const sdk = new TronCharts({
baseUrl: 'https://api.troncharts.xyz',
token,
tenantSlug: 'your-slug',
})
const state = await sdk.accounts.state(accountId)
const { intentId } = await sdk.oms.composeIntent({
venue: 'hyperliquid',
symbol: 'BTC.HL',
side: 'buy',
type: 'limit',
qty: '0.01',
price: '60000',
})