Repository navigation
Feature Guide REST API
Programmatic access to all Caddy Proxy Manager resources via a REST API.
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.
The API supports two authentication methods:
curl -H "Authorization: Bearer <your-api-token>" \
https://your-instance:3000/api/v1/proxy-hostsIf you are already logged in via the web UI, API requests from the same browser session are authenticated automatically.
Manage tokens from the API Tokens page (/api-tokens) or the Profile page.
- Go to API Tokens or Profile.
- Enter a name and optional expiration date.
- Click Create.
- Copy the token immediately -- it is shown only once.
| 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.
| 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.
(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/:idchanges an instance'sname,baseUrl,apiTokenorenabledflag; 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. AbaseUrlthat points to a different sync endpoint, likeDELETE, removes the old URL's pin unless another instance orINSTANCE_SLAVESentry still uses that URL. Base URLs must behttporhttpswith 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), ornulluntil a sync pins one. -
PUT /api/v1/instances/:id/sync-key-pinwith{"publicKey":"<base64>"}pins the slave's key by hand (sourcemanual), replacing any pin.DELETEon the same path resets the pin, so the next sync pins whatever key the slave presents; it returns404when nothing is pinned. -
GET /api/v1/instances/sync-key-pinslists every pin with its normalizedurland the instances andINSTANCE_SLAVESentries that use it (slaves).PUTandDELETEwith?url=<slave base URL>pin or reset by URL, forINSTANCE_SLAVESentries, slaves not added yet, and pins no slave uses. Withouturlthey return400"The url query parameter is required". -
GET /api/v1/instances/sync-keyreturns 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 | jqRead the slave's key over a channel you trust, not through the sync connection.
-
GET /api/v1/users,GET /api/v1/users/:idandPUT /api/v1/users/:idresponses includeusername, the user's sign-in username (since the release after v1.12.0). They never include the password hash. -
POST /api/v1/usersapplies 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 gets400with the missing requirements, e.g.{"error":"Password must be at least 12 characters long, must include at least one number"}. -
DELETE /api/v1/users/:idalso 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.
-
DNS provider credentials saved through
PUT /api/v1/settings/dns-providerare stored encrypted, as the dashboard form stores them, and so is the token of the legacycloudflaregroup (since the release after v1.12.0). Credentials that older releases stored in plaintext are encrypted on startup, logged asEncrypted N DNS provider credential(s) that were stored in plaintext.GETresponses only list which credential fields are set. -
WAF custom directives.
PUT /api/v1/settings/waf, and proxy host saves withwafsettings, 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.
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.
curl -s -H "Authorization: Bearer $TOKEN" \
https://your-instance:3000/api/v1/proxy-hosts | jqcurl -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 | jqcurl -s -X POST -H "Authorization: Bearer $TOKEN" \
https://your-instance:3000/api/v1/caddy/apply | jqcurl -s -H "Authorization: Bearer $TOKEN" \
https://your-instance:3000/api/v1/settings/general | jq- Environment Variables Reference
- Feature Guide Proxy Hosts
- Feature Guide Forward Auth - Forward auth session and access endpoints
- Feature Guide User Management - User and group management endpoints
- Feature Guide Instance Sync - Instance and sync key pin endpoints
- Feature Guide WAF - WAF settings and custom directives
- Feature Guide mTLS RBAC - mTLS role and access rule endpoints
- Security Configuration
Need help? Open an issue with the request/response details (redact tokens and sensitive data).