API Docs/

Agent Guide

Agent Onboarding

Build autonomous trading agents that discover strategies, receive signals, and run backtests via the ArcQuant API.

Quick Start

Three steps to get your agent connected to ArcQuant. Register for an API key, authenticate your requests, and start pulling signals.

1

Register for an API key

POST to /api/auth/register with your wallet address. You'll receive an aq_-prefixed API key instantly.
curl
curl -X POST https://arcquant.xyz/api/auth/register \
  -H "Content-Type: application/json" \
  -d '{"walletAddress": "0xYourWalletAddress", "name": "my-trading-bot"}'
Response:
json
{
  "success": true,
  "apiKey": "aq_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
  "walletAddress": "0xYourWalletAddress",
  "tier": "free",
  "createdAt": "2026-03-01T00:00:00.000Z"
}

Store your API key securely. It cannot be retrieved after creation — only revoked and re-generated.

2

Authenticate requests

Pass your key in the Authorization header on every request:
http
Authorization: Bearer aq_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4

Alternatively, use the x-api-key header:

http
x-api-key: aq_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4

Authenticated requests get 200 req/min per key — 10x more than unauthenticated.

3

Make your first API call

Discover available strategies, indicators, and node types:
curl
curl https://arcquant.xyz/api/v1/schema \
  -H "Authorization: Bearer aq_a1b2c3d4..."

# Returns: node types, 150+ indicators, filter operators,
# connection rules, exit logic, and param formats

Then fetch live signals from any strategy:

curl
curl "https://arcquant.xyz/api/signals?strategyId=strat-momentum-scalper&symbol=BTC/USDT" \
  -H "Authorization: Bearer aq_a1b2c3d4..."

Endpoint Reference

Key endpoints for agent integration. For the full API reference, see the API Documentation.

Auth API

POST/api/auth/registerNo Auth

Generate a new API key tied to your wallet address. One active key per wallet.

walletAddressstringrequired

Your wallet address (1–200 chars)

namestring?

Optional label for this key (max 200 chars)

json
// Response
{
  "success": true,
  "apiKey": "aq_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
  "walletAddress": "0x...",
  "tier": "free",
  "createdAt": "2026-03-01T00:00:00.000Z"
}
POST/api/auth/revokeNo Auth

Permanently deactivate an API key. After revocation, register again for a new key.

json
// Request body
{ "key": "aq_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4" }

// Response
{ "success": true }
GET/api/auth/usageBearer aq_ key

Check your API usage stats, call breakdown by tier, and estimated costs.

json
{
  "success": true,
  "totalCalls": 1847,
  "callsByTier": { "price": 850, "indicator": 620, "strategy": 377 },
  "estimatedCost": 592.0,
  "recentCalls": [
    {
      "apiKey": "aq_...",
      "endpoint": "/api/signals",
      "tier": "strategy",
      "timestamp": "2026-03-01T12:30:00.000Z",
      "latencyMs": 142
    }
  ]
}

Schema Discovery

GET/api/v1/schemaAgent-FriendlyNo Auth

Full data dictionary for the Strategy Builder. Returns all node categories, 150+ indicators with parameter specs, filter operators, connection rules, exit logic, and action types. Designed for agents to programmatically discover and build strategies.

Key sections in the response:

categories

Node types: source, indicator, filter, logic, action

connectionRules

Which node types can connect to which

indicatorNodes

150+ indicators with param specs and defaults

filterNodes

Comparison operators and band-touch types

actionNodes

Market orders, TP/SL, trailing stop, alerts

exitRules

Take profit, stop loss, trailing stop behavior

json
// Abridged response
{
  "version": "1.1.0",
  "categories": ["source", "indicator", "filter", "logic", "action"],
  "connectionRules": {
    "source": { "canConnectTo": ["indicator", "filter", "logic"] },
    "indicator": { "canConnectTo": ["indicator", "filter", "logic", "action"] },
    ...
  },
  "indicatorNodes": {
    "indicators": [
      { "name": "RSI", "match": "rsi", "params": { "period": { "default": 14 } } },
      { "name": "MACD", "match": "macd", "params": { "fast": 12, "slow": 26, "signal": 9, "output": "line" } },
      { "name": "EMA", "match": "ema", "params": { "period": { "default": 20 } } },
      // ... 147 more
    ]
  },
  "exitRules": {
    "fields": { "takeProfitPct": "number", "stopLossPct": "number", "trailingStopPct": "number" },
    "behavior": {
      "longTP": "Exit when candle high >= entry * (1 + tp/100)",
      "longSL": "Exit when candle low <= entry * (1 - sl/100)",
      "sameBarConflict": "SL wins if both trigger on same bar"
    }
  }
}

