Superior Api
#Superior API
REST API documentation and test cases for Superior Trade.
Base URL: https://api.superior.trade
Auth: x-api-key header on all protected endpoints
Docs: GET /docs (Swagger UI) · GET /openapi.json (OpenAPI spec) · GET /llms.txt (LLM-optimized)
#Getting an API key
- Go to https://account.superior.trade
- Sign up (email or wallet)
- Complete onboarding — a trading wallet is created for you
- Create an API key (
st_live_...) from your account settings
Use the key in the x-api-key header for all authenticated requests.
#Endpoints
#Public (no auth required)
| Method | Path | Description |
|---|---|---|
| GET | /health |
Health check — { "status": "ok", "timestamp": "..." } |
| GET | /docs |
Swagger UI |
| GET | /openapi.json |
OpenAPI 3.0 spec |
| GET | /llms.txt |
LLM-optimized API documentation |
| GET | /.well-known/ai-plugin.json |
AI plugin manifest |
#Backtesting
All backtesting endpoints require authentication via x-api-key.
| Method | Path | Description |
|---|---|---|
| GET | /v2/backtesting |
List all backtests (paginated) |
| POST | /v2/backtesting |
Create a new backtest |
| GET | /v2/backtesting/{id} |
Get backtest details |
| GET | /v2/backtesting/{id}/status |
Poll backtest status |
| PUT | /v2/backtesting/{id}/status |
Start a backtest |
| GET | /v2/backtesting/{id}/logs |
Get backtest logs |
| DELETE | /v2/backtesting/{id} |
Delete a backtest |
#Deployment
All deployment endpoints require authentication via x-api-key.
| Method | Path | Description |
|---|---|---|
| GET | /v2/deployment |
List all deployments (paginated) |
| POST | /v2/deployment |
Create a new deployment |
| GET | /v2/deployment/{id} |
Get deployment details |
| GET | /v2/deployment/{id}/status |
Get live deployment status |
| PUT | /v2/deployment/{id}/status |
Start or stop a deployment |
| POST | /v2/deployment/{id}/credentials |
Store exchange credentials |
| GET | /v2/deployment/{id}/credentials |
Get credential info (no secrets returned) |
| POST | /v2/deployment/{id}/exit |
Exit all open positions (must be stopped first) |
| GET | /v2/deployment/{id}/logs |
Get deployment logs |
| DELETE | /v2/deployment/{id} |
Delete a deployment |
#Authentication
All /v2/* endpoints require an API key in the x-api-key header:
curl https://api.superior.trade/v2/backtesting \ -H "x-api-key: st_live_YOUR_KEY"
Missing or invalid keys return 401:
{ "message": "No API key found in request", "request_id": "..." }
#Backtesting API
#Create a backtest
Required fields: config, code, timerange ({ "start": "YYYY-MM-DD", "end": "YYYY-MM-DD" }).
The timerange specifies the historical period to backtest against. Dates are validated against available data — the server returns invalid_timerange with available date bounds if the requested period is outside what's available.
curl -X POST https://api.superior.trade/v2/backtesting \ -H "x-api-key: st_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "config": { "exchange": { "name": "hyperliquid", "pair_whitelist": ["BTC/USDC:USDC"] }, "stake_currency": "USDC", "stake_amount": 100, "timeframe": "5m", "max_open_trades": 3, "stoploss": -0.1, "minimal_roi": { "0": 0.10 }, "trading_mode": "futures", "margin_mode": "cross", "entry_pricing": { "price_side": "other" }, "exit_pricing": { "price_side": "other" }, "pairlists": [{ "method": "StaticPairList" }] }, "code": "from freqtrade.strategy import IStrategy\nimport pandas as pd\nimport talib.abstract as ta\n\nclass MyStrategy(IStrategy):\n minimal_roi = {\"0\": 0.10}\n stoploss = -0.10\n timeframe = \"5m\"\n startup_candle_count = 20\n\n def populate_indicators(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:\n dataframe[\"rsi\"] = ta.RSI(dataframe, timeperiod=14)\n return dataframe\n\n def populate_entry_trend(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:\n dataframe.loc[dataframe[\"rsi\"] < 30, \"enter_long\"] = 1\n return dataframe\n\n def populate_exit_trend(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:\n dataframe.loc[dataframe[\"rsi\"] > 70, \"exit_long\"] = 1\n return dataframe", "timerange": { "start": "2025-11-01", "end": "2026-01-01" } }'
Response (201):
{ "id": "abc123", "status": "pending", "message": "Backtest created. Call PUT /:id/status with action \"start\" to begin." }
#Start a backtest
curl -X PUT https://api.superior.trade/v2/backtesting/abc123/status \ -H "x-api-key: st_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "action": "start" }'
Response (200):
{ "id": "abc123", "status": "running", "previous_status": "pending", "k8s_job_name": "bt-abc123" }
#Poll status
curl https://api.superior.trade/v2/backtesting/abc123/status \ -H "x-api-key: st_live_YOUR_KEY"
Response (200):
{ "id": "abc123", "status": "completed", "results": { "total_trades": 42, "winning_trades": 28, "losing_trades": 14, "win_rate": "66.7%", "total_profit": "12.5%", "max_drawdown": "4.2%", "sharpe_ratio": 1.85 }, "resultUrl": "https://storage.googleapis.com/..." }
Status values: pending → running → completed | failed
#Get full details
curl https://api.superior.trade/v2/backtesting/abc123 \ -H "x-api-key: st_live_YOUR_KEY"
Returns the full backtest object including config, code, timestamps, and a signed resultUrl for detailed JSON results (valid 24 hours).
#Get logs
curl "https://api.superior.trade/v2/backtesting/abc123/logs?pageSize=50" \ -H "x-api-key: st_live_YOUR_KEY"
Response (200):
{ "backtest_id": "abc123", "items": [ { "timestamp": "2026-03-28T10:00:00Z", "message": "Starting backtest...", "severity": "INFO" } ], "nextCursor": null }
#Delete a backtest
curl -X DELETE https://api.superior.trade/v2/backtesting/abc123 \ -H "x-api-key: st_live_YOUR_KEY"
Response (200): { "message": "Backtest deleted" }
Cancels the job if still running.
#Deployment API
#Create a deployment
curl -X POST https://api.superior.trade/v2/deployment \ -H "x-api-key: st_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "config": { "exchange": { "name": "hyperliquid", "pair_whitelist": ["BTC/USDC:USDC"] }, "stake_currency": "USDC", "stake_amount": 100, "timeframe": "5m", "max_open_trades": 3, "stoploss": -0.1, "minimal_roi": { "0": 0.10 }, "trading_mode": "futures", "margin_mode": "cross", "entry_pricing": { "price_side": "other" }, "exit_pricing": { "price_side": "other" }, "pairlists": [{ "method": "StaticPairList" }] }, "code": "...", "name": "BTC RSI Strategy" }'
Response (201):
{ "id": "def456", "status": "pending", "message": "Deployment created. Call PUT /:id/status with action \"start\" to begin." }
#Store credentials (for live trading)
Skip this step to run in dry-run/paper mode.
curl -X POST https://api.superior.trade/v2/deployment/def456/credentials \ -H "x-api-key: st_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "exchange": "hyperliquid" }'
The server resolves wallet credentials automatically — no private keys are accepted in the v2 API. Optionally pass wallet_address to use a specific wallet (ownership is validated server-side).
Response (200):
{ "id": "def456", "credentials_status": "stored", "exchange": "hyperliquid", "wallet_address": "0x...", "wallet_source": "main_trading_wallet", "agent_wallet_address": "0x...", "updated_at": "2026-03-28T10:00:00Z" }
Idempotent: Calling again returns existing credentials unchanged.
Errors:
| Code | Error | Cause |
|---|---|---|
| 400 | invalid_request |
private_key sent (not accepted in v2) |
| 400 | invalid_wallet_address |
Bad Ethereum address format |
| 400 | duplicate_wallet_address |
Wallet already used by another deployment |
| 400 | unsupported_exchange |
Exchange other than hyperliquid |
| 400 | no_wallet_available |
Cannot export key for this wallet |
| 403 | wallet_not_owned |
Wallet not owned by the authenticated user |
| 500 | server_misconfigured |
Server wallet config missing |
#Start a deployment
curl -X PUT https://api.superior.trade/v2/deployment/def456/status \ -H "x-api-key: st_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "action": "start" }'
Response (200):
{ "id": "def456", "status": "running", "previous_status": "pending", "k8s_deployment_name": "freqtrade-def456" }
If credentials are stored, the deployment trades live. If not, it runs in dry-run mode.
#Stop a deployment
curl -X PUT https://api.superior.trade/v2/deployment/def456/status \ -H "x-api-key: st_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "action": "stop" }'
Automatically cancels all open orders and closes all positions on Hyperliquid before stopping.
#Get credential info
curl https://api.superior.trade/v2/deployment/def456/credentials \ -H "x-api-key: st_live_YOUR_KEY"
Returns wallet metadata only — never returns private keys.
{ "id": "def456", "credentials_status": "stored", "exchange": "hyperliquid", "wallet_address": "0x...", "wallet_source": "main_trading_wallet", "wallet_type": "agent_wallet", "agent_wallet_address": "0x..." }
#Exit all positions
Deployment must be stopped first. Closes all open orders and liquidates all positions at market price.
curl -X POST https://api.superior.trade/v2/deployment/def456/exit \ -H "x-api-key: st_live_YOUR_KEY"
Response (200):
{ "id": "def456", "status": "stopped", "orders_cancelled": 3, "positions_closed": 2 }
#Delete a deployment
curl -X DELETE https://api.superior.trade/v2/deployment/def456 \ -H "x-api-key: st_live_YOUR_KEY"
Closes all positions and orders on Hyperliquid before deleting.
Response (200): { "message": "Deployment deleted" }
#Pagination
List endpoints return paginated results:
{ "items": [...], "nextCursor": "eyJ..." }
Pass cursor as a query parameter to fetch the next page:
curl "https://api.superior.trade/v2/backtesting?cursor=eyJ..." \ -H "x-api-key: st_live_YOUR_KEY"
#Limits
| Resource | Max |
|---|---|
| Backtests per user | 10 |
| Deployments per user | 10 |
Delete existing resources if you hit the limit. Creating beyond the limit returns:
{ "error": "limit_exceeded", "message": "Maximum of 10 backtests allowed. Please delete an existing backtest first." }
#Error format
All errors follow a consistent shape:
{ "error": "error_code", "message": "Human-readable description", "details": [...] }
| Status | Error | Description |
|---|---|---|
| 400 | validation_failed |
Request body failed schema validation |
| 400 | invalid_json |
Request body is not valid JSON |
| 400 | invalid_request |
Business logic violation (e.g. starting a non-pending backtest) |
| 400 | invalid_code |
Strategy code failed validation or compilation |
| 400 | limit_exceeded |
Resource limit reached |
| 401 | — | Missing or invalid API key |
| 403 | wallet_not_owned |
Wallet ownership check failed |
| 404 | not_found |
Resource not found |
| 500 | internal_error |
Server error |
#Validation
Both POST /v2/backtesting and POST /v2/deployment validate the strategy before accepting it:
- Config validation — exchange, timeframe, stake currency, stoploss, pair format
- Code compilation — Python syntax check
- Code linting — Ruff linter for common issues
- Strategy validation — must inherit from
IStrategy, class name must be PascalCase ending inStrategy, must implementpopulate_indicators,populate_entry_trend,populate_exit_trend
Invalid submissions return 400 with specific error details.
#Running the tests
This repo includes integration tests you can run against the live API.
npm install cp .env.example .env # add your API key npm test
See the tests/ directory for the full test suite.
#Related repositories
| Repo | Description |
|---|---|
| superior-skills | Skill file and main documentation |
| superior-examples | Practical workflows and examples |
| superior-mcp | MCP integration layer |
#Links
- Website: https://www.superior.trade/
- Account / API keys: https://account.superior.trade
- Swagger UI: https://api.superior.trade/docs
- OpenAPI spec: https://api.superior.trade/openapi.json
#Disclaimer
Trading involves risk. Backtests do not guarantee future performance. Users remain responsible for strategy choice, deployment decisions, exchange connectivity, and capital risk.