Skip to content

Feature Guide REST API

fuomag9 edited this page Sep 26, 2026 · 6 revisions

Feature Guide: REST API

Programmatic access to all Caddy Proxy Manager resources via a REST API.

Table of Contents

  1. Overview
  2. Authentication
  3. API Tokens
  4. Endpoints
  5. Endpoint Notes
  6. OpenAPI Documentation
  7. Examples

Overview

A full REST API is available under /api/v1/. It supports the same operations as the web UI: managing proxy hosts, certificates, access lists, settings, users, and more.

The interactive OpenAPI 3.1.0 specification is available at /api-docs in the web UI, or as raw JSON at /api/v1/openapi.json.


Authentication

The API supports two authentication methods:

Bearer token (recommended for automation)

curl -H "Authorization: Bearer <your-api-token>" \
  https://your-instance:3000/api/v1/proxy-hosts

Session cookie (browser)

If you are already logged in via the web UI, API requests from the same browser session are authenticated automatically.


API Tokens

Manage tokens from the API Tokens page (/api-tokens) or the Profile page.

Create a token

  1. Go to API Tokens or Profile.
  2. Enter a name and optional expiration date.
  3. Click Create.
  4. Copy the token immediately -- it is shown only once.

Token properties

Property Description
Name Human-readable label
Expiration Optional future date after which the token stops working
Last used Updated automatically (debounced to 60 seconds)

Tokens are stored as SHA-256 hashes in the database. The raw token cannot be recovered after creation.

Admin users can view and delete any token. Non-admin users can only manage their own tokens.

Since the release after v1.12.0, changing a password signs out the user's other sessions but does not revoke their API tokens; delete a token here if it may be compromised. Deleting a user deletes the tokens they created.


Endpoints

Resource Methods Path
Health GET /api/health
Tokens GET, POST, DELETE /api/v1/tokens
Proxy Hosts GET, POST, PUT, DELETE /api/v1/proxy-hosts
L4 Proxy Hosts GET, POST, PUT, DELETE /api/v1/l4-proxy-hosts
Certificates GET, POST, PUT, DELETE /api/v1/certificates
CA Certificates GET, POST, PUT, DELETE /api/v1/ca-certificates
Client Certificates GET, POST, DELETE /api/v1/client-certificates
Client Cert Roles GET /api/v1/client-certificates/:id/roles
Access Lists GET, POST, PUT, DELETE /api/v1/access-lists
Access List Entries POST, DELETE /api/v1/access-lists/:id/entries
Settings GET, PUT /api/v1/settings/:group
Instances GET, POST /api/v1/instances
Instance PUT, DELETE /api/v1/instances/:id
Instance Sync Key Pin PUT, DELETE /api/v1/instances/:id/sync-key-pin
Sync Key Pins GET, PUT, DELETE /api/v1/instances/sync-key-pins
Own Sync Key GET /api/v1/instances/sync-key
Instance Sync POST /api/v1/instances/sync
Users GET, POST, PUT, DELETE /api/v1/users
Groups GET, POST, PATCH, DELETE /api/v1/groups
Group Members POST, DELETE /api/v1/groups/:id/members
mTLS Roles GET, POST, PUT, DELETE /api/v1/mtls-roles
mTLS Role Certs POST, DELETE /api/v1/mtls-roles/:id/certificates
mTLS Access Rules GET, POST, PUT, DELETE /api/v1/proxy-hosts/:id/mtls-access-rules
Forward Auth Access GET, PUT /api/v1/proxy-hosts/:id/forward-auth-access
Forward Auth Sessions GET, DELETE /api/v1/forward-auth-sessions
Sessions GET, DELETE /api/v1/sessions
Audit Log GET /api/v1/audit-log
DNS Providers GET /api/v1/dns-providers
OAuth Providers GET, POST, PUT, DELETE /api/v1/oauth-providers
Caddy Apply POST /api/v1/caddy/apply

PUT /api/v1/instances/:id and the sync key routes (/api/v1/instances/:id/sync-key-pin, /api/v1/instances/sync-key-pins, /api/v1/instances/sync-key) are available since the release after v1.12.0.

All endpoints return JSON. Error responses use standard HTTP status codes (400, 401, 403, 404, 500) with a JSON body containing an error field; a 500 response also carries an errorId to find the matching entry in the web container log.


Endpoint Notes

Instances and sync key pins

(since the release after v1.12.0)

These endpoints are admin only. See Feature Guide Instance Sync for how sync key pinning works.

  • PUT /api/v1/instances/:id changes an instance's name, baseUrl, apiToken or enabled flag; fields left out are kept. A new token keeps the slave's sync key pin, so update an instance rather than deleting and re-adding it to change its token. A baseUrl that points to a different sync endpoint, like DELETE, removes the old URL's pin unless another instance or INSTANCE_SLAVES entry still uses that URL. Base URLs must be http or https with no credentials, query string or fragment ("Base URL must not contain a query string or fragment"). Tokens must be 32–512 characters with no leading or trailing whitespace.
  • Instance responses include syncKeyPin: the pinned key (keyId, publicKey, pinnedAt, source), or null until a sync pins one.
  • PUT /api/v1/instances/:id/sync-key-pin with {"publicKey":"<base64>"} pins the slave's key by hand (source manual), replacing any pin. DELETE on the same path resets the pin, so the next sync pins whatever key the slave presents; it returns 404 when nothing is pinned.
  • GET /api/v1/instances/sync-key-pins lists every pin with its normalized url and the instances and INSTANCE_SLAVES entries that use it (slaves). PUT and DELETE with ?url=<slave base URL> pin or reset by URL, for INSTANCE_SLAVES entries, slaves not added yet, and pins no slave uses. Without url they return 400 "The url query parameter is required".
  • GET /api/v1/instances/sync-key returns this instance's own sync key (keyId, publicKey). Call it on a slave to compare with, or pin, the key its master holds.
# On the slave: read its sync key
curl -s -H "Authorization: Bearer $SLAVE_TOKEN" \
  https://slave.example.com:3000/api/v1/instances/sync-key | jq

# On the master: pin that key for instance 3
curl -s -X PUT -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"publicKey":"<publicKey from the slave>"}' \
  https://your-instance:3000/api/v1/instances/3/sync-key-pin | jq

Read the slave's key over a channel you trust, not through the sync connection.

Users

  • GET /api/v1/users, GET /api/v1/users/:id and PUT /api/v1/users/:id responses include username, the user's sign-in username (since the release after v1.12.0). They never include the password hash.
  • POST /api/v1/users applies the password policy (since the release after v1.12.0): 12+ characters, upper- and lowercase letters, a digit and a special character. A weak password gets 400 with the missing requirements, e.g. {"error":"Password must be at least 12 characters long, must include at least one number"}.
  • DELETE /api/v1/users/:id also deletes the user's sessions, API tokens, sign-in methods, forward-auth sessions and grants, and group memberships (since the release after v1.12.0).

See Feature Guide User Management.

Settings

  • DNS provider credentials saved through PUT /api/v1/settings/dns-provider are stored encrypted, as the dashboard form stores them, and so is the token of the legacy cloudflare group (since the release after v1.12.0). Credentials that older releases stored in plaintext are encrypted on startup, logged as Encrypted N DNS provider credential(s) that were stored in plaintext. GET responses only list which credential fields are set.
  • WAF custom directives. PUT /api/v1/settings/waf, and proxy host saves with waf settings, reject only the directive lines that the save newly drops (since the release after v1.12.0). A stored line that a newer release no longer sends to Caddy does not block unrelated changes; it is left out of the generated config and reported in the web container log. See Feature Guide WAF.

OpenAPI Documentation

The interactive API docs are available at /api-docs in the web UI. This page renders the full OpenAPI 3.1.0 specification with:

  • Try-it-out functionality for all endpoints
  • Request/response schema documentation
  • Authentication configuration

The raw spec is also available at /api/v1/openapi.json for code generation tools.


Examples

List all proxy hosts

curl -s -H "Authorization: Bearer $TOKEN" \
  https://your-instance:3000/api/v1/proxy-hosts | jq

Create a proxy host

curl -s -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My App",
    "domains": ["app.example.com"],
    "upstreams": ["192.0.2.5:8080"],
    "ssl_forced": true,
    "enabled": true
  }' \
  https://your-instance:3000/api/v1/proxy-hosts | jq

Apply Caddy configuration

curl -s -X POST -H "Authorization: Bearer $TOKEN" \
  https://your-instance:3000/api/v1/caddy/apply | jq

Get settings for a group

curl -s -H "Authorization: Bearer $TOKEN" \
  https://your-instance:3000/api/v1/settings/general | jq

Related Documentation


Need help? Open an issue with the request/response details (redact tokens and sensitive data).

Clone this wiki locally