Signals

GET/api/signalsBearer aq_ key

Fetch the latest signals from a strategy for a given symbol. Returns direction (BUY/SELL), confidence score, and supporting indicator values.

strategyIdstringrequired

Strategy ID (e.g. "strat-momentum-scalper")

symbolstringrequired

Trading pair (e.g. "BTC/USDT", "AAPL")

Backtesting

POST/api/backtestBearer aq_ key

Run a full backtest on a strategy. Returns signals, trades with entry/exit prices and exit reasons, portfolio metrics (win rate, return, drawdown), and risk analytics (Sharpe, Sortino).

json
// Request body
{
  "strategyId": "strat-momentum-scalper",
  "symbol": "BTC/USDT",
  "startDate": "2025-03-01",
  "endDate": "2026-03-01"
}

// Response includes:
// - signals[]: { date, direction, confidence, indicators }
// - portfolio: { totalTrades, winRate, totalReturnPct, maxDrawdown }
// - metrics: { sharpeRatio, sortinoRatio, profitFactor }
// - trades[]: { entryDate, entryPrice, exitDate, exitPrice, exitReason, pnl }

Async Backtest (Webhook Delivery)

POST/api/backtest/runasync

For long-running backtests, include a callbackUrl to receive the result asynchronously. The API returns 202 Accepted with a job ID immediately. When the backtest finishes, the result is POSTed to your callback URL with an HMAC-SHA256 signature.

json
// Request — include callbackUrl for async mode
{
  "strategyId": "strat-momentum-scalper",
  "symbol": "BTC/USDT",
  "startDate": "2025-03-01",
  "endDate": "2026-03-01",
  "callbackUrl": "https://your-agent.com/webhook/backtest"
}

// 202 Response (immediate)
{
  "jobId": "bt_m3k9x_a1b2c3d4",
  "status": "processing",
  "message": "Backtest queued. Result will be delivered to your callbackUrl.",
  "statusUrl": "/api/backtest/status/bt_m3k9x_a1b2c3d4"
}

// Webhook delivery to callbackUrl (when done)
// Headers: X-ArcQuant-Signature, X-ArcQuant-Event: backtest.completed
{
  "event": "backtest.completed",
  "jobId": "bt_m3k9x_a1b2c3d4",
  "status": "completed",
  "result": { "signals": [...], "portfolio": {...}, "trades": [...] }
}
GET/api/backtest/status/:jobIdBearer aq_ key

Poll job status as an alternative to webhooks. Returns the full result once the backtest completes. Jobs are cleaned up after 24 hours.

json
// Response (processing)
{ "jobId": "bt_m3k9x_a1b2c3d4", "status": "processing", "createdAt": "..." }

// Response (completed — includes full result)
{
  "jobId": "bt_m3k9x_a1b2c3d4",
  "status": "completed",
  "result": { "signals": [...], "portfolio": {...}, "trades": [...] },
  "completedAt": "2026-03-01T12:01:00Z"
}

Strategies

GET/api/strategiesBearer aq_ key

List all available strategies. Returns strategy ID, name, description, node graph, and symbols. Use the schema endpoint to understand node types before parsing the DAG.

POST/api/strategiesBearer aq_ key

Create a new strategy with a node graph. Agents can programmatically build strategies using the node types and connection rules from the schema endpoint.

Webhooks

Receive real-time signal notifications pushed to your agent's callback URL. All payloads are signed with HMAC-SHA256 for verification.

Setting Up Webhooks

Subscribe to a strategy's signals by POSTing to the subscription endpoint. You'll receive a whsec_-prefixed webhook secret for signature verification.

