This document defines the contract rules for QuantDinger HTTP APIs. Machine-readable specs:
| Spec | Path | Audience |
|---|---|---|
| Human Web API (flask-smorest) | docs/api/openapi.yaml |
Frontend, integrators, community |
| Agent Gateway | docs/agent/agent-openapi.json |
AI agents, MCP, automation |
Browse the human spec locally: open docs/api/index.html (Redoc).
- Authenticated with user JWT (
Authorization: Bearer <jwt>) unless noted. - Used by the QuantDinger web/mobile UI.
- Authenticated with agent tokens (
qd_agent_...), scoped (R/W/B/...). - Documented separately; do not mix agent routes into the human spec without an
x-agent-onlytag. - See
docs/agent/AGENT_QUICKSTART.md.
{
"code": 1,
"msg": "success",
"data": { }
}| Field | Type | Notes |
|---|---|---|
code |
int | 1 = success |
msg |
string | Human-readable status |
data |
any | Payload; may be null |
{
"code": 0,
"msg": "Error description",
"data": null
}HTTP status is often 400, 401, 403, or 500 depending on the route.
OpenAPI schemas: HumanSuccessEnvelope, HumanErrorEnvelope in docs/api/openapi.yaml.
Agent routes use message (not msg) and code: 0 on success.
Errors may include details and retriable. See docs/agent/agent-openapi.json.
| Scheme | Header | Used by |
|---|---|---|
HumanJWT |
Authorization: Bearer <jwt> |
Human Web API |
AgentToken |
Authorization: Bearer qd_agent_... |
/api/agent/v1/* only |
Obtain JWT via POST /api/auth/login (documented in a future migration phase).
Tag or extension every operation when migrating to flask-smorest:
| Tier | OpenAPI | Who may rely on it |
|---|---|---|
| Public | default tag, no extension | Open-source community, third-party clients |
| Internal | x-visibility: internal |
QuantDinger product; may change without notice |
| Private | x-visibility: private |
Admin / sensitive; minimal public docs |
Public modules (migration priority): community, market, indicator, backtest, global-market, health.
Internal / sensitive: strategy, credentials, billing, quick-trade, broker adapters (ibkr, alpaca, mt5).
- Paths: lowercase, kebab-case segments (
/api/global-market/...). - Query params: snake_case (
page_size,sort_by). - JSON bodies: snake_case (match existing backend).
- Document breaking changes in PR descriptions; CI runs
oasdiffagainst committeddocs/api/openapi.yaml. - Future human API versioning: prefer
/api/v2/...over silent breaking changes.
Common shape inside data:
{
"items": [],
"total": 0,
"page": 1,
"page_size": 12
}OpenAPI schema: PaginationMeta (fields may be inlined per route during migration).
- New Public route — implement with flask-smorest in
app/openapi/routes/(or migrate existing Blueprint). - Regenerate spec —
cd backend_api_python && python scripts/export_openapi.py - Commit — include updated
docs/api/openapi.yamlin the same PR. - Agent routes — update
docs/agent/agent-openapi.jsonseparately. - PR checklist — see CONTRIBUTING.md.
Local interactive docs (debug mode): /api/docs/swagger and /api/docs/redoc when OPENAPI_ENABLED=true or PYTHON_API_DEBUG=true.
| Module | Status | Spec source |
|---|---|---|
Health (/, /health, /api/health) |
Migrated | flask-smorest |
| Agent Gateway | Hand-written OpenAPI + CI lint | docs/agent/agent-openapi.json |
| All other modules | Legacy Flask Blueprint | Not yet in openapi.yaml |
Phase 1+ will migrate community, market, etc. incrementally.