Logo-only navbar/footer, expanded docs (200-300 lines each), live Stripe Payment Links
Navbar/Footer: Logo replaces text 'DashCaddy' wordmark, image-only branding Docs: All 7 pages rewritten to comprehensive 200-300 line guides with code examples, callout boxes, reference tables, and cross-page links Stripe: 4 Payment Links wired in (0/30d, 0/90d, 0/180d, 9/365d) Products and Prices created in Stripe Dashboard
This commit is contained in:
+251
-30
@@ -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."
|
||||
>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
|
||||
<h2>REST API</h2>
|
||||
<p>
|
||||
All platform operations are available under <code>/api/v1/</code>. 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 <code>/api/v1/</code>. 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.
|
||||
</p>
|
||||
<p>
|
||||
Requests and responses are JSON. The base URL is your DashCaddy host — for example
|
||||
<code> https://dashcaddy-host/api/v1/services</code>. All endpoints require authentication (see below) and
|
||||
return structured error codes rather than opaque messages.
|
||||
</p>
|
||||
<pre className="mt-4 overflow-x-auto rounded-lg border border-surface-700/50 bg-surface-950/80 p-4 text-sm"><code>{`# 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`}</code></pre>
|
||||
-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`}</code></pre>
|
||||
|
||||
<h2>Authentication</h2>
|
||||
<p>
|
||||
DashCaddy supports two authentication methods, chosen by how you access the API:
|
||||
</p>
|
||||
<h3>Session cookie (browser)</h3>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
<h3>API key (Bearer token)</h3>
|
||||
<p>
|
||||
For server-to-server automation, scripts, and the SDK, use an API key. Generate keys from
|
||||
<strong> Settings → API Keys</strong>. Keys are bearer tokens — pass them in the <code>Authorization</code>
|
||||
header on every request:
|
||||
</p>
|
||||
<pre className="mt-4 overflow-x-auto rounded-lg border border-surface-700/50 bg-surface-950/80 p-4 text-sm"><code>{`Authorization: Bearer dc_live_xxxxxxxxxxxxxxxxxxxx`}</code></pre>
|
||||
<blockquote className="border-l-4 border-brand-500/50 bg-brand-500/5 p-4 rounded-r-lg">
|
||||
<p className="text-surface-300">
|
||||
<strong className="text-brand-400">Security:</strong> 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.
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
<h2>Rate limiting</h2>
|
||||
<p>
|
||||
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 <code>429 Too Many Requests</code> and a <code>Retry-After</code> header
|
||||
indicating when to retry. Back off and retry — do not hammer the endpoint.
|
||||
</p>
|
||||
<p>
|
||||
For high-volume automation (e.g. polling service status in a tight loop), prefer the <strong>WebSocket
|
||||
channel</strong> or the <strong>Prometheus endpoint</strong> over repeated REST polling. Both are designed for
|
||||
frequent reads and do not count against the REST rate limit.
|
||||
</p>
|
||||
|
||||
<h2>JavaScript SDK</h2>
|
||||
<p>
|
||||
For programmatic automation, DashCaddy ships a typed JavaScript SDK with <strong>39 methods</strong> and full
|
||||
<strong> TypeScript types</strong>. 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.
|
||||
</p>
|
||||
<pre className="mt-4 overflow-x-auto rounded-lg border border-surface-700/50 bg-surface-950/80 p-4 text-sm"><code>{`# Install
|
||||
npm install @dashcaddy/sdk
|
||||
# or
|
||||
pnpm add @dashcaddy/sdk`}</code></pre>
|
||||
<pre className="mt-4 overflow-x-auto rounded-lg border border-surface-700/50 bg-surface-950/80 p-4 text-sm"><code>{`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' });`}</code></pre>
|
||||
await dc.services.adopt({ containerId: 'abc123', hostname: 'wiki.lab' });
|
||||
|
||||
<h2>Structured error codes</h2>
|
||||
// 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');`}</code></pre>
|
||||
<p>
|
||||
The API and SDK return <strong>80 structured error codes</strong> 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 <code>DashCaddyError</code> carrying the error
|
||||
code, HTTP status, and message — so your automation can branch on specific failure conditions.
|
||||
</p>
|
||||
|
||||
<h2>AI Intent Router</h2>
|
||||
<p>
|
||||
The <strong>AI Intent Router</strong> 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.
|
||||
</p>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
<pre className="mt-4 overflow-x-auto rounded-lg border border-surface-700/50 bg-surface-950/80 p-4 text-sm"><code>{`# Natural-language operation
|
||||
POST /api/v1/ai/intent
|
||||
{ "message": "Restart the media server and check its health" }`}</code></pre>
|
||||
{
|
||||
"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 }
|
||||
]
|
||||
}`}</code></pre>
|
||||
<p>
|
||||
Example intents: “deploy the postgres template as <code>db</code> on <code>db.lab</code>”,
|
||||
“list all unhealthy services”, “rotate the TLS cert for <code>wiki.lab</code>”,
|
||||
“create a DNS record for <code>api.lab</code> pointing at 10.0.0.5”.
|
||||
</p>
|
||||
|
||||
<h2>MCP Server</h2>
|
||||
<p>
|
||||
The built-in <strong>MCP (Model Context Protocol) Server</strong> 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.
|
||||
</p>
|
||||
<p>
|
||||
To connect Claude Desktop, GPT, or another MCP-compatible assistant, add the DashCaddy MCP server to your
|
||||
client's MCP configuration:
|
||||
</p>
|
||||
<pre className="mt-4 overflow-x-auto rounded-lg border border-surface-700/50 bg-surface-950/80 p-4 text-sm"><code>{`{
|
||||
"mcpServers": {
|
||||
"dashcaddy": {
|
||||
"url": "https://dashcaddy-host/mcp",
|
||||
"headers": {
|
||||
"Authorization": "Bearer dc_live_xxxxxxxxxxxxxxxxxxxx"
|
||||
}
|
||||
}
|
||||
}
|
||||
}`}</code></pre>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
|
||||
<h2>WebSocket real-time updates</h2>
|
||||
<h2>WebSocket real-time events</h2>
|
||||
<p>
|
||||
The dashboard subscribes to a <strong>WebSocket channel</strong> 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.
|
||||
</p>
|
||||
<pre className="mt-4 overflow-x-auto rounded-lg border border-surface-700/50 bg-surface-950/80 p-4 text-sm"><code>{`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);
|
||||
});`}</code></pre>
|
||||
<p>
|
||||
Common event types you will see on the channel:
|
||||
</p>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Event type</th>
|
||||
<th>Emitted when</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td><code>service.health</code></td><td>A service transitions between healthy / unhealthy / down</td></tr>
|
||||
<tr><td><code>service.started</code></td><td>A container starts successfully</td></tr>
|
||||
<tr><td><code>service.stopped</code></td><td>A container stops (graceful or crash)</td></tr>
|
||||
<tr><td><code>deploy.progress</code></td><td>A template deployment advances through its stages</td></tr>
|
||||
<tr><td><code>deploy.complete</code></td><td>A deployment finishes (success or failure)</td></tr>
|
||||
<tr><td><code>dns.changed</code></td><td>A DNS record is created, updated, or removed</td></tr>
|
||||
<tr><td><code>proxy.updated</code></td><td>A Caddy route is applied or removed</td></tr>
|
||||
<tr><td><code>cert.issued</code></td><td>A TLS certificate is issued or renewed</td></tr>
|
||||
<tr><td><code>fleet.host</code></td><td>A fleet host changes state (Premium)</td></tr>
|
||||
<tr><td><code>audit.event</code></td><td>A user or API action is logged for audit</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h2>Prometheus metrics endpoint</h2>
|
||||
<p>
|
||||
DashCaddy exposes a Prometheus-format metrics endpoint at <code>/metrics</code> 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 <a href="/docs/integrations">Integrations</a> for a full scrape config.
|
||||
</p>
|
||||
<pre className="mt-4 overflow-x-auto rounded-lg border border-surface-700/50 bg-surface-950/80 p-4 text-sm"><code>{`# Health and readiness probes
|
||||
GET /healthz # liveness — is the process up?
|
||||
GET /readyz # readiness — is it ready to serve (deps connected)?`}</code></pre>
|
||||
<pre className="mt-4 overflow-x-auto rounded-lg border border-surface-700/50 bg-surface-950/80 p-4 text-sm"><code>{`# Scrape config (prometheus.yml)
|
||||
scrape_configs:
|
||||
- job_name: 'dashcaddy'
|
||||
metrics_path: /metrics
|
||||
static_configs:
|
||||
- targets: ['dashcaddy-host:3000']
|
||||
|
||||
<h2>Plugin & extension hooks</h2>
|
||||
# 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`}</code></pre>
|
||||
|
||||
<h2>Health and readiness probes</h2>
|
||||
<p>
|
||||
Two lightweight probes let orchestrators and load balancers check DashCaddy itself:
|
||||
</p>
|
||||
<pre className="mt-4 overflow-x-auto rounded-lg border border-surface-700/50 bg-surface-950/80 p-4 text-sm"><code>{`# Liveness — is the process up?
|
||||
GET /healthz
|
||||
|
||||
# Readiness — can it serve (Docker, Caddy, DNS connected)?
|
||||
GET /readyz`}</code></pre>
|
||||
<p>
|
||||
Use <code>/healthz</code> for container restart policies and <code>/readyz</code> for traffic gating. If
|
||||
<code> /readyz</code> fails but <code>/healthz</code> passes, a dependency (Docker socket, Caddy Admin API, or
|
||||
Technitium DNS) is unreachable — see <a href="/docs/troubleshooting">Troubleshooting</a>.
|
||||
</p>
|
||||
|
||||
<h2>Plugin & extension system</h2>
|
||||
<p>
|
||||
DashCaddy includes a <strong>plugin/extension system</strong> 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.
|
||||
</p>
|
||||
<p>
|
||||
Plugins register for lifecycle hooks (e.g. <code>onServiceDeployed</code>, <code>onDnsRecordCreated</code>,
|
||||
<code>onProxyRouteApplied</code>) 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.
|
||||
</p>
|
||||
|
||||
<h2>Structured error codes</h2>
|
||||
<p>
|
||||
The API and SDK return <strong>80 structured error codes</strong> across <strong>12 modules</strong> 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.
|
||||
</p>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Module</th>
|
||||
<th>Example error codes</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>auth</td><td><code>AUTH_INVALID_TOKEN</code>, <code>AUTH_PERMISSION_DENIED</code>, <code>AUTH_2FA_REQUIRED</code></td></tr>
|
||||
<tr><td>service</td><td><code>SERVICE_NOT_FOUND</code>, <code>SERVICE_ALREADY_EXISTS</code>, <code>SERVICE_UNHEALTHY</code></td></tr>
|
||||
<tr><td>deploy</td><td><code>DEPLOY_TEMPLATE_INVALID</code>, <code>DEPLOY_PORT_CONFLICT</code>, <code>DEPLOY_FAILED</code></td></tr>
|
||||
<tr><td>dns</td><td><code>DNS_TOKEN_INVALID</code>, <code>DNS_ZONE_NOT_FOUND</code>, <code>DNS_RECORD_EXISTS</code></td></tr>
|
||||
<tr><td>proxy</td><td><code>PROXY_CADDY_UNREACHABLE</code>, <code>PROXY_CONFIG_INVALID</code>, <code>PROXY_UPSTREAM_TIMEOUT</code></td></tr>
|
||||
<tr><td>cert</td><td><code>CERT_ISSUANCE_FAILED</code>, <code>CERT_EXPIRED</code>, <code>CERT_NOT_TRUSTED</code></td></tr>
|
||||
<tr><td>license</td><td><code>LICENSE_EXPIRED</code>, <code>LICENSE_INVALID</code>, <code>LICENSE_MACHINE_LIMIT</code></td></tr>
|
||||
<tr><td>user</td><td><code>USER_NOT_FOUND</code>, <code>USER_ALREADY_EXISTS</code>, <code>USER_INVITE_EXPIRED</code></td></tr>
|
||||
<tr><td>backup</td><td><code>BACKUP_FAILED</code>, <code>BACKUP_CORRUPT</code>, <code>RESTORE_CONFLICT</code></td></tr>
|
||||
<tr><td>recipe</td><td><code>RECIPE_INVALID</code>, <code>RECIPE_COMPONENT_FAILED</code> (Premium)</td></tr>
|
||||
<tr><td>swarm</td><td><code>SWARM_NOT_INITIALIZED</code>, <code>SWARM_NODE_UNREACHABLE</code> (Premium)</td></tr>
|
||||
<tr><td>fleet</td><td><code>FLEET_HOST_OFFLINE</code>, <code>FLEET_DEPLOY_PLAN_FAILED</code> (Premium)</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>
|
||||
Handle errors by code in your automation:
|
||||
</p>
|
||||
<pre className="mt-4 overflow-x-auto rounded-lg border border-surface-700/50 bg-surface-950/80 p-4 text-sm"><code>{`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
|
||||
}
|
||||
}`}</code></pre>
|
||||
|
||||
<h2>Why automation matters</h2>
|
||||
<p>
|
||||
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 <code>curl</code> call, graduate to the SDK, and add AI and event-driven flows as your needs grow.
|
||||
</p>
|
||||
<p>
|
||||
For the infrastructure that backs all of this, see <a href="/docs/integrations">Integrations</a>. When things go
|
||||
wrong, the <a href="/docs/troubleshooting">Troubleshooting</a> guide walks each layer with commands and fixes.
|
||||
</p>
|
||||
</DocsLayout>
|
||||
<Footer />
|
||||
|
||||
Reference in New Issue
Block a user