curl
curl -X POST https://arcquant.xyz/api/signals/subscribe \
  -H "Authorization: Bearer aq_a1b2c3d4..." \
  -H "Content-Type: application/json" \
  -d '{
    "strategyId": "strat-momentum-scalper",
    "interval": "5m",
    "callbackUrl": "https://my-agent.example.com/webhook"
  }'

Webhook payload delivered to your callback URL:

json
{
  "event": "signal",
  "strategyId": "strat-momentum-scalper",
  "strategyName": "Momentum Scalper",
  "signal": {
    "id": "sig_abc123",
    "symbol": "BTC/USDT",
    "direction": "BUY",
    "confidence": 0.82,
    "timestamp": "2026-03-01T12:30:00.000Z",
    "indicators": { "rsi": 28.4, "ema_crossover": 1.2 }
  },
  "meta": {
    "deliveredAt": "2026-03-01T12:30:01.142Z",
    "subscriptionId": "sub_xyz789"
  }
}

Verifying Webhook Signatures

Every webhook request includes an X-ArcQuant-Signature header containing a hex-encoded HMAC-SHA256 hash of the request body, signed with your webhook secret.

Always verify the signature before processing webhook payloads. Reject any request where the computed HMAC doesn't match the header value.

python
import hmac, hashlib

def verify_webhook(body: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(
        secret.encode(), body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature)
typescript
import { createHmac, timingSafeEqual } from "crypto";

function verifyWebhook(body: string, signature: string, secret: string): boolean {
  const expected = createHmac("sha256", secret)
    .update(body)
    .digest("hex");
  return timingSafeEqual(
    Buffer.from(expected, "hex"),
    Buffer.from(signature, "hex")
  );
}

Retry & Failure Policy

AttemptDelayTimeout
1st (immediate)0s10s
2nd retry1s10s
3rd retry5s10s
After 3 consecutive failures, webhook is auto-disabled. Re-subscribe to re-enable.

Code Examples

Complete examples for integrating your agent with ArcQuant in different languages.

curl

bash
# Register for API key
curl -X POST https://arcquant.xyz/api/auth/register \
  -H "Content-Type: application/json" \
  -d '{"walletAddress": "0xYourWallet"}'

# Discover strategy schema
curl https://arcquant.xyz/api/v1/schema \
  -H "Authorization: Bearer aq_YOUR_KEY"

# Get signals
curl "https://arcquant.xyz/api/signals?strategyId=strat-rsi-oversold&symbol=ETH/USDT" \
  -H "Authorization: Bearer aq_YOUR_KEY"

# Run backtest
curl -X POST https://arcquant.xyz/api/backtest \
  -H "Authorization: Bearer aq_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "strategyId": "strat-momentum-scalper",
    "symbol": "BTC/USDT",
    "startDate": "2025-06-01",
    "endDate": "2026-03-01"
  }'

# Check usage
curl https://arcquant.xyz/api/auth/usage \
  -H "Authorization: Bearer aq_YOUR_KEY"

# Revoke key
curl -X POST https://arcquant.xyz/api/auth/revoke \
  -H "Content-Type: application/json" \
  -d '{"key": "aq_YOUR_KEY"}'

Python

python
import requests

BASE = "https://arcquant.xyz"

# 1. Register
resp = requests.post(f"{BASE}/api/auth/register", json={
    "walletAddress": "0xYourWallet",
    "name": "my-python-agent"
})
api_key = resp.json()["apiKey"]
headers = {"Authorization": f"Bearer {api_key}"}

# 2. Discover available indicators & node types
schema = requests.get(f"{BASE}/api/v1/schema", headers=headers).json()
print(f"Available indicators: {len(schema['indicatorNodes']['indicators'])}")

# 3. List strategies
strategies = requests.get(f"{BASE}/api/strategies", headers=headers).json()
for s in strategies["data"][:5]:
    print(f"  {s['id']}: {s['name']}")

# 4. Get live signals
signals = requests.get(
    f"{BASE}/api/signals",
    params={"strategyId": "strat-momentum-scalper", "symbol": "BTC/USDT"},
    headers=headers
).json()
for sig in signals.get("signals", []):
    print(f"  {sig['direction']} @ confidence {sig['confidence']:.2f}")

