Skip to content

REST API Overview

The services/api Hono server exposes the full Doable REST surface. This page is a high-level map; per-resource pages drill into specific endpoints.

The API does not yet have an OpenAPI spec. Use this page + the route source files as the reference. Source lives under services/api/src/routes/.

Base URL

Environment URL
Local dev http://localhost:4000
Docker (default) http://localhost:4000 (proxied through nginx as https://<host>/api)
Production https://api.<your-domain> (or https://<host>/api)

The web app reads it from NEXT_PUBLIC_API_URL.

Authentication

All authenticated endpoints expect a JWT in either:

  • the Authorization: Bearer <token> header (preferred for SDKs/CLI), or
  • the doable_access_token HttpOnly cookie (used by the web app).

See Authentication for the full flow.

A small set of endpoints is intentionally public:

  • /health
  • /auth/* (login, signup, OAuth, password reset)
  • /preview/:projectId/* (live preview proxy — protected by per-project tokens, not JWT)
  • /visual-edit-bridge.js

Mounted route groups

From services/api/src/routes.ts:

Mount Module Purpose
/health routes/health.ts Liveness/readiness
/internal/* routes/internal.ts Server-to-server (signed by INTERNAL_SECRET)
/auth/* routes/auth.ts, routes/auth/* Sign up, login, OAuth, password reset
/preview/:id/* routes/preview-proxy.ts Reverse proxy to Vite dev servers
/projects/* routes/projects.ts, routes/projects/* CRUD on projects
/projects/:id/files/* routes/project-files.ts File CRUD (filesystem-backed)
/projects/:id/context/* routes/context.ts Semantic context (pgvector)
/projects/:id/security/* routes/security.ts Project-level secrets
/projects/:id/versions/* routes/versions.ts Git history
/projects/:id/env-vars/* routes/env-vars.ts Per-project env vars
/workspaces/* routes/workspaces.ts Workspaces & members
/workspaces/:id/ai/* routes/ai-settings*.ts AI provider/key config
/workspaces/:id/connectors/* routes/connectors.ts MCP connectors
/workspaces/:id/skills/* routes/skills.ts Per-workspace skills
/workspaces/:id/environments/* routes/environments.ts Build environments
/folders/* routes/folders.ts Project folders
/billing/* routes/billing.ts Stripe checkout / portal / webhooks
/deploy/* routes/deploy.ts Build & publish
/domains/* routes/custom-domains.ts Custom domain management
/templates/* routes/templates.ts Project templates
/github/* routes/github.ts, routes/github/* Repo sync, PRs
/thumbnails/* routes/thumbnails.ts Project preview screenshots
/analytics/* routes/analytics.ts, routes/analytics/* Usage events
/admin/* routes/admin*.ts Platform admin
/community/* routes/community.ts Stars, public projects
/marketplace/* routes/marketplace.ts Templates & skills marketplace
/integrations/* routes/integrations*.ts, routes/integrations/* Third-party connectors
/team-chat/* routes/team-chat.ts In-workspace chat
/chat/*, /plan/*, /editor/* routes/chat/*, routes/plan.ts, routes/editor.ts AI chat & editor APIs

Conventions

  • JSON request and response bodies. Content-Type: application/json.
  • Streaming endpoints (chat, plan) use Server-Sent Events with Content-Type: text/event-stream.
  • Errors are { "error": "<code>", "message": "<human readable>", "details": { ... } } with appropriate HTTP status codes.
  • IDs are UUID v4 unless explicitly noted.
  • Timestamps are ISO 8601 strings in UTC.
  • Pagination is cursor-based: ?cursor=<opaque>&limit=50. Responses include nextCursor when more results exist.

Rate limiting

The default policy in services/api/src/index.ts:

windowMs: 60_000,
max: 200,                 // requests per minute per token / IP

Override per-route by passing a different rate-limiter middleware. With REDIS_URL set, limits are shared across replicas; otherwise they're per-process.

Internal endpoints

Routes mounted under /internal are only callable with an Internal-Secret: <hex> header matching INTERNAL_SECRET. They power:

  • services/ws → API auth callbacks.
  • The publish pipeline calling back into the API after a build finishes.
  • Cron-like jobs (cleanup, analytics rollups).

Never expose /internal/* through your public proxy.

Health check

curl https://<host>/api/health
# {"status":"ok","db":"ok","ws":"ok","uptime":1234}

Use this for load balancers and uptime monitors.

→ Drill in: Auth · Projects · Chat · Files · WebSocket · Webhooks.