Spaces:
Paused
API Reference
Base and authentication
All Futures routes are mounted on the existing Hermes FastAPI application and port. In production, use the Space base URL and an authenticated browser/session or HTTP Basic credentials.
When HERMES_ADMIN_PASSWORD is set, Futures API routes require:
Authorization: Basic <base64(username:password)>
Default username: admin, configurable with HERMES_DASHBOARD_BASIC_AUTH_USERNAME.
All Futures responses set Cache-Control: no-store. /futures also sets no-cache headers and runtime SHA-256 headers.
GET /futures
Returns the packaged HTML dashboard.
Important response headers:
X-Hermes-Template-SHA256
X-Hermes-Router-SHA256
Cache-Control: no-store, no-cache, must-revalidate, max-age=0
GET /api/futures/status
Returns application status, runtime-file evidence, market health, latest bounded plan state, source metadata, account summary, and diagnostics.
Representative shape:
{
"application": {
"status": "online",
"runtimeStatus": "verified | mismatch | unknown",
"runtimeFiles": {}
},
"marketData": {"status": "healthy | degraded | unavailable"},
"tradingReadiness": "ready | blocked",
"mergeStatus": "complete | partial | unknown",
"analysisState": "NOT_ANALYZED",
"sourceMetadata": {
"datasource4": {},
"binance": {},
"datasource2": {}
},
"fieldSources": {},
"fieldMetadata": {},
"verifiedFutures": false,
"missingRequiredFields": [],
"staleRequiredFields": [],
"latestTradePlan": null,
"latestPlanId": null,
"latestSignalScore": null,
"riskApproved": false,
"tradingMode": "paper",
"equity": 10000.0,
"realizedPnlToday": 0.0,
"openPositionCount": 0,
"serverTime": 0
}
Consumers should treat additional fields as additive and avoid strict whole-object equality.
GET /api/futures/symbols
Returns the merged catalog.
{
"symbols": [
{
"symbol": "BTCUSDT",
"baseAsset": "BTC",
"quoteAsset": "USDT",
"futuresVerified": true,
"marketOnly": false,
"contractType": "PERPETUAL",
"status": "TRADING",
"source": "datasource4",
"rank": 1,
"updatedAt": "2026-07-21T00:00:00Z"
}
],
"source": "...",
"updatedAt": "...",
"counts": {
"total": 0,
"verifiedFutures": 0,
"marketOnly": 0
}
}
Catalog membership alone does not authorize execution. Only items with futuresVerified=true are eligible for Paper revalidation.
GET /api/futures/positions
Returns Paper mode and enriched open positions.
{
"mode": "paper",
"positions": [
{
"symbol": "BTC/USDT:USDT",
"side": "long",
"size": 0.01,
"entryPrice": 60000.0,
"markPrice": 60500.0,
"unrealizedPnl": 5.0
}
]
}
Mark price enrichment is best-effort. Missing mark data produces null, not zero.
GET /api/futures/market
Query parameters:
| Parameter | Type | Default | Constraints |
|---|---|---|---|
symbol |
string | BTCUSDT |
length 3–32; normalized server-side |
interval |
enum | 5m |
1m, 5m, 15m, 1h |
limit |
integer | 120 |
20–500 |
Example:
GET /api/futures/market?symbol=BTCUSDT&interval=5m&limit=120
Successful/partial shape:
{
"state": "available | partial | stale | unavailable",
"analysisState": "NOT_ANALYZED | STALE | API_UNAVAILABLE",
"dataUsability": "usable | degraded | unavailable",
"reason": null,
"symbol": "BTCUSDT",
"interval": "5m",
"limit": 120,
"candles": [
{"timestamp": 0, "open": 0, "high": 0, "low": 0, "close": 0, "volume": 0}
],
"currentPrice": null,
"markPrice": null,
"change24h": null,
"volume24h": null,
"fundingRate": null,
"openInterest": null,
"source": "datasource4 | binance_public | datasource2 | mixed | unavailable",
"sourcesUsed": [],
"fieldSources": {},
"fieldMetadata": {},
"freshness": "fresh | stale | invalid | unknown",
"verifiedFutures": false,
"futuresVerification": {},
"warnings": [],
"missingFields": [],
"analysisRequiredFieldsMissing": [],
"staleRequiredFields": [],
"mergeStatus": "complete | partial | unavailable",
"tradingReadiness": "ready | blocked",
"rejectionReasons": [],
"sourceMetadata": {},
"technicalDiagnostics": {},
"fetchedAt": 0
}
If acquisition raises, the route returns HTTP 503 with the same high-level keys, empty candles, null values, state=unavailable, analysisState=API_UNAVAILABLE, and blocked readiness.
No mock candles are permitted in production responses.
POST /api/futures/analyze
Request:
{
"symbol": "BTCUSDT",
"risk_profile": "moderate",
"include_external_context": false
}
Allowed risk profiles:
conservative
moderate
aggressive
Unknown request fields are rejected.
Representative response:
{
"planId": "server-generated-reference",
"symbol": "BTCUSDT",
"decision": "LONG | SHORT | NO_TRADE",
"analysis_state": "LONG | SHORT | NO_TRADE",
"score": null,
"confidence": null,
"components": {},
"core_reasons": [],
"warnings": [],
"entry": null,
"stop_loss": null,
"take_profit": null,
"reward_to_risk": null,
"risk_profile": "moderate",
"risk_percent": null,
"requested_leverage": 5,
"effective_leverage": null,
"quantity": null,
"estimated_slippage_percent": null,
"risk_approved": false,
"rejection_reasons": [],
"noTradeGuard": true,
"plan_type": "directional_plan | non_executable_plan",
"executable": false,
"futuresVerified": false,
"trading_readiness": "blocked",
"created_at": "...",
"expires_at": "...",
"external_advisory": null
}
A NO_TRADE response is a successful deterministic evaluation, not an HTTP failure. An internal analysis failure returns HTTP 503 with detail="Futures analysis failed" and clears the current plan state.
POST /api/futures/paper/execute
Request:
{
"symbol": "BTCUSDT",
"risk_profile": "moderate",
"planId": "server-generated-reference"
}
The endpoint may return:
403for unverified contract or non-Paper mode;409for superseded/unknown plan, symbol/risk change, expiry, prior execution, blocked readiness, failed fresh revalidation, or non-executable plan;422for invalid request shape/symbol;200for the final Paper result.
The endpoint is intentionally absent from the read-only audit tool.
Telegram routes
POST /api/telegram/webhook
Public webhook ingress protected by:
X-Telegram-Bot-Api-Secret-Token: <TELEGRAM_WEBHOOK_SECRET>
Limits request body to 256 KiB, applies per-user rate limiting, requires owner/allowed-user authorization, and invokes analysis-only commands.
GET /api/telegram/status
Returns enabled/mode/webhook/proxy/relay/authorized-user/alert-scheduler status. It does not expose tokens or user IDs.
GET /api/telegram/bootstrap/status
Requires the same Telegram secret header and returns only:
{"ok": true, "ownerClaimed": true, "bootstrapConsumed": true}