# 5. Run backtest
bt = requests.post(f"{BASE}/api/backtest", headers=headers, json={
    "strategyId": "strat-momentum-scalper",
    "symbol": "BTC/USDT",
    "startDate": "2025-06-01",
    "endDate": "2026-03-01"
}).json()
print(f"Win rate: {bt['portfolio']['winRate']:.1f}%")
print(f"Return: {bt['portfolio']['totalReturnPct']:.2f}%")
print(f"Sharpe: {bt['metrics']['sharpeRatio']:.3f}")

# 6. Subscribe to webhook signals
sub = requests.post(f"{BASE}/api/signals/subscribe", headers=headers, json={
    "strategyId": "strat-momentum-scalper",
    "interval": "5m",
    "callbackUrl": "https://my-agent.example.com/webhook"
}).json()
print(f"Webhook secret: {sub['secret']}")  # Store securely!

# 7. Check usage
usage = requests.get(f"{BASE}/api/auth/usage", headers=headers).json()
print(f"Total API calls: {usage['totalCalls']}")

TypeScript

typescript
const BASE = "https://arcquant.xyz";

// 1. Register
const reg = await fetch(`${BASE}/api/auth/register`, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ walletAddress: "0xYourWallet", name: "my-ts-agent" }),
});
const { apiKey } = await reg.json();
const headers = { Authorization: `Bearer ${apiKey}` };

// 2. Discover schema
const schema = await fetch(`${BASE}/api/v1/schema`, { headers }).then(r => r.json());
console.log(`${schema.indicatorNodes.indicators.length} indicators available`);

// 3. Get signals
const signals = await fetch(
  `${BASE}/api/signals?strategyId=strat-momentum-scalper&symbol=BTC/USDT`,
  { headers }
).then(r => r.json());

for (const sig of signals.signals ?? []) {
  console.log(`${sig.direction} @ confidence ${sig.confidence.toFixed(2)}`);
}

// 4. Run backtest
const bt = await fetch(`${BASE}/api/backtest`, {
  method: "POST",
  headers: { ...headers, "Content-Type": "application/json" },
  body: JSON.stringify({
    strategyId: "strat-momentum-scalper",
    symbol: "BTC/USDT",
    startDate: "2025-06-01",
    endDate: "2026-03-01",
  }),
}).then(r => r.json());

console.log(`Win rate: ${bt.portfolio.winRate.toFixed(1)}%`);
console.log(`Return: ${bt.portfolio.totalReturnPct.toFixed(2)}%`);
console.log(`Sharpe: ${bt.metrics.sharpeRatio.toFixed(3)}`);

// 5. Webhook handler (Express example)
import express from "express";
import { createHmac, timingSafeEqual } from "crypto";

const app = express();
app.post("/webhook", express.raw({ type: "*/*" }), (req, res) => {
  const signature = req.headers["x-arcquant-signature"] as string;
  const expected = createHmac("sha256", WEBHOOK_SECRET)
    .update(req.body)
    .digest("hex");

  if (!timingSafeEqual(Buffer.from(expected, "hex"), Buffer.from(signature, "hex"))) {
    return res.status(401).send("Invalid signature");
  }

  const payload = JSON.parse(req.body.toString());
  console.log(`Signal: ${payload.signal.direction} ${payload.signal.symbol}`);
  res.status(200).send("OK");
});
app.listen(8080);

Rate Limits

Authenticated agents get significantly higher rate limits. Always include your API key.

EndpointUnauthenticatedWith API Key
/api/backtest/*10 req/min200 req/min
/api/signals/*20 req/min200 req/min
/api/v1/schema60 req/min200 req/min
All other endpoints30 req/min200 req/min

Rate-limited responses return 429 Too Many Requests with headers:

http
Retry-After: 12
X-RateLimit-Limit: 200
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 12

Error Handling

All errors return a consistent JSON structure. Use the HTTP status code and error message to determine the appropriate response in your agent.

StatusMeaningAgent Action
400Bad RequestFix request params and retry
401UnauthorizedCheck API key is valid and not revoked
404Not FoundVerify endpoint path and resource ID
429Rate LimitedWait for Retry-After seconds, then retry
500Server ErrorRetry with exponential backoff (max 3 attempts)

Error response format:

json
{
  "success": false,
  "error": "Description of what went wrong"
}
Full API Reference

Questions? Reach out on Slack or open a GitHub issue.