API Documentation
Every externally-callable HTTP endpoint this app exposes, stated honestly: the only endpoints designed for third-party/programmatic consumption today are the health-check family. Everything else under src/app/api/ exists to serve this app's own UI or a scheduled cron job, not as a general-purpose public API — listed below for completeness, not because they're meant to be integrated against. There is no broader REST API for creating copy relationships, placing trades, or reading account data programmatically yet; the product surface for those is the dashboard UI itself.
Authentication
Two credential types, either accepted on every endpoint below that requires auth (see src/lib/security/api-auth.ts):
1. Session cookie — the normal browser session from being logged in. Not usable from a script/server-to-server; this is the dashboard UI's own auth. 2. API key — Authorization: Bearer atc_live_.... Create one at Settings → Security → API Keys (/dashboard/settings/security). A key is scoped read_only or read_write at creation and shown in full exactly once — only its hash is ever stored, so a lost key can't be recovered, only revoked and replaced. Bearer tokens are inherently immune to CSRF (browsers never attach them automatically the way cookies are), which is why this is the credential type for any non-browser caller.
Health & status endpoints
The real, intended-for-external-use API surface — built for uptime monitors and status dashboards. All return JSON with HTTP 200 (healthy/degraded) or 503 (unhealthy) — a monitor should alert on the HTTP status, not just parse the body.
GET /api/health
The aggregate check — every sub-check below, combined into one report. Accepts either credential (optional — degrades to a non-user-scoped report if neither is presented, rather than requiring auth for a basic uptime probe).
{
"status": "healthy",
"checkedAt": "2026-08-08T12:00:00.000Z",
"authenticated": true,
"checks": [
{ "name": "database", "status": "healthy", "latencyMs": 42 },
{ "name": "broker_connections", "status": "healthy", "details": { "...": "..." } },
{ "name": "copy_engine", "status": "healthy" },
{ "name": "event_bus", "status": "healthy" },
{ "name": "market_data", "status": "degraded", "message": "..." }
]
}GET /api/health/database
Postgres reachability/latency via Supabase. No auth required — a global check, not user-scoped.
GET /api/health/event-bus
The in-process connector event bus's own health. No auth required — reflects this server instance's own state (see docs/ARCHITECTURE.md on why this is per-instance, not fleet-wide).
GET /api/health/market-data
Market-data/connector latency metrics (connector_order_latency_ms, connector_market_data_latency_ms, connector_position_sync_latency_ms histograms). No auth required.
GET /api/health/brokers
This caller's broker connection health — requires auth (session or API key); returns a non-user-scoped shape if neither is presented (see _shared.ts's currentUserId).
GET /api/health/copy-engine
This caller's Copy Engine / active copy relationship health — same auth behavior as /brokers above.
Scheduled/internal endpoints (not for general use)
Each gated by a shared secret header, not the API-key system above — meant for exactly one external cron/scheduler to call, not for end-user integration:
| Endpoint | Header | Purpose |
|---|---|---|
GET /api/admin/alerts/check | x-alert-check-secret: $ALERT_CHECK_SHARED_SECRET | Threshold checks (queue backlog, high latency, health failures) that feed the Alert System |
GET /api/ai/automations/run | x-automation-run-secret: $AI_AUTOMATION_RUN_SECRET | Runs due AI-driven automations |
GET /api/automation/workflows/run | x-automation-run-secret: $AUTOMATION_WORKFLOW_RUN_SECRET | Runs due Workflow Engine automations |
See DEPLOYMENT.md §12 Monitoring for how to actually schedule these (Vercel Cron, a systemd timer, GitHub Actions, etc. — this app has no built-in scheduler of its own).
Webhooks (inbound, not outbound)
POST /api/webhooks/stripe — Stripe's own webhook delivery, verified via STRIPE_WEBHOOK_SECRET signature checking. Not callable by anyone else; documented here only for completeness.
What's NOT here (and why)
- No public REST API for trades/positions/copy relationships. Every
such action today happens through a Next.js Server Action, reached only from this app's own dashboard UI, not a documented/stable JSON API contract meant for third parties. Building a real public API (with its own versioning, request/response contracts, and API-key scope enforcement beyond read_only/read_write) would be a genuinely new feature, not something to imply already exists.
- No webhook system for outbound events (e.g. "notify my server
when a copy executes") — the Alert System (docs/ALERT_SYSTEM.md) covers Slack/Discord/Telegram/SMS/email notification, not a developer-facing webhook subscription API.
- No rate limit is currently applied per API key on the health
endpoints specifically — reviewed deliberately during the production security audit (docs/SECURITY_REVIEW.md §12) and left as-is: these are lightweight, read-only checks, and throttling a health-check endpoint risks breaking legitimate uptime monitoring for negligible benefit. If a genuine data-returning public API is built later, it should NOT inherit this same assumption.