diff --git a/src/app/docs/api/page.tsx b/src/app/docs/api/page.tsx index 1a9c11b..a93891f 100644 --- a/src/app/docs/api/page.tsx +++ b/src/app/docs/api/page.tsx @@ -10,32 +10,98 @@ export default function DocsApiPage() { title="API and Automation" intro="DashCaddy is more than a dashboard — it exposes a real API and automation surface so you can drive deployments, DNS, proxy, certificates, monitoring, and operations programmatically or through AI." > +

+ Every action available in the DashCaddy UI is also available through a programmatic surface: a versioned REST + API, a typed JavaScript SDK, an AI Intent Router for natural-language commands, an MCP Server for AI assistant + integration, a WebSocket channel for real-time events, a Prometheus endpoint for metrics, and a plugin system + for extending the platform. This guide covers each surface with concrete examples. +

+

+ Whether you are wiring DashCaddy into a CI/CD pipeline, building a custom dashboard, or letting an AI assistant + manage your infrastructure, the automation layer is designed to be the primary interface — the web UI is just + one consumer of it. +

+

REST API

- All platform operations are available under /api/v1/. The API covers service management, - app deployment, DNS automation, Caddy reverse-proxy integration, certificate workflows, health and status - reporting, user/admin operations, and backup/restore. The repository ships with an OpenAPI definition so the - public contract can mature into a full reference. + All platform operations are available under /api/v1/. The API covers service management, app + deployment, DNS automation, Caddy reverse-proxy integration, certificate workflows, health and status + reporting, user and admin operations, backup/restore, and more. The repository ships with an OpenAPI definition + so the public contract can mature into a full reference. +

+

+ Requests and responses are JSON. The base URL is your DashCaddy host — for example + https://dashcaddy-host/api/v1/services. All endpoints require authentication (see below) and + return structured error codes rather than opaque messages.

{`# List all services
-curl -H "Authorization: Bearer $TOKEN" \\
+curl -H "Authorization: Bearer ***" \\
   https://dashcaddy-host/api/v1/services
 
 # Deploy from a template
-curl -X POST -H "Authorization: Bearer $TOKEN" \\
+curl -X POST -H "Authorization: Bearer ***" \\
   -H "Content-Type: application/json" \\
-  -d '{"template":" jellyfin","name":"media","hostname":"media.lab"}' \\
-  https://dashcaddy-host/api/v1/services`}
+ -d '{"template":"jellyfin","name":"media","hostname":"media.lab"}' \\ + https://dashcaddy-host/api/v1/services + +# Restart a service +curl -X POST -H "Authorization: Bearer ***" \\ + https://dashcaddy-host/api/v1/services/media/restart`} + +

Authentication

+

+ DashCaddy supports two authentication methods, chosen by how you access the API: +

+

Session cookie (browser)

+

+ The web dashboard authenticates with a session cookie set after login (email magic link or username/password + with optional TOTP 2FA). API calls made from the browser carry the cookie automatically. This is the right + method for in-dashboard automation and userscripts. +

+

API key (Bearer token)

+

+ For server-to-server automation, scripts, and the SDK, use an API key. Generate keys from + Settings → API Keys. Keys are bearer tokens — pass them in the Authorization + header on every request: +

+
{`Authorization: Bearer dc_live_xxxxxxxxxxxxxxxxxxxx`}
+
+

+ Security: API keys grant the same permissions as the user who + created them, scoped by RBAC role. Store keys in a secret manager — never commit them to source control. + Rotate keys immediately if one is leaked. +

+
+ +

Rate limiting

+

+ The API applies per-token rate limiting to protect the platform from runaway scripts and abusive clients. + Limits are generous for normal operation: interactive dashboard usage will never hit them. If a client exceeds + the limit, the API responds with 429 Too Many Requests and a Retry-After header + indicating when to retry. Back off and retry — do not hammer the endpoint. +

+

+ For high-volume automation (e.g. polling service status in a tight loop), prefer the WebSocket + channel or the Prometheus endpoint over repeated REST polling. Both are designed for + frequent reads and do not count against the REST rate limit. +

JavaScript SDK

For programmatic automation, DashCaddy ships a typed JavaScript SDK with 39 methods and full TypeScript types. It mirrors the REST API and handles authentication, retries, and structured - error handling for you. + error handling for you. Install it from npm and use it in Node.js, Deno, Bun, or the browser.

+
{`# Install
+npm install @dashcaddy/sdk
+# or
+pnpm add @dashcaddy/sdk`}
{`import { DashCaddy } from '@dashcaddy/sdk';
 
-const dc = new DashCaddy({ baseUrl: 'https://dashcaddy-host', token: process.env.DC_TOKEN });
+const dc = new DashCaddy({
+  baseUrl: 'https://dashcaddy-host',
+  token: process.env.DC_TOKEN,
+});
 
 // List services
 const services = await dc.services.list();
@@ -48,60 +114,215 @@ const svc = await dc.services.deploy({
 });
 
 // Adopt a discovered container
-await dc.services.adopt({ containerId: 'abc123', hostname: 'wiki.lab' });`}
+await dc.services.adopt({ containerId: 'abc123', hostname: 'wiki.lab' }); -

Structured error codes

+// Create a DNS record +await dc.dns.createRecord({ zone: 'lab', name: 'wiki', type: 'A', ip: '192.168.1.55' }); + +// Inspect service health +const health = await dc.services.health('media');`}

- The API and SDK return 80 structured error codes rather than opaque messages, so your - automation can branch on specific failure conditions (DNS token invalid, Caddy unreachable, license expired, - etc.) instead of parsing strings. + Every SDK method returns a typed result or throws a structured DashCaddyError carrying the error + code, HTTP status, and message — so your automation can branch on specific failure conditions.

AI Intent Router

The AI Intent Router accepts natural-language commands and translates them into real - infrastructure actions through the same API. This turns ad-hoc operator requests into reproducible, logged - operations. + infrastructure actions through the same API. This turns ad-hoc operator requests (“restart the media + server”, “is postgres up?”, “deploy redis”) into reproducible, logged operations + — no need to remember endpoint paths or parameter names. +

+

+ The router parses intent, maps it to the correct API call, executes it, and returns both a human-readable + summary and the raw API result. Every intent execution is recorded in the audit log just like a manual action.

{`# Natural-language operation
 POST /api/v1/ai/intent
-{ "message": "Restart the media server and check its health" }`}
+{ + "message": "Restart the media server and check its health" +} + +# Response +{ + "summary": "Restarted 'media' and confirmed health: healthy", + "actions": [ + { "method": "POST", "path": "/api/v1/services/media/restart", "status": 200 }, + { "method": "GET", "path": "/api/v1/services/media/health", "status": 200 } + ] +}`} +

+ Example intents: “deploy the postgres template as db on db.lab”, + “list all unhealthy services”, “rotate the TLS cert for wiki.lab”, + “create a DNS record for api.lab pointing at 10.0.0.5”. +

MCP Server

The built-in MCP (Model Context Protocol) Server exposes DashCaddy operations as tools that AI assistants and external automation can call directly. Connect your assistant to the MCP endpoint and it can - list services, deploy templates, manage DNS, and inspect health — all through the standard MCP tool interface. + list services, deploy templates, manage DNS, inspect health, and trigger operations — all through the standard + MCP tool interface, with full audit logging. +

+

+ To connect Claude Desktop, GPT, or another MCP-compatible assistant, add the DashCaddy MCP server to your + client's MCP configuration: +

+
{`{
+  "mcpServers": {
+    "dashcaddy": {
+      "url": "https://dashcaddy-host/mcp",
+      "headers": {
+        "Authorization": "Bearer dc_live_xxxxxxxxxxxxxxxxxxxx"
+      }
+    }
+  }
+}`}
+

+ Once connected, the assistant discovers DashCaddy's tools automatically and can invoke them in response to + your requests — “ask DashCaddy which services are down”, “have DashCaddy deploy Grafana”, + etc. This is the most natural way to operate infrastructure through conversation.

-

WebSocket real-time updates

+

WebSocket real-time events

The dashboard subscribes to a WebSocket channel for live updates: service health changes, - container starts/stops, deployment progress, and fleet events arrive in real time without polling. You can - consume the same channel in your own dashboards or automation. + container starts and stops, deployment progress, DNS changes, and fleet events arrive in real time without + polling. You can consume the same channel in your own dashboards, chatops bots, or automation.

+
{`const ws = new WebSocket('wss://dashcaddy-host/api/v1/events', {
+  headers: { Authorization: 'Bearer ' + process.env.DC_TOKEN },
+});
+
+ws.on('message', (data) => {
+  const event = JSON.parse(data);
+  console.log(event.type, event.payload);
+});`}
+

+ Common event types you will see on the channel: +

+ + + + + + + + + + + + + + + + + + + +
Event typeEmitted when
service.healthA service transitions between healthy / unhealthy / down
service.startedA container starts successfully
service.stoppedA container stops (graceful or crash)
deploy.progressA template deployment advances through its stages
deploy.completeA deployment finishes (success or failure)
dns.changedA DNS record is created, updated, or removed
proxy.updatedA Caddy route is applied or removed
cert.issuedA TLS certificate is issued or renewed
fleet.hostA fleet host changes state (Premium)
audit.eventA user or API action is logged for audit

Prometheus metrics endpoint

DashCaddy exposes a Prometheus-format metrics endpoint at /metrics for service health, container - status, request counts, and system indicators. Scrape it with Prometheus and visualize in Grafana. + status, request counts, certificate expiry, and system indicators. Scrape it with Prometheus and visualize in + Grafana. See Integrations for a full scrape config.

-
{`# Health and readiness probes
-GET /healthz   # liveness — is the process up?
-GET /readyz    # readiness — is it ready to serve (deps connected)?`}
+
{`# Scrape config (prometheus.yml)
+scrape_configs:
+  - job_name: 'dashcaddy'
+    metrics_path: /metrics
+    static_configs:
+      - targets: ['dashcaddy-host:3000']
 
-        

Plugin & extension hooks

+# Sample exported metrics +dashcaddy_service_health{service="media"} 1 +dashcaddy_container_running{container="db"} 1 +dashcaddy_http_requests_total{service="wiki",code="200"} 48213 +dashcaddy_cert_expiry_days{domain="media.lab"} 87`}
+ +

Health and readiness probes

+

+ Two lightweight probes let orchestrators and load balancers check DashCaddy itself: +

+
{`# Liveness — is the process up?
+GET /healthz
+
+# Readiness — can it serve (Docker, Caddy, DNS connected)?
+GET /readyz`}
+

+ Use /healthz for container restart policies and /readyz for traffic gating. If + /readyz fails but /healthz passes, a dependency (Docker socket, Caddy Admin API, or + Technitium DNS) is unreachable — see Troubleshooting. +

+ +

Plugin & extension system

DashCaddy includes a plugin/extension system with hooks into the deployment, DNS, proxy, and monitoring pipelines. Write extensions to react to service lifecycle events, inject custom Caddy directives, emit additional metrics, or integrate third-party tools — without forking the core.

+

+ Plugins register for lifecycle hooks (e.g. onServiceDeployed, onDnsRecordCreated, + onProxyRouteApplied) and receive a context object they can act on. A plugin can modify the + generated Caddyfile before it is applied, push a notification when a service goes unhealthy, or export custom + metrics alongside the built-in ones. Plugins are loaded at startup and run in the same process. +

+ +

Structured error codes

+

+ The API and SDK return 80 structured error codes across 12 modules rather + than opaque messages, so your automation can branch on specific failure conditions — DNS token invalid, Caddy + unreachable, license expired, rate limited — instead of parsing strings. Every error response includes the + machine-readable code, the HTTP status, and a human-readable message. +

+ + + + + + + + + + + + + + + + + + + + + +
ModuleExample error codes
authAUTH_INVALID_TOKEN, AUTH_PERMISSION_DENIED, AUTH_2FA_REQUIRED
serviceSERVICE_NOT_FOUND, SERVICE_ALREADY_EXISTS, SERVICE_UNHEALTHY
deployDEPLOY_TEMPLATE_INVALID, DEPLOY_PORT_CONFLICT, DEPLOY_FAILED
dnsDNS_TOKEN_INVALID, DNS_ZONE_NOT_FOUND, DNS_RECORD_EXISTS
proxyPROXY_CADDY_UNREACHABLE, PROXY_CONFIG_INVALID, PROXY_UPSTREAM_TIMEOUT
certCERT_ISSUANCE_FAILED, CERT_EXPIRED, CERT_NOT_TRUSTED
licenseLICENSE_EXPIRED, LICENSE_INVALID, LICENSE_MACHINE_LIMIT
userUSER_NOT_FOUND, USER_ALREADY_EXISTS, USER_INVITE_EXPIRED
backupBACKUP_FAILED, BACKUP_CORRUPT, RESTORE_CONFLICT
recipeRECIPE_INVALID, RECIPE_COMPONENT_FAILED (Premium)
swarmSWARM_NOT_INITIALIZED, SWARM_NODE_UNREACHABLE (Premium)
fleetFLEET_HOST_OFFLINE, FLEET_DEPLOY_PLAN_FAILED (Premium)
+

+ Handle errors by code in your automation: +

+
{`try {
+  await dc.services.deploy({ template: 'postgres', name: 'db', hostname: 'db.lab' });
+} catch (err) {
+  if (err.code === 'DEPLOY_PORT_CONFLICT') {
+    // pick a different port and retry
+  } else if (err.code === 'LICENSE_EXPIRED') {
+    // alert ops to renew
+  } else {
+    throw err; // unknown — surface to the operator
+  }
+}`}

Why automation matters

- DashCaddy can execute the full infrastructure chain around a service, not just report its state after the - fact. Between the REST API, the JS SDK, the AI Intent Router, MCP, WebSockets, Prometheus, and the plugin - system, you have every surface you need to make DashCaddy a first-class citizen of your automation stack. + DashCaddy can execute the full infrastructure chain around a service, not just report its state after the fact. + Between the REST API, the JS SDK, the AI Intent Router, MCP, WebSockets, Prometheus, and the plugin system, you + have every surface you need to make DashCaddy a first-class citizen of your automation stack. Start with a + simple curl call, graduate to the SDK, and add AI and event-driven flows as your needs grow. +

+

+ For the infrastructure that backs all of this, see Integrations. When things go + wrong, the Troubleshooting guide walks each layer with commands and fixes.