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 v1.13.1, 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 v1.13.1.
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 v1.13.1)
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 v1.13.1), ornullwhen the account has none. They never include the password hash. -
POST /api/v1/usersapplies the password policy (since v1.13.1): 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 v1.13.1).
Sign-in usernames (since v1.13.1):
-
"username"inPUT /api/v1/users/:id(admin only, also for your own account) sets the user's sign-in username.POST /api/v1/usersaccepts it too; without it, the new user gets their email address as username only when that address is a valid username no other account uses, and no username otherwise. CPM no longer makes a username up from the email address. - A username must be 3–255 characters of lowercase letters (
a-z), digits and_ . @ -(surrounding whitespace is removed), and must not be another account's username, email address or forward-auth portal name (the<name>of an email<name>@localhost), ignoring case. Otherwise the request gets400, e.g.{"error":"Username must be 3-255 characters long and use only lowercase letters (a-z), digits and the characters _ . @ -"}or{"error":"Another account already signs in with this name or has it as its email address"}. -
"username": null, or nousername, leaves the username unchanged, so aGETresponse can be sent back as it is. Sending the username the user already has is no change either. - Changing
emailleavesusernameunchanged. An email address that is another account's email or username (for a@localhostaddress, also when the part before@localhostis another account's username) gets400with the reason. - A request refused with
400changes nothing:PUTdoes not applyroleorstatuseither, andPOSTcreates no user. - A changed username is recorded in the audit log as
Changed user <id> sign-in username to <username>.
# Set the sign-in username of user 5
curl -s -X PUT -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"username": "alice"}' \
https://your-instance:3000/api/v1/users/5 | jqSee Feature Guide User Management#sign-in-usernames.
-
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 v1.13.1). 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 v1.13.1). 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).