algoth.ink

Docs — Automation

The AlgoThink API

AlgoThink's REST API: authenticate with a bearer key, read suggestions/positions/trades, and optionally approve or close through the same checks as the dashboard.

The AlgoThink API lets your own bot or script read suggestions, positions and trades, and — if you allow it — act on them, without opening the dashboard. It's the same data and the same trade chokepoint the web app uses, just reachable from code.

Authentication

Create a key on Account → Security → Developer API access (requires a Pro plan). The raw key is shown once at creation — store it yourself, AlgoThink only ever keeps a hash of it. Send it as a bearer token on every request:

curl -H "Authorization: Bearer ak_..." \
  https://app.algoth.ink/api/v1/suggestions

A key only ever sees and does what your account can — the same tier and entitlements that gate the dashboard gate the API. There's no separate scope system to configure.

Read-only vs. trading keys

Each key is either read-only or allowed to trade, chosen when you create it. A read-only key can call every GET endpoint below; a trading key can additionally approve or reject suggestions and close positions. Keep a read-only key for a dashboard/monitoring bot and a separate trading key for anything that places orders — you can revoke one without touching the other.

Endpoints

MethodPathDoes
GET/api/v1/accountmode, tier, cash and equity
GET/api/v1/suggestionsyour pending suggestions
GET/api/v1/positionsyour open positions, with live mark/P&L
GET/api/v1/tradesyour last 50 closed trades
GET/api/v1/strategiesstrategies your plan entitles you to, with health stats
POST/api/v1/suggestions/{id}/approveexecute a suggestion (trading key only)
POST/api/v1/suggestions/{id}/rejectdismiss a suggestion (trading key only)
POST/api/v1/positions/{id}/closeclose an open position (trading key only)

GET /api/v1/account

curl -H "Authorization: Bearer ak_..." \
  https://app.algoth.ink/api/v1/account
{
  "mode": "paper",
  "tier": "pro",
  "cash_usdt": 8421.17,
  "equity_usdt": 9963.42,
  "can_trade": true
}

mode is "paper" or "live"; can_trade reflects this specific key, not your account as a whole — a read-only key always reports false here even on a trading-enabled account.

GET /api/v1/suggestions

{
  "suggestions": [
    {
      "id": 4821,
      "created_at": 1782300012.4,
      "symbol": "BTC/USDT",
      "side": "LONG",
      "size_usdt": 250.0,
      "sl": 61200.0,
      "tp": 65400.0,
      "strategy": "tsmom_weekly",
      "status": "pending"
    }
  ]
}

Only status: "pending" suggestions are returned — once approved, rejected or expired they drop out of this list (see /trades for what happened to executed ones). Timestamps throughout the API are Unix epoch seconds (UTC), not ISO strings.

GET /api/v1/positions

{
  "positions": [
    {
      "id": 991,
      "symbol": "BTC/USDT",
      "side": "long",
      "qty": 0.0041,
      "entry_price": 61850.0,
      "sl": 60100.0,
      "tp": 64900.0,
      "leverage": 2.0,
      "strategy": "tsmom_weekly",
      "opened_at": 1782212004.1,
      "mark": 62430.5,
      "value_usdt": 255.97,
      "upnl_usdt": 4.75,
      "liquidation_price": 31400.2
    }
  ]
}

mark, value_usdt, upnl_usdt and liquidation_price are computed against the platform's current price cache at request time, not stored values — they move between calls. liquidation_price is null on an unleveraged position.

GET /api/v1/trades

{
  "trades": [
    {
      "id": 883,
      "symbol": "ETH/USDT",
      "side": "long",
      "entry_price": 3120.0,
      "close_price": 3244.5,
      "opened_at": 1781990004.0,
      "closed_at": 1782102004.0,
      "close_reason": "tp",
      "pnl_usdt": 18.62,
      "strategy": "gap_momentum"
    }
  ]
}

Your most recent 50 closed positions, newest first. close_reason is one of manual, sl, tp, signal or liq.

GET /api/v1/strategies

{
  "entitled": ["darvas_daily", "gap_momentum", "tsmom_weekly"],
  "health": [
    {
      "strategy": "tsmom_weekly",
      "verdict": "FAIL",
      "pooled_sharpe": 0.83,
      "pct_folds_profitable": 0.58,
      "expected_hold_hours": 96.0,
      "live_n": 14,
      "live_pnl": 62.31,
      "live_win_rate": 0.57,
      "live_avg_hold_hours": 88.2
    }
  ]
}

entitled is every strategy your plan allows, whether or not it has traded yet. health has one entry per strategy with walk-forward and/or live history, and carries a few more diagnostic fields (exit-reason P&L breakdown, expectancy, average R-multiple) beyond the ones shown above. verdict is the strategy's out-of-sample walk-forward result (PASS/FAIL), independent of how it's performed on your own account so far.

POST /api/v1/suggestions/{id}/approve

curl -X POST -H "Authorization: Bearer ak_..." \
  "https://app.algoth.ink/api/v1/suggestions/4821/approve?leverage=2"
{"ok": true, "msg": "opened LONG 0.004000 BTC/USDT @ 61850.0000 (SL 60100.0000 / TP 64900.0000, 2x)"}

Pass ?leverage=N to override the default leverage, bounded by your account's own max leverage setting — a value outside that range fails without touching the suggestion:

{"ok": false, "msg": "leverage must be between 1 and your max 3x"}

Every approve goes through the exact same checks a click in the dashboard would — 2FA, live-trading arming, risk limits — an API key gets no special treatment. A suggestion that's already been approved, rejected or expired fails the same way for both callers:

{"ok": false, "msg": "suggestion is no longer pending"}

POST /api/v1/suggestions/{id}/reject

{"ok": true, "msg": "rejected suggestion #4821"}

POST /api/v1/positions/{id}/close

{"ok": true, "msg": "closed LONG BTC/USDT @ 62430.5000 (manual), pnl +4.75 USDT"}

Closing a position that's already closed, or one that doesn't belong to your account, fails the same way it would from the dashboard: {"ok": false, "msg": "position already closed"}.

Status codes

CodeMeaningBody
200request handled — for writes, check ok before assuming it succeeded{...} or {"ok": bool, "msg": str}
401missing, malformed or revoked key{"detail": "..."}
403key valid, but not entitled: below Pro, or a read-only key on a write endpoint{"detail": "..."}
422malformed request — e.g. leverage isn't a number{"detail": [...]}, FastAPI's standard validation format
429rate limit exceeded for this key{"detail": "..."}

There's a real distinction worth noting: a write endpoint almost never returns 4xx for a business-logic failure like an already-expired suggestion or an over-limit leverage request — those come back as 200 with {"ok": false, "msg": "..."}, the same as the dashboard's own buttons would show you. The 4xx codes above are about the request itself (who you are, whether you're allowed to ask), not the outcome of the trade action.

Rate limits

120 requests per minute per key. Cache GET responses for a few seconds in your own bot rather than polling in a tight loop — suggestions and positions don't change faster than the platform's own signal cycle.

Related

Pro includes full API access.

Create free account