API Reference
The HTTP interface behind the terminal: market data, technical signals, backtests, the evidence gate, and the automation engine. Everything returns JSON.
OPENAPI 3.1 DOCUMENT PRODUCT GUIDEAUTHENTICATION
There is no API key. Authentication is the same session cookie the
website uses: POST /api/auth/login with your email and
password, keep the nusa_sess cookie, and send it back on
every later call.
That means a script authenticates exactly as a browser does. It also means there is no credential you can hand to a third party without handing over the account, which is why no such credential exists yet rather than one being improvised.
curl -c jar.txt -X POST https://www.nusaterminal.com/api/auth/login \
-H 'Content-Type: application/json' \
-d '{"email":"you@example.com","password":"…"}'
curl -b jar.txt 'https://www.nusaterminal.com/api/signal?symbol=BTCUSDT&range=4h'
Endpoints marked public need nothing.
signed in needs any account.
Pro plan refuses a trial with HTTP 403
and an upgrade field.
BEFORE YOU BUILD ON THIS
Signals are a calculation over technical rules. They are not
forecasts and not investment advice, and the responses say so in a
disclaimer field that is there to be read, not stripped.
Every performance figure the API returns is simulated unless the field name says otherwise. Backtest results carry the cost model that produced them; two results computed under different cost models are not comparable, and neither are results from different markets.
Rate limiting applies per address. A 429 means slow down, not stop.
Service
/api/healthpublicLiveness. Poll this from a watchdog.
Tiny and unauthenticated on purpose: a watchdog that needs a credential stops working the day the credential expires.
Response
{
"ok": true,
"uptime_s": 37821,
"started": 1788913578
}/api/marketspublicThe five markets and everything that differs between them.
Labels, size units, cost model, leverage limits, whether the market can be shorted, and the direction words it uses (futures LONG/SHORT, everything else BUY/SELL).
Response
{
"ok": true,
"markets": {
"futures": {
"label": "FUTURES",
"side_labels": {
"long": "LONG",
"short": "SHORT"
}
}
}
}/api/strategiespublicThe ten strategies, with what each suits and fails at.
Response
{
"strategies": [
{
"id": "confluence",
"name": "Confluence, 5 rules"
}
]
}/api/strategypublicThe full rule specification for one strategy.
| PARAMETER | MEANING | EXAMPLE |
|---|---|---|
| id | strategy id, e.g. macd_momentum | confluence |
| market | market the rules are described for | spot |
Market data
/api/public/tapepublicThe ticker strip used by the landing page.
Response
{
"rows": [
{
"symbol": "BTCUSDT",
"price": 79120.0,
"pct": -0.55
}
]
}/api/boardsigned inA whole board of prices at once.
| PARAMETER | MEANING | EXAMPLE |
|---|---|---|
| group | WORLD, CRYPTO, IDX, US, FX | WORLD |
/api/quotesigned inCandles and the current quote for one symbol.
Ranges 15m to 5y. The 1s range is crypto only, and several ranges are Pro; a trial gets 403 with an `upgrade` field.
| PARAMETER | MEANING | EXAMPLE |
|---|---|---|
| symbol | e.g. BTCUSDT, BBCA.JK, EUR_USD | BTCUSDT |
| range | 1s 15m 1h 4h 1d 5d 1mo 3mo 6mo 1y 5y | 1d |
/api/depthPro planOrder book depth. Crypto only.
| PARAMETER | MEANING | EXAMPLE |
|---|---|---|
| symbol | a Binance spot pair | BTCUSDT |
/api/moverssigned inBiggest 24-hour movers on Binance.
/api/searchsigned inFind a symbol by name.
| PARAMETER | MEANING | EXAMPLE |
|---|---|---|
| q | free text, e.g. telkom | telkom |
/api/newssigned inHeadlines for a symbol, or the general feed.
| PARAMETER | MEANING | EXAMPLE |
|---|---|---|
| symbol | optional; omit for general market news |
/api/overnightPro planOvernight Radar: how the reference markets moved since the Jakarta close, weighted into one bias figure.
The weights are hand-chosen, not fitted. The figure is indicative and the response says so.
Signals
/api/signalsigned inThe technical signal for one symbol, with the rules that fired and the levels derived from ATR.
A trial sees the signal and the rule breakdown but not the entry, stop and target levels. This is a calculation over rules, not a forecast, and it has not been backtested by itself - the response carries that disclaimer.
| PARAMETER | MEANING | EXAMPLE |
|---|---|---|
| symbol | instrument | BTCUSDT |
| range | chart horizon | 4h |
| market | optional; overrides the guess made from the symbol, which matters because the direction words differ per market | futures |
Response
{
"ok": true,
"side": "long",
"label": "LONG",
"score": 4,
"levels": {
"entry": 79120,
"stop": 77900,
"tp1": 80340
}
}/api/scansigned inScan a whole board and return only what passes the threshold.
| PARAMETER | MEANING | EXAMPLE |
|---|---|---|
| group | board to scan | CRYPTO |
| range | chart horizon | 4h |
Backtests
/api/backtestPro planReplay the rules bar by bar over one symbol.
Signals are computed from bars 0..i and the position opens at the OPEN of bar i+1, so nothing acts on a price it could not have known. A bar that touches both stop and target counts as a stop.
| PARAMETER | MEANING | EXAMPLE |
|---|---|---|
| symbol | instrument | BTCUSDT |
| range | how far back | 1y |
/api/backtest/boardPro planThe same, across a whole board.
| PARAMETER | MEANING | EXAMPLE |
|---|---|---|
| group | board | IDX |
| range | how far back | 1y |
/api/backtest/submitsigned inSubmit a result computed on the customer's own machine.
Backtests run on the customer's computer; only the result comes here. Plan limits are enforced on this endpoint, so a result outside the plan is refused after it was computed.
Request body
{
"email": "you@example.com",
"key": "NUSA-XXXX-XXXX-XXXX-XXXX",
"result": {
"symbol": "BTCUSDT",
"trades": 262,
"avg_r": -0.151
}
}/api/backtest/uploadsigned inUpload a JSON file of results saved offline.
Request body
{
"results": [
{
"symbol": "BTCUSDT",
"trades": 262
}
]
}/api/backtest/historysigned inStored results. Add ?id= for one result in full.
| PARAMETER | MEANING | EXAMPLE |
|---|---|---|
| id | optional result id |
/api/backtest/suggestsigned inSymbols worth testing next, from your own history.
/api/evidencePro planWhat your stored backtests support, per market.
Deduplicated, never pooled across markets, and corrected for selection: a strategy is only 'supported' if it beats the plain EMA baseline by a margin. This is what the automation engine consults before it will arm.
| PARAMETER | MEANING | EXAMPLE |
|---|---|---|
| market | spot futures forex stock idx | futures |
Automation
/api/auto/statusPro planEverything about one market's automation account.
Capital, risk, symbols, strategy, venue, open positions, the recent log, the evidence verdict, and whether the broker keys are stored and unlocked. Each market is a separate account.
| PARAMETER | MEANING | EXAMPLE |
|---|---|---|
| market | which market | futures |
/api/autoPro planEvery automation action, chosen by the `act` field.
act: config, arm, venue, keys, unlock, forget, close, kill, plan, apply_plan, balance, sync_capital, add, remove. `arm` refuses when your own backtests show the chosen strategy losing in that market - that refusal is the point of the feature, not a fault.
Request body
{
"act": "arm",
"market": "futures",
"on": true
}/api/analyzePro planAn AI explanation of a signal or of a market's evidence.
The model is given figures this server already computed and asked to explain them. It is never asked what the market will do, and it cannot see prices. You choose a subject; you cannot send a prompt.
| PARAMETER | MEANING | EXAMPLE |
|---|---|---|
| subject | signal or evidence | evidence |
| market | for subject=evidence | futures |
| symbol | for subject=signal | BTCUSDT |
| range | for subject=signal | 4h |
Account
/api/auth/registerpublicCreate an account. Starts on the trial plan.
Request body
{
"email": "you@example.com",
"password": "at least 8 characters",
"name": "Your Name"
}/api/auth/loginpublicSign in. Sets the session cookie every other call needs.
Request body
{
"email": "you@example.com",
"password": "\u2026"
}/api/auth/logoutpublicEnd the session.
Public because clearing a cookie that is not there is harmless, and refusing it would only make a signed-out client handle an error it cannot act on.
/api/auth/reset/requestpublicAsk for a password reset link.
The reply is identical whether or not the address is registered - telling the difference would let anyone test for customer addresses.
Request body
{
"email": "you@example.com"
}/api/auth/reset/confirmpublicSet a new password with the emailed token.
Changing the password deletes the stored broker API keys: they are encrypted under the old one and cannot be reopened.
Request body
{
"token": "\u2026",
"password": "\u2026"
}/api/profilesigned inAccount, plan, and trading performance per venue.
/api/entitlements/mesigned inWhat this plan allows: quotas, markets, strategies.
/api/license/statuspublicLicence state for this session or device.
/api/teamPro planTeam members who receive backtest results by email.
Request body
{
"act": "add",
"email": "colleague@example.com"
}Billing
/api/payment/offerpublicPlans for sale, the networks accepted, and your invoices.
Public: the plan catalogue and the receiving wallet address are already on the pricing page, and a wallet nobody can read is a wallet nobody can pay. The `invoices` array is scoped to the session, so an anonymous caller gets an empty one - your invoices are never visible to anyone else.
Response
{
"ok": true,
"plans": [
{
"id": "pro1y",
"usd": 3000
}
],
"networks": [
{
"id": "tron",
"label": "TRON (TRC20)"
}
],
"invoices": []
}/api/payment/startsigned inCreate an invoice: an address and an amount.
Request body
{
"plan": "pro1y",
"network": "tron"
}/api/payment/claimsigned inSubmit the transaction id. Verified on-chain, then the plan activates.
The transaction is checked against the address the invoice named, not the address currently configured - so changing the receiving wallet never invalidates an invoice already issued.
Request body
{
"id": 4,
"txid": "\u2026"
}