# DashCaddy API Surface > **Handler rows (method+path per route file):** 443 > **Public rows (matched by PUBLIC_ROUTES allowlist):** 88 > **Methodology:** statically derived from route declarations + the mount/composition map in the generator (lazy and composed mounts encoded from src/app.js with cited line refs). Code-derived counts are authoritative for what is DECLARED; boot-time verification lives in the MCP route-existence drift gate. > **Files scanned:** 81 > **Generated by:** `dashcaddy/scripts/api-surface-extract.py` ## Auth & Rate Limit Model - `public` = in `PUBLIC_ROUTES` (`src/utilities/middleware.js`), bypasses TOTP - `protected` = requires TOTP session OR API key/JWT - CSRF: state-changing requests need `X-CSRF-Token` matching `csrf_token` cookie - Rate limits: GENERAL 1000/15m, STRICT 20/15m (auth keys), TOTP 10/15m ## Summary by Area | Area | Routes | Public | Protected | |---|---:|---:|---:| | Other | 135 | 13 | 122 | | Authentication | 34 | 18 | 16 | | App catalog | 28 | 0 | 28 | | DNS | 20 | 0 | 20 | | Tailscale | 20 | 20 | 0 | | Monitoring | 19 | 3 | 16 | | Backups | 18 | 0 | 18 | | Logs | 17 | 0 | 17 | | Updates | 16 | 6 | 10 | | Configuration | 13 | 9 | 4 | | Health | 13 | 3 | 10 | | Services | 12 | 4 | 8 | | Containers (lifecycle) | 11 | 0 | 11 | | Core / system | 9 | 6 | 3 | | Dependencies | 8 | 0 | 8 | | Notifications | 8 | 0 | 8 | | App recipes | 8 | 0 | 8 | | Docker resources | 7 | 0 | 7 | | Caddy / sites | 7 | 0 | 7 | | Certificate authority | 6 | 3 | 3 | | Updates / workflows | 6 | 0 | 6 | | Auto-restart | 5 | 0 | 5 | | OpenClaw integration | 5 | 0 | 5 | | Config drift | 4 | 0 | 4 | | Licensing | 4 | 2 | 2 | | File browser | 3 | 0 | 3 | | Theming | 3 | 1 | 2 | | Service credentials | 2 | 0 | 2 | | Events | 2 | 0 | 2 | | **TOTAL** | **443** | **88** | **355** | ## Other _135 routes_ | Method | Full path | Auth | Rate limit | Defined in | |---|---|---|---|---| | GET | `/api/v1/ai/capabilities` | protected | GENERAL (1000/15m) | `routes/ai-intent.js:681` | | POST | `/api/v1/ai/intent` | protected | GENERAL (1000/15m) | `routes/ai-intent.js:569` | | DELETE | `/api/v1/ai/settings` | protected | GENERAL (1000/15m) | `routes/ai-intent.js:642` | | GET | `/api/v1/ai/settings` | protected | GENERAL (1000/15m) | `routes/ai-intent.js:597` | | PUT | `/api/v1/ai/settings` | protected | GENERAL (1000/15m) | `routes/ai-intent.js:614` | | POST | `/api/v1/ai/settings/test` | protected | GENERAL (1000/15m) | `routes/ai-intent.js:652` | | DELETE | `/api/v1/audit-logs` | protected | GENERAL (1000/15m) | `routes/audit-log.js:176` | | GET | `/api/v1/audit-logs` | protected | GENERAL (1000/15m) | `routes/audit-log.js:63` | | GET | `/api/v1/audit-logs/actions` | protected | GENERAL (1000/15m) | `routes/audit-log.js:148` | | POST | `/api/v1/billing/checkout` | public | GENERAL (1000/15m) | `routes/billing.js:143` | | GET | `/api/v1/billing/lookup/:sessionId` | public | GENERAL (1000/15m) | `routes/billing.js:184` | | GET | `/api/v1/caddy/upstreams` | protected | GENERAL (1000/15m) | `routes/caddy-upstreams.js:66` | | POST | `/api/v1/caddy/upstreams/:host/mute` | protected | GENERAL (1000/15m) | `routes/caddy-upstreams.js:120` | | POST | `/api/v1/caddy/upstreams/:host/unmute` | protected | GENERAL (1000/15m) | `routes/caddy-upstreams.js:133` | | GET | `/api/v1/caddy/upstreams/incidents` | protected | GENERAL (1000/15m) | `routes/caddy-upstreams.js:80` | | POST | `/api/v1/caddy/upstreams/mute` | protected | GENERAL (1000/15m) | `routes/caddy-upstreams.js:107` | | POST | `/api/v1/caddycode/generate` | protected | GENERAL (1000/15m) | `routes/caddycode.js:244` | | GET | `/api/v1/caddycode/templates` | protected | GENERAL (1000/15m) | `routes/caddycode.js:320` | | POST | `/api/v1/caddycode/validate` | protected | GENERAL (1000/15m) | `routes/caddycode.js:276` | | POST | `/api/v1/calendar/discover` | protected | GENERAL (1000/15m) | `routes/calendar.js:280` | | GET | `/api/v1/calendar/events` | protected | GENERAL (1000/15m) | `routes/calendar.js:176` | | POST | `/api/v1/calendar/radicale/provision` | protected | GENERAL (1000/15m) | `routes/calendar.js:234` | | GET | `/api/v1/calendar/sources` | protected | GENERAL (1000/15m) | `routes/calendar.js:99` | | POST | `/api/v1/calendar/sources` | protected | GENERAL (1000/15m) | `routes/calendar.js:105` | | DELETE | `/api/v1/calendar/sources/:id` | protected | GENERAL (1000/15m) | `routes/calendar.js:166` | | PUT | `/api/v1/calendar/sources/:id` | protected | GENERAL (1000/15m) | `routes/calendar.js:131` | | GET | `/api/v1/capabilities` | public | GENERAL (1000/15m) | `routes/capabilities.js:38` | | GET | `/api/v1/catalog` | protected | GENERAL (1000/15m) | `routes/catalog.js:52` | | GET | `/api/v1/catalog/:appId` | protected | GENERAL (1000/15m) | `routes/catalog.js:102` | | GET | `/api/v1/catalog/search` | protected | GENERAL (1000/15m) | `routes/catalog.js:82` | | GET | `/api/v1/deploys/catalog/apps` | protected | GENERAL (1000/15m) | `routes/deploys.js:101` | | POST | `/api/v1/deploys/catalog/deploy` | protected | GENERAL (1000/15m) | `routes/deploys.js:113` | | POST | `/api/v1/deploys/deploy` | protected | GENERAL (1000/15m) | `routes/deploys.js:244` | | POST | `/api/v1/deploys/gitea-repos` | protected | GENERAL (1000/15m) | `routes/deploys.js:358` | | POST | `/api/v1/deploys/install` | protected | GENERAL (1000/15m) | `routes/deploys.js:300` | | GET | `/api/v1/deploys/journal` | protected | GENERAL (1000/15m) | `routes/deploys.js:197` | | GET | `/api/v1/deploys/repos` | protected | GENERAL (1000/15m) | `routes/deploys.js:181` | | POST | `/api/v1/deploys/rollback` | protected | GENERAL (1000/15m) | `routes/deploys.js:271` | | GET | `/api/v1/deploys/services` | protected | GENERAL (1000/15m) | `routes/deploys.js:189` | | GET | `/api/v1/deploys/status` | protected | GENERAL (1000/15m) | `routes/deploys.js:210` | | POST | `/api/v1/disaster/backup` | protected | GENERAL (1000/15m) | `routes/disaster-recovery.js:135` | | POST | `/api/v1/disaster/restore` | protected | GENERAL (1000/15m) | `routes/disaster-recovery.js:223` | | GET | `/api/v1/disaster/status` | protected | GENERAL (1000/15m) | `routes/disaster-recovery.js:410` | | GET | `/api/v1/discover` | protected | GENERAL (1000/15m) | `routes/discover.js:45` | | POST | `/api/v1/discover/adopt` | protected | GENERAL (1000/15m) | `routes/discover-adopt.js:39` | | GET | `/api/v1/disk-settings/` | protected | GENERAL (1000/15m) | `routes/disk-settings.js:13` | | POST | `/api/v1/disk-settings/` | protected | GENERAL (1000/15m) | `routes/disk-settings.js:54` | | POST | `/api/v1/disk-settings/cleanup` | protected | GENERAL (1000/15m) | `routes/disk-settings.js:92` | | GET | `/api/v1/disk/` | protected | GENERAL (1000/15m) | `routes/disk-space.js:88` | | GET | `/api/v1/disk/breakdown` | protected | GENERAL (1000/15m) | `routes/disk-space.js:94` | | POST | `/api/v1/disk/cleanup` | protected | GENERAL (1000/15m) | `routes/disk-space.js:130` | | GET | `/api/v1/disk/config` | protected | GENERAL (1000/15m) | `routes/disk-space.js:100` | | POST | `/api/v1/disk/config` | protected | GENERAL (1000/15m) | `routes/disk-space.js:105` | | POST | `/api/v1/fleet/deploy` | protected | GENERAL (1000/15m) | `routes/fleet.js:311` | | GET | `/api/v1/fleet/hosts` | protected | GENERAL (1000/15m) | `routes/fleet.js:136` | | POST | `/api/v1/fleet/hosts` | protected | GENERAL (1000/15m) | `routes/fleet.js:142` | | DELETE | `/api/v1/fleet/hosts/:hostId` | protected | GENERAL (1000/15m) | `routes/fleet.js:223` | | GET | `/api/v1/fleet/status` | protected | GENERAL (1000/15m) | `routes/fleet.js:246` | | GET | `/api/v1/i18n/languages` | public | GENERAL (1000/15m) | `routes/i18n.js:16` | | GET | `/api/v1/i18n/translations/:lang` | public | GENERAL (1000/15m) | `routes/i18n.js:28` | | GET | `/api/v1/log-insights` | protected | GENERAL (1000/15m) | `routes/log-insights.js:103` | | POST | `/api/v1/log-insights/dispose` | protected | GENERAL (1000/15m) | `routes/log-insights.js:222` | | DELETE | `/api/v1/mcp/` | protected | GENERAL (1000/15m) | `routes/mcp.js:276` | | GET | `/api/v1/mcp/` | protected | GENERAL (1000/15m) | `routes/mcp.js:266` | | POST | `/api/v1/mcp/` | protected | GENERAL (1000/15m) | `routes/mcp.js:165` | | POST | `/api/v1/mcp/config` | protected | GENERAL (1000/15m) | `routes/mcp.js:315` | | GET | `/api/v1/mcp/connections` | protected | GENERAL (1000/15m) | `routes/mcp.js:302` | | GET | `/api/v1/mcp/info` | protected | GENERAL (1000/15m) | `routes/mcp.js:285` | | GET | `/api/v1/network/access/` | protected | GENERAL (1000/15m) | `routes/network-access.js:79` | | PUT | `/api/v1/network/access/` | protected | GENERAL (1000/15m) | `routes/network-access.js:85` | | GET | `/api/v1/network/access/effective/:principalType/:principalId` | protected | GENERAL (1000/15m) | `routes/network-access.js:135` | | DELETE | `/api/v1/network/access/grant` | protected | GENERAL (1000/15m) | `routes/network-access.js:116` | | POST | `/api/v1/network/access/grant` | protected | GENERAL (1000/15m) | `routes/network-access.js:101` | | POST | `/api/v1/network/devices/:id/revoke` | protected | GENERAL (1000/15m) | `routes/network-lifecycle.js:92` | | GET | `/api/v1/network/forward-auth/` | public | GENERAL (1000/15m) | `routes/network-forward-auth.js:134` | | POST | `/api/v1/network/forward-auth/` | public | GENERAL (1000/15m) | `routes/network-forward-auth.js:135` | | GET | `/api/v1/network/groups/` | protected | GENERAL (1000/15m) | `routes/network-groups.js:67` | | POST | `/api/v1/network/groups/` | protected | GENERAL (1000/15m) | `routes/network-groups.js:72` | | DELETE | `/api/v1/network/groups/:id` | protected | GENERAL (1000/15m) | `routes/network-groups.js:90` | | PATCH | `/api/v1/network/groups/:id` | protected | GENERAL (1000/15m) | `routes/network-groups.js:81` | | GET | `/api/v1/network/invites/` | protected | GENERAL (1000/15m) | `routes/network-invites.js:161` | | POST | `/api/v1/network/invites/` | protected | GENERAL (1000/15m) | `routes/network-invites.js:179` | | DELETE | `/api/v1/network/invites/:id` | protected | GENERAL (1000/15m) | `routes/network-invites.js:246` | | GET | `/api/v1/network/people/` | protected | GENERAL (1000/15m) | `routes/network-people.js:60` | | POST | `/api/v1/network/people/` | protected | GENERAL (1000/15m) | `routes/network-people.js:73` | | DELETE | `/api/v1/network/people/:id` | protected | GENERAL (1000/15m) | `routes/network-people.js:125` | | GET | `/api/v1/network/people/:id` | protected | GENERAL (1000/15m) | `routes/network-people.js:65` | | PATCH | `/api/v1/network/people/:id` | protected | GENERAL (1000/15m) | `routes/network-people.js:101` | | POST | `/api/v1/network/people/:id/block` | protected | GENERAL (1000/15m) | `routes/network-lifecycle.js:74` | | POST | `/api/v1/network/people/:id/remove` | protected | GENERAL (1000/15m) | `routes/network-lifecycle.js:87` | | POST | `/api/v1/network/people/:id/unblock` | protected | GENERAL (1000/15m) | `routes/network-lifecycle.js:79` | | POST | `/api/v1/network/people/sync` | protected | GENERAL (1000/15m) | `routes/network-people.js:151` | | GET | `/api/v1/network/resources/` | protected | GENERAL (1000/15m) | `routes/network-resources.js:63` | | POST | `/api/v1/network/resources/` | protected | GENERAL (1000/15m) | `routes/network-resources.js:74` | | DELETE | `/api/v1/network/resources/:name` | protected | GENERAL (1000/15m) | `routes/network-resources.js:93` | | GET | `/api/v1/network/resources/:name` | protected | GENERAL (1000/15m) | `routes/network-resources.js:68` | | PATCH | `/api/v1/network/resources/:name` | protected | GENERAL (1000/15m) | `routes/network-resources.js:84` | | GET | `/api/v1/network/wg/:token` | protected | GENERAL (1000/15m) | `routes/network-wg-redeem.js:278` | | POST | `/api/v1/network/wg/:token` | protected | GENERAL (1000/15m) | `routes/network-wg-redeem.js:288` | | GET | `/api/v1/network/wizard/` | protected | GENERAL (1000/15m) | `routes/network-wizard.js:207` | | POST | `/api/v1/network/wizard/admin` | protected | GENERAL (1000/15m) | `routes/network-wizard.js:160` | | POST | `/api/v1/network/wizard/ca` | protected | GENERAL (1000/15m) | `routes/network-wizard.js:149` | | POST | `/api/v1/network/wizard/complete` | protected | GENERAL (1000/15m) | `routes/network-wizard.js:171` | | POST | `/api/v1/network/wizard/connect` | protected | GENERAL (1000/15m) | `routes/network-wizard.js:127` | | POST | `/api/v1/network/wizard/dns` | protected | GENERAL (1000/15m) | `routes/network-wizard.js:138` | | POST | `/api/v1/network/wizard/domain` | protected | GENERAL (1000/15m) | `routes/network-wizard.js:116` | | POST | `/api/v1/network/wizard/mode` | protected | GENERAL (1000/15m) | `routes/network-wizard.js:105` | | GET | `/api/v1/network/wizard/state` | protected | GENERAL (1000/15m) | `routes/network-wizard.js:99` | | GET | `/api/v1/network/wizard/status` | protected | GENERAL (1000/15m) | `routes/network-wizard.js:182` | | GET | `/api/v1/security/events` | protected | GENERAL (1000/15m) | `routes/security.js:52` | | GET | `/api/v1/security/events/:id` | protected | GENERAL (1000/15m) | `routes/security.js:207` | | POST | `/api/v1/security/events/batch` | public | GENERAL (1000/15m) | `routes/security.js:235` | | POST | `/api/v1/security/events/ingest` | public | GENERAL (1000/15m) | `routes/security.js:216` | | GET | `/api/v1/security/events/perimeter` | protected | GENERAL (1000/15m) | `routes/security.js:96` | | GET | `/api/v1/security/events/stats` | protected | GENERAL (1000/15m) | `routes/security.js:71` | | GET | `/api/v1/security/events/stream` | protected | GENERAL (1000/15m) | `routes/security.js:176` | | GET | `/api/v1/security/hosts` | protected | GENERAL (1000/15m) | `routes/security.js:262` | | POST | `/api/v1/security/hosts` | protected | GENERAL (1000/15m) | `routes/security.js:267` | | DELETE | `/api/v1/security/hosts/:id` | protected | GENERAL (1000/15m) | `routes/security.js:294` | | GET | `/api/v1/security/hosts/:id` | protected | GENERAL (1000/15m) | `routes/security.js:280` | | PATCH | `/api/v1/security/hosts/:id` | protected | GENERAL (1000/15m) | `routes/security.js:287` | | GET | `/api/v1/security/hosts/:id/health` | protected | GENERAL (1000/15m) | `routes/security.js:305` | | POST | `/api/v1/security/hosts/:id/rotate-key` | protected | GENERAL (1000/15m) | `routes/security.js:335` | | GET | `/api/v1/share` | protected | GENERAL (1000/15m) | `routes/share.js:287` | | POST | `/api/v1/share` | protected | GENERAL (1000/15m) | `routes/share.js:147` | | DELETE | `/api/v1/share/:id` | protected | GENERAL (1000/15m) | `routes/share.js:292` | | GET | `/api/v1/share/:token/preview` | public | GENERAL (1000/15m) | `routes/share.js:328` | | POST | `/api/v1/share/:token/redeem-tailscale` | public | GENERAL (1000/15m) | `routes/share.js:367` | | POST | `/api/v1/share/:token/subscribe` | public | GENERAL (1000/15m) | `routes/share.js:345` | | POST | `/api/v1/share/tailscale` | protected | GENERAL (1000/15m) | `routes/share.js:183` | | GET | `/api/v1/shield` | protected | GENERAL (1000/15m) | `routes/shield.js:108` | | GET | `/api/v1/version` | public | GENERAL (1000/15m) | `routes/version.js:30` | | POST | `/api/v1/wizard/apply` | protected | GENERAL (1000/15m) | `routes/wizard.js:146` | | GET | `/api/v1/wizard/categories` | protected | GENERAL (1000/15m) | `routes/wizard.js:76` | | POST | `/api/v1/wizard/recommend` | protected | GENERAL (1000/15m) | `routes/wizard.js:88` | ## Authentication _34 routes_ | Method | Full path | Auth | Rate limit | Defined in | |---|---|---|---|---| | GET | `/api/v1/auth/admin/allowlist` | protected | GENERAL (1000/15m) | `routes/auth/admin.js:200` | | GET | `/api/v1/auth/admin/invites` | protected | GENERAL (1000/15m) | `routes/auth/admin.js:207` | | POST | `/api/v1/auth/admin/invites` | protected | GENERAL (1000/15m) | `routes/auth/admin.js:212` | | DELETE | `/api/v1/auth/admin/invites/:id` | protected | GENERAL (1000/15m) | `routes/auth/admin.js:287` | | GET | `/api/v1/auth/admin/users` | protected | GENERAL (1000/15m) | `routes/auth/admin.js:146` | | POST | `/api/v1/auth/admin/users` | protected | GENERAL (1000/15m) | `routes/auth/admin.js:151` | | DELETE | `/api/v1/auth/admin/users/:id` | protected | GENERAL (1000/15m) | `routes/auth/admin.js:186` | | PATCH | `/api/v1/auth/admin/users/:id` | protected | GENERAL (1000/15m) | `routes/auth/admin.js:172` | | GET | `/api/v1/auth/app-token/:serviceId` | public | STRICT (20/15m) | `routes/auth/sso-gate.js:105` | | POST | `/api/v1/auth/disable/:provider` | public | GENERAL (1000/15m) | `routes/auth/login.js:102` | | GET | `/api/v1/auth/gate/:serviceId` | public | STRICT (20/15m) | `routes/auth/sso-gate.js:27` | | GET | `/api/v1/auth/invites/:token` | public | GENERAL (1000/15m) | `routes/auth/admin.js:296` | | POST | `/api/v1/auth/invites/:token/accept` | public | GENERAL (1000/15m) | `routes/auth/admin.js:315` | | POST | `/api/v1/auth/jwt` | protected | STRICT (20/15m) | `routes/auth/keys.js:103` | | GET | `/api/v1/auth/keys` | protected | STRICT (20/15m) | `routes/auth/keys.js:36` | | POST | `/api/v1/auth/keys` | protected | STRICT (20/15m) | `routes/auth/keys.js:47` | | DELETE | `/api/v1/auth/keys/:keyId` | protected | STRICT (20/15m) | `routes/auth/keys.js:81` | | GET | `/api/v1/auth/login-page` | public | GENERAL (1000/15m) | `routes/auth/sso-gate.js:270` | | POST | `/api/v1/auth/login/:provider/initiate` | public | GENERAL (1000/15m) | `routes/auth/login.js:57` | | POST | `/api/v1/auth/login/:provider/verify` | public | GENERAL (1000/15m) | `routes/auth/login.js:74` | | GET | `/api/v1/auth/login/methods` | public | GENERAL (1000/15m) | `routes/auth/login.js:49` | | GET | `/api/v1/auth/login/recovery-info` | public | GENERAL (1000/15m) | `routes/auth/login.js:88` | | GET | `/api/v1/auth/me` | protected | GENERAL (1000/15m) | `routes/auth/admin.js:112` | | GET | `/api/v1/auth/me` | protected | GENERAL (1000/15m) | `routes/auth/index.js:158` | | GET | `/api/v1/auth/sso-exchange` | public | GENERAL (1000/15m) | `routes/auth/sso-gate.js:245` | | GET | `/api/v1/auth/sso-handoff` | protected | GENERAL (1000/15m) | `routes/auth/sso-gate.js:221` | | GET | `/api/v1/totp/check-session` | public | TOTP (10/15m) | `routes/auth/totp.js:246` | | GET | `/api/v1/totp/config` | public | TOTP (10/15m) | `routes/auth/totp.js:31` | | POST | `/api/v1/totp/config` | public | TOTP (10/15m) | `routes/auth/totp.js:307` | | POST | `/api/v1/totp/disable` | protected | TOTP (10/15m) | `routes/auth/totp.js:274` | | GET | `/api/v1/totp/recovery-info` | public | TOTP (10/15m) | `routes/auth/totp.js:57` | | POST | `/api/v1/totp/setup` | public | TOTP (10/15m) | `routes/auth/totp.js:117` | | POST | `/api/v1/totp/verify` | public | TOTP (10/15m) | `routes/auth/totp.js:195` | | POST | `/api/v1/totp/verify-setup` | public | TOTP (10/15m) | `routes/auth/totp.js:158` | ## App catalog _28 routes_ | Method | Full path | Auth | Rate limit | Defined in | |---|---|---|---|---| | DELETE | `/api/v1/apps/:appId` | protected | GENERAL (1000/15m) | `routes/apps/removal.js:39` | | GET | `/api/v1/apps/:appId/backup-points` | protected | GENERAL (1000/15m) | `routes/apps/restore.js:133` | | POST | `/api/v1/apps/:appId/restore` | protected | GENERAL (1000/15m) | `routes/apps/restore.js:40` | | POST | `/api/v1/apps/:appId/revert/:filename` | protected | GENERAL (1000/15m) | `routes/apps/restore.js:187` | | POST | `/api/v1/apps/check-existing` | protected | GENERAL (1000/15m) | `routes/apps/deploy.js:242` | | DELETE | `/api/v1/apps/compose-stack/:stackName` | protected | GENERAL (1000/15m) | `routes/apps/compose.js:308` | | POST | `/api/v1/apps/deploy` | protected | GENERAL (1000/15m) | `routes/apps/deploy.js:255` | | POST | `/api/v1/apps/deploy-compose` | protected | GENERAL (1000/15m) | `routes/apps/compose.js:170` | | POST | `/api/v1/apps/import-compose` | protected | GENERAL (1000/15m) | `routes/apps/compose.js:159` | | GET | `/api/v1/apps/ports/:basePort/suggest` | protected | GENERAL (1000/15m) | `routes/apps/templates.js:77` | | GET | `/api/v1/apps/ports/:port/check` | protected | GENERAL (1000/15m) | `routes/apps/templates.js:65` | | POST | `/api/v1/apps/restore-all` | protected | GENERAL (1000/15m) | `routes/apps/restore.js:60` | | GET | `/api/v1/apps/restore-status` | protected | GENERAL (1000/15m) | `routes/apps/restore.js:99` | | GET | `/api/v1/apps/templates` | protected | GENERAL (1000/15m) | `routes/apps/templates.js:45` | | GET | `/api/v1/apps/templates/:appId` | protected | GENERAL (1000/15m) | `routes/apps/templates.js:54` | | POST | `/api/v1/apps/update-subdomain` | protected | GENERAL (1000/15m) | `routes/apps/templates.js:91` | | POST | `/api/v1/arr/auto-setup` | protected | GENERAL (1000/15m) | `routes/arr/config.js:282` | | POST | `/api/v1/arr/configure-overseerr` | protected | GENERAL (1000/15m) | `routes/arr/config.js:27` | | GET | `/api/v1/arr/credentials` | protected | GENERAL (1000/15m) | `routes/arr/credentials.js:109` | | POST | `/api/v1/arr/credentials` | protected | GENERAL (1000/15m) | `routes/arr/credentials.js:21` | | DELETE | `/api/v1/arr/credentials/:service` | protected | GENERAL (1000/15m) | `routes/arr/credentials.js:134` | | GET | `/api/v1/arr/detect` | protected | GENERAL (1000/15m) | `routes/arr/detect.js:20` | | GET | `/api/v1/arr/quality-profiles` | protected | GENERAL (1000/15m) | `routes/arr/config.js:499` | | POST | `/api/v1/arr/quality-profiles` | protected | GENERAL (1000/15m) | `routes/arr/config.js:568` | | POST | `/api/v1/arr/smart-connect` | protected | GENERAL (1000/15m) | `routes/arr/smart-connect.js:26` | | GET | `/api/v1/arr/smart-detect` | protected | GENERAL (1000/15m) | `routes/arr/detect.js:78` | | POST | `/api/v1/arr/test-connection` | protected | GENERAL (1000/15m) | `routes/arr/config.js:208` | | GET | `/api/v1/plex/libraries` | protected | GENERAL (1000/15m) | `routes/arr/plex.js:26` | ## DNS _20 routes_ | Method | Full path | Auth | Rate limit | Defined in | |---|---|---|---|---| | GET | `/api/v1/dns/check-update` | protected | GENERAL (1000/15m) | `routes/dns.js:684` | | DELETE | `/api/v1/dns/credentials` | protected | GENERAL (1000/15m) | `routes/dns.js:612` | | POST | `/api/v1/dns/credentials` | protected | GENERAL (1000/15m) | `routes/dns.js:505` | | GET | `/api/v1/dns/logs` | protected | GENERAL (1000/15m) | `routes/dns.js:352` | | GET | `/api/v1/dns/propagation` | protected | GENERAL (1000/15m) | `routes/dns.js:828` | | GET | `/api/v1/dns/propagation/:domain` | protected | GENERAL (1000/15m) | `routes/dns.js:873` | | POST | `/api/v1/dns/propagation/verify` | protected | GENERAL (1000/15m) | `routes/dns.js:841` | | GET | `/api/v1/dns/provider/status` | protected | GENERAL (1000/15m) | `routes/dns.js:55` | | GET | `/api/v1/dns/providers` | protected | GENERAL (1000/15m) | `routes/dns.js:48` | | DELETE | `/api/v1/dns/record` | protected | GENERAL (1000/15m) | `routes/dns.js:191` | | POST | `/api/v1/dns/record` | protected | GENERAL (1000/15m) | `routes/dns.js:240` | | GET | `/api/v1/dns/records` | protected | GENERAL (1000/15m) | `routes/dns.js:72` | | POST | `/api/v1/dns/refresh-token` | protected | GENERAL (1000/15m) | `routes/dns.js:670` | | GET | `/api/v1/dns/resolve` | protected | GENERAL (1000/15m) | `routes/dns.js:307` | | POST | `/api/v1/dns/restart/:dnsId` | protected | GENERAL (1000/15m) | `routes/dns.js:636` | | GET | `/api/v1/dns/token-status` | protected | GENERAL (1000/15m) | `routes/dns.js:489` | | DELETE | `/api/v1/dns/universal/record` | protected | GENERAL (1000/15m) | `routes/dns.js:134` | | POST | `/api/v1/dns/universal/record` | protected | GENERAL (1000/15m) | `routes/dns.js:86` | | GET | `/api/v1/dns/universal/resolve` | protected | GENERAL (1000/15m) | `routes/dns.js:160` | | POST | `/api/v1/dns/update` | protected | GENERAL (1000/15m) | `routes/dns.js:753` | ## Tailscale _20 routes_ | Method | Full path | Auth | Rate limit | Defined in | |---|---|---|---|---| | GET | `/api/v1/tailscale/acl` | public | GENERAL (1000/15m) | `routes/tailscale.js:316` | | GET | `/api/v1/tailscale/admin/devices` | public | GENERAL (1000/15m) | `routes/tailscale-admin.js:280` | | DELETE | `/api/v1/tailscale/admin/devices/:id` | public | GENERAL (1000/15m) | `routes/tailscale-admin.js:296` | | GET | `/api/v1/tailscale/admin/keys` | public | GENERAL (1000/15m) | `routes/tailscale-admin.js:328` | | POST | `/api/v1/tailscale/admin/keys` | public | GENERAL (1000/15m) | `routes/tailscale-admin.js:337` | | DELETE | `/api/v1/tailscale/admin/keys/:id` | public | GENERAL (1000/15m) | `routes/tailscale-admin.js:369` | | GET | `/api/v1/tailscale/admin/users` | public | GENERAL (1000/15m) | `routes/tailscale-admin.js:317` | | GET | `/api/v1/tailscale/api-devices` | public | GENERAL (1000/15m) | `routes/tailscale.js:289` | | GET | `/api/v1/tailscale/check-connection` | public | GENERAL (1000/15m) | `routes/tailscale.js:107` | | POST | `/api/v1/tailscale/config` | public | GENERAL (1000/15m) | `routes/tailscale.js:80` | | GET | `/api/v1/tailscale/devices` | public | GENERAL (1000/15m) | `routes/tailscale.js:124` | | DELETE | `/api/v1/tailscale/oauth-config` | public | GENERAL (1000/15m) | `routes/tailscale.js:274` | | POST | `/api/v1/tailscale/oauth-config` | public | GENERAL (1000/15m) | `routes/tailscale.js:216` | | POST | `/api/v1/tailscale/protect-service` | public | GENERAL (1000/15m) | `routes/tailscale.js:158` | | DELETE | `/api/v1/tailscale/settings` | public | GENERAL (1000/15m) | `routes/tailscale-admin.js:239` | | GET | `/api/v1/tailscale/settings` | public | GENERAL (1000/15m) | `routes/tailscale-admin.js:172` | | PUT | `/api/v1/tailscale/settings` | public | GENERAL (1000/15m) | `routes/tailscale-admin.js:188` | | POST | `/api/v1/tailscale/settings/test` | public | GENERAL (1000/15m) | `routes/tailscale-admin.js:246` | | GET | `/api/v1/tailscale/status` | public | GENERAL (1000/15m) | `routes/tailscale.js:36` | | POST | `/api/v1/tailscale/sync` | public | GENERAL (1000/15m) | `routes/tailscale.js:302` | ## Monitoring _19 routes_ | Method | Full path | Auth | Rate limit | Defined in | |---|---|---|---|---| | GET | `/api/v1/certificates` | protected | GENERAL (1000/15m) | `routes/ssl-monitor.js:26` | | GET | `/api/v1/certificates/:serviceId` | protected | GENERAL (1000/15m) | `routes/ssl-monitor.js:35` | | POST | `/api/v1/check` | protected | GENERAL (1000/15m) | `routes/ssl-monitor.js:50` | | POST | `/api/v1/check/:serviceId` | protected | GENERAL (1000/15m) | `routes/ssl-monitor.js:59` | | GET | `/api/v1/config` | public | GENERAL (1000/15m) | `routes/ssl-monitor.js:80` | | POST | `/api/v1/config` | public | GENERAL (1000/15m) | `routes/ssl-monitor.js:90` | | GET | `/api/v1/monitoring/aggregated/:containerId` | protected | GENERAL (1000/15m) | `routes/monitoring.js:72` | | GET | `/api/v1/monitoring/alerts` | protected | GENERAL (1000/15m) | `routes/monitoring.js:104` | | DELETE | `/api/v1/monitoring/alerts/:containerId` | protected | GENERAL (1000/15m) | `routes/monitoring.js:174` | | GET | `/api/v1/monitoring/alerts/:containerId` | protected | GENERAL (1000/15m) | `routes/monitoring.js:168` | | POST | `/api/v1/monitoring/alerts/:containerId` | protected | GENERAL (1000/15m) | `routes/monitoring.js:162` | | POST | `/api/v1/monitoring/alerts/:containerId/test` | protected | GENERAL (1000/15m) | `routes/monitoring.js:111` | | GET | `/api/v1/monitoring/alerts/config` | protected | GENERAL (1000/15m) | `routes/monitoring.js:85` | | POST | `/api/v1/monitoring/alerts/config` | protected | GENERAL (1000/15m) | `routes/monitoring.js:91` | | GET | `/api/v1/monitoring/history/:containerId` | protected | GENERAL (1000/15m) | `routes/monitoring.js:49` | | GET | `/api/v1/monitoring/stats` | public | GENERAL (1000/15m) | `routes/monitoring.js:20` | | GET | `/api/v1/monitoring/stats/:containerId` | protected | GENERAL (1000/15m) | `routes/monitoring.js:38` | | GET | `/api/v1/stats/container/:id` | protected | GENERAL (1000/15m) | `routes/monitoring.js:240` | | GET | `/api/v1/stats/containers` | protected | GENERAL (1000/15m) | `routes/monitoring.js:182` | ## Backups _18 routes_ | Method | Full path | Auth | Rate limit | Defined in | |---|---|---|---|---| | POST | `/api/v1/backups/backup/:appId` | protected | GENERAL (1000/15m) | `routes/backups.js:165` | | POST | `/api/v1/backups/compare/:filename` | protected | GENERAL (1000/15m) | `routes/backups.js:377` | | GET | `/api/v1/backups/config` | protected | GENERAL (1000/15m) | `routes/backups.js:484` | | POST | `/api/v1/backups/config` | protected | GENERAL (1000/15m) | `routes/backups.js:490` | | DELETE | `/api/v1/backups/credentials/:provider` | protected | GENERAL (1000/15m) | `routes/backups.js:615` | | GET | `/api/v1/backups/credentials/:provider` | protected | GENERAL (1000/15m) | `routes/backups.js:542` | | POST | `/api/v1/backups/credentials/:provider` | protected | GENERAL (1000/15m) | `routes/backups.js:574` | | POST | `/api/v1/backups/execute` | protected | GENERAL (1000/15m) | `routes/backups.js:503` | | GET | `/api/v1/backups/files` | protected | GENERAL (1000/15m) | `routes/backups.js:122` | | GET | `/api/v1/backups/files/:appId` | protected | GENERAL (1000/15m) | `routes/backups.js:193` | | GET | `/api/v1/backups/history` | protected | GENERAL (1000/15m) | `routes/backups.js:509` | | POST | `/api/v1/backups/restore-file/:filename` | protected | GENERAL (1000/15m) | `routes/backups.js:241` | | POST | `/api/v1/backups/restore/:backupId` | protected | GENERAL (1000/15m) | `routes/backups.js:522` | | GET | `/api/v1/backups/schedule` | protected | GENERAL (1000/15m) | `routes/backups.js:37` | | POST | `/api/v1/backups/schedule` | protected | GENERAL (1000/15m) | `routes/backups.js:67` | | DELETE | `/api/v1/backups/schedule/:appId` | protected | GENERAL (1000/15m) | `routes/backups.js:106` | | GET | `/api/v1/backups/storage-info` | protected | GENERAL (1000/15m) | `routes/backups.js:516` | | POST | `/api/v1/backups/test-destination` | protected | GENERAL (1000/15m) | `routes/backups.js:530` | ## Logs _17 routes_ | Method | Full path | Auth | Rate limit | Defined in | |---|---|---|---|---| | DELETE | `/api/v1/error-logs` | protected | GENERAL (1000/15m) | `routes/errorlogs.js:216` | | GET | `/api/v1/error-logs` | protected | GENERAL (1000/15m) | `routes/errorlogs.js:143` | | GET | `/api/v1/error-logs/contexts` | protected | GENERAL (1000/15m) | `routes/errorlogs.js:125` | | GET | `/api/v1/logs/container/:id` | protected | GENERAL (1000/15m) | `routes/logs.js:48` | | GET | `/api/v1/logs/containers` | protected | GENERAL (1000/15m) | `routes/logs.js:32` | | GET | `/api/v1/logs/digest/:date` | protected | GENERAL (1000/15m) | `routes/logs.js:197` | | POST | `/api/v1/logs/digest/generate` | protected | GENERAL (1000/15m) | `routes/logs.js:185` | | GET | `/api/v1/logs/digest/history` | protected | GENERAL (1000/15m) | `routes/logs.js:178` | | GET | `/api/v1/logs/digest/latest` | protected | GENERAL (1000/15m) | `routes/logs.js:161` | | GET | `/api/v1/logs/digest/live` | protected | GENERAL (1000/15m) | `routes/logs.js:171` | | GET | `/api/v1/logs/docker-disk` | protected | GENERAL (1000/15m) | `routes/logs.js:216` | | POST | `/api/v1/logs/docker-maintenance` | protected | GENERAL (1000/15m) | `routes/logs.js:224` | | GET | `/api/v1/logs/file` | protected | GENERAL (1000/15m) | `routes/logs.js:320` | | GET | `/api/v1/logs/journal` | protected | GENERAL (1000/15m) | `routes/logs.js:245` | | GET | `/api/v1/logs/journal/stream` | protected | GENERAL (1000/15m) | `routes/logs.js:260` | | GET | `/api/v1/logs/journal/units` | protected | GENERAL (1000/15m) | `routes/logs.js:236` | | GET | `/api/v1/logs/stream/:id` | protected | GENERAL (1000/15m) | `routes/logs.js:102` | ## Updates _16 routes_ | Method | Full path | Auth | Rate limit | Defined in | |---|---|---|---|---| | POST | `/api/v1/system/rollback` | protected | GENERAL (1000/15m) | `routes/updates.js:164` | | GET | `/api/v1/system/rollback-versions` | protected | GENERAL (1000/15m) | `routes/updates.js:158` | | POST | `/api/v1/system/update-apply` | protected | GENERAL (1000/15m) | `routes/updates.js:95` | | GET | `/api/v1/system/update-check` | public | GENERAL (1000/15m) | `routes/updates.js:89` | | GET | `/api/v1/system/update-history` | public | GENERAL (1000/15m) | `routes/updates.js:152` | | POST | `/api/v1/system/update-notify` | public | GENERAL (1000/15m) | `routes/updates.js:126` | | GET | `/api/v1/system/update-status` | public | GENERAL (1000/15m) | `routes/updates.js:143` | | GET | `/api/v1/system/version` | public | GENERAL (1000/15m) | `routes/updates.js:83` | | GET | `/api/v1/updates/auto-update` | protected | GENERAL (1000/15m) | `routes/updates.js:65` | | POST | `/api/v1/updates/auto-update/:containerId` | protected | GENERAL (1000/15m) | `routes/updates.js:59` | | GET | `/api/v1/updates/available` | public | GENERAL (1000/15m) | `routes/updates.js:29` | | POST | `/api/v1/updates/check` | protected | GENERAL (1000/15m) | `routes/updates.js:22` | | GET | `/api/v1/updates/history` | protected | GENERAL (1000/15m) | `routes/updates.js:49` | | POST | `/api/v1/updates/rollback/:containerId` | protected | GENERAL (1000/15m) | `routes/updates.js:43` | | POST | `/api/v1/updates/schedule/:containerId` | protected | GENERAL (1000/15m) | `routes/updates.js:71` | | POST | `/api/v1/updates/update/:containerId` | protected | GENERAL (1000/15m) | `routes/updates.js:37` | ## Configuration _13 routes_ | Method | Full path | Auth | Rate limit | Defined in | |---|---|---|---|---| | POST | `/api/v1/assets/upload` | protected | GENERAL (1000/15m) | `routes/config/assets.js:58` | | GET | `/api/v1/backup/export` | protected | GENERAL (1000/15m) | `routes/config/backup.js:51` | | POST | `/api/v1/backup/preview` | protected | GENERAL (1000/15m) | `routes/config/backup.js:153` | | POST | `/api/v1/backup/restore` | protected | GENERAL (1000/15m) | `routes/config/backup.js:218` | | DELETE | `/api/v1/config` | public | GENERAL (1000/15m) | `routes/config/settings.js:86` | | GET | `/api/v1/config` | public | GENERAL (1000/15m) | `routes/config/settings.js:26` | | POST | `/api/v1/config` | public | GENERAL (1000/15m) | `routes/config/settings.js:43` | | DELETE | `/api/v1/favicon` | public | GENERAL (1000/15m) | `routes/config/assets.js:280` | | GET | `/api/v1/favicon` | public | GENERAL (1000/15m) | `routes/config/assets.js:216` | | POST | `/api/v1/favicon` | public | GENERAL (1000/15m) | `routes/config/assets.js:225` | | DELETE | `/api/v1/logo` | public | GENERAL (1000/15m) | `routes/config/assets.js:183` | | GET | `/api/v1/logo` | public | GENERAL (1000/15m) | `routes/config/assets.js:94` | | POST | `/api/v1/logo` | public | GENERAL (1000/15m) | `routes/config/assets.js:129` | ## Health _13 routes_ | Method | Full path | Auth | Rate limit | Defined in | |---|---|---|---|---| | DELETE | `/api/v1/health-checks/:serviceId/configure` | protected | GENERAL (1000/15m) | `routes/health.js:357` | | POST | `/api/v1/health-checks/:serviceId/configure` | protected | GENERAL (1000/15m) | `routes/health.js:351` | | GET | `/api/v1/health-checks/:serviceId/stats` | protected | GENERAL (1000/15m) | `routes/health.js:340` | | GET | `/api/v1/health-checks/incidents` | protected | GENERAL (1000/15m) | `routes/health.js:363` | | GET | `/api/v1/health-checks/incidents/history` | protected | GENERAL (1000/15m) | `routes/health.js:371` | | GET | `/api/v1/health-checks/status` | public | GENERAL (1000/15m) | `routes/health.js:319` | | GET | `/api/v1/health/ca` | public | GENERAL (1000/15m) | `routes/health.js:267` | | GET | `/api/v1/health/cached` | protected | GENERAL (1000/15m) | `routes/health.js:179` | | GET | `/api/v1/health/probe` | protected | GENERAL (1000/15m) | `routes/health.js:230` | | GET | `/api/v1/health/pylon` | protected | GENERAL (1000/15m) | `routes/health.js:245` | | GET | `/api/v1/health/service/:id` | protected | GENERAL (1000/15m) | `routes/health.js:188` | | GET | `/api/v1/health/services` | protected | GENERAL (1000/15m) | `routes/health.js:109` | | GET | `/api/v1/system/health` | public | GENERAL (1000/15m) | `routes/health.js:383` | ## Services _12 routes_ | Method | Full path | Auth | Rate limit | Defined in | |---|---|---|---|---| | DELETE | `/api/v1/seedhost-creds` | protected | GENERAL (1000/15m) | `routes/services.js:315` | | GET | `/api/v1/seedhost-creds` | protected | GENERAL (1000/15m) | `routes/services.js:294` | | POST | `/api/v1/seedhost-creds` | protected | GENERAL (1000/15m) | `routes/services.js:277` | | GET | `/api/v1/services` | public | GENERAL (1000/15m) | `routes/services.js:379` | | POST | `/api/v1/services` | public | GENERAL (1000/15m) | `routes/services.js:394` | | PUT | `/api/v1/services` | public | GENERAL (1000/15m) | `routes/services.js:441` | | DELETE | `/api/v1/services/:id` | protected | GENERAL (1000/15m) | `routes/services.js:470` | | DELETE | `/api/v1/services/:serviceId/credentials` | protected | GENERAL (1000/15m) | `routes/services.js:241` | | GET | `/api/v1/services/:serviceId/credentials` | protected | GENERAL (1000/15m) | `routes/services.js:256` | | POST | `/api/v1/services/:serviceId/credentials` | protected | GENERAL (1000/15m) | `routes/services.js:217` | | GET | `/api/v1/services/status` | public | GENERAL (1000/15m) | `routes/services.js:332` | | POST | `/api/v1/services/update` | protected | GENERAL (1000/15m) | `routes/services.js:495` | ## Containers (lifecycle) _11 routes_ | Method | Full path | Auth | Rate limit | Defined in | |---|---|---|---|---| | GET | `/api/v1/containers/` | protected | GENERAL (1000/15m) | `routes/containers.js:76` | | DELETE | `/api/v1/containers/:id` | protected | GENERAL (1000/15m) | `routes/containers.js:295` | | GET | `/api/v1/containers/:id/check-update` | protected | GENERAL (1000/15m) | `routes/containers.js:211` | | GET | `/api/v1/containers/:id/logs` | protected | GENERAL (1000/15m) | `routes/containers.js:249` | | GET | `/api/v1/containers/:id/resources` | protected | GENERAL (1000/15m) | `routes/containers.js:283` | | PUT | `/api/v1/containers/:id/resources` | protected | GENERAL (1000/15m) | `routes/containers.js:261` | | POST | `/api/v1/containers/:id/restart` | protected | GENERAL (1000/15m) | `routes/containers.js:104` | | POST | `/api/v1/containers/:id/start` | protected | GENERAL (1000/15m) | `routes/containers.js:90` | | POST | `/api/v1/containers/:id/stop` | protected | GENERAL (1000/15m) | `routes/containers.js:97` | | POST | `/api/v1/containers/:id/update` | protected | GENERAL (1000/15m) | `routes/containers.js:111` | | GET | `/api/v1/containers/discover` | protected | GENERAL (1000/15m) | `routes/containers.js:302` | ## Core / system _9 routes_ | Method | Full path | Auth | Rate limit | Defined in | |---|---|---|---|---| | GET | `/api/v1/docs` | protected | GENERAL (1000/15m) | `src/app.js:1358` | | GET | `/api/v1/docs/spec` | protected | GENERAL (1000/15m) | `src/app.js:1376` | | GET | `/api/v1/network/ips` | protected | GENERAL (1000/15m) | `src/app.js:1332` | | GET | `/health` | public | GENERAL (1000/15m) | `src/app.js:1210` | | GET | `/health/live` | public | GENERAL (1000/15m) | `src/app.js:1211` | | GET | `/health/ready` | public | GENERAL (1000/15m) | `src/app.js:1215` | | GET | `/healthz` | public | GENERAL (1000/15m) | `src/app.js:1212` | | GET | `/probe/:id` | public | GENERAL (1000/15m) | `src/app.js:1219` | | GET | `/readyz` | public | GENERAL (1000/15m) | `src/app.js:1216` | ## Dependencies _8 routes_ | Method | Full path | Auth | Rate limit | Defined in | |---|---|---|---|---| | DELETE | `/api/v1/dependencies/:serviceId` | protected | GENERAL (1000/15m) | `routes/dependencies.js:199` | | GET | `/api/v1/dependencies/:serviceId` | protected | GENERAL (1000/15m) | `routes/dependencies.js:108` | | POST | `/api/v1/dependencies/:serviceId` | protected | GENERAL (1000/15m) | `routes/dependencies.js:151` | | GET | `/api/v1/dependencies/:serviceId/chain` | protected | GENERAL (1000/15m) | `routes/dependencies.js:133` | | POST | `/api/v1/dependencies/:serviceId/restart` | protected | GENERAL (1000/15m) | `routes/dependencies.js:233` | | GET | `/api/v1/dependencies/:serviceId/status` | protected | GENERAL (1000/15m) | `routes/dependencies.js:142` | | GET | `/api/v1/dependencies/graph` | protected | GENERAL (1000/15m) | `routes/dependencies.js:76` | | GET | `/api/v1/dependencies/validate` | protected | GENERAL (1000/15m) | `routes/dependencies.js:84` | ## Notifications _8 routes_ | Method | Full path | Auth | Rate limit | Defined in | |---|---|---|---|---| | GET | `/api/v1/notifications/config` | protected | GENERAL (1000/15m) | `routes/notifications.js:20` | | POST | `/api/v1/notifications/config` | protected | GENERAL (1000/15m) | `routes/notifications.js:61` | | POST | `/api/v1/notifications/health-check` | protected | GENERAL (1000/15m) | `routes/notifications.js:300` | | DELETE | `/api/v1/notifications/history` | protected | GENERAL (1000/15m) | `routes/notifications.js:294` | | GET | `/api/v1/notifications/history` | protected | GENERAL (1000/15m) | `routes/notifications.js:278` | | POST | `/api/v1/notifications/send` | protected | GENERAL (1000/15m) | `routes/notifications.js:332` | | GET | `/api/v1/notifications/status` | protected | GENERAL (1000/15m) | `routes/notifications.js:310` | | POST | `/api/v1/notifications/test` | protected | GENERAL (1000/15m) | `routes/notifications.js:245` | ## App recipes _8 routes_ | Method | Full path | Auth | Rate limit | Defined in | |---|---|---|---|---| | DELETE | `/api/v1/recipes/:recipeId` | protected | GENERAL (1000/15m) | `routes/recipes/manage.js:215` | | POST | `/api/v1/recipes/:recipeId/restart` | protected | GENERAL (1000/15m) | `routes/recipes/manage.js:188` | | POST | `/api/v1/recipes/:recipeId/start` | protected | GENERAL (1000/15m) | `routes/recipes/manage.js:123` | | POST | `/api/v1/recipes/:recipeId/stop` | protected | GENERAL (1000/15m) | `routes/recipes/manage.js:155` | | POST | `/api/v1/recipes/deploy` | protected | GENERAL (1000/15m) | `routes/recipes/deploy.js:29` | | GET | `/api/v1/recipes/deployed` | protected | GENERAL (1000/15m) | `routes/recipes/manage.js:39` | | GET | `/api/v1/recipes/templates` | protected | GENERAL (1000/15m) | `routes/recipes/index.js:34` | | GET | `/api/v1/recipes/templates/:recipeId` | protected | GENERAL (1000/15m) | `routes/recipes/index.js:63` | ## Docker resources _7 routes_ | Method | Full path | Auth | Rate limit | Defined in | |---|---|---|---|---| | GET | `/api/v1/docker/disk-usage` | protected | GENERAL (1000/15m) | `routes/docker-resources.js:84` | | GET | `/api/v1/docker/networks` | protected | GENERAL (1000/15m) | `routes/docker-resources.js:50` | | POST | `/api/v1/docker/networks` | protected | GENERAL (1000/15m) | `routes/docker-resources.js:64` | | DELETE | `/api/v1/docker/networks/:id` | protected | GENERAL (1000/15m) | `routes/docker-resources.js:76` | | GET | `/api/v1/docker/volumes` | protected | GENERAL (1000/15m) | `routes/docker-resources.js:17` | | POST | `/api/v1/docker/volumes` | protected | GENERAL (1000/15m) | `routes/docker-resources.js:30` | | DELETE | `/api/v1/docker/volumes/:name` | protected | GENERAL (1000/15m) | `routes/docker-resources.js:42` | ## Caddy / sites _7 routes_ | Method | Full path | Auth | Rate limit | Defined in | |---|---|---|---|---| | GET | `/api/v1/caddy/cas` | protected | GENERAL (1000/15m) | `routes/sites.js:60` | | GET | `/api/v1/caddy/config` | protected | GENERAL (1000/15m) | `routes/sites.js:34` | | POST | `/api/v1/caddy/reload` | protected | GENERAL (1000/15m) | `routes/sites.js:41` | | GET | `/api/v1/caddyfile` | protected | GENERAL (1000/15m) | `routes/sites.js:28` | | POST | `/api/v1/site` | protected | GENERAL (1000/15m) | `routes/sites.js:167` | | DELETE | `/api/v1/site/:domain` | protected | GENERAL (1000/15m) | `routes/sites.js:138` | | POST | `/api/v1/site/external` | protected | GENERAL (1000/15m) | `routes/sites.js:212` | ## Certificate authority _6 routes_ | Method | Full path | Auth | Rate limit | Defined in | |---|---|---|---|---| | POST | `/api/v1/ca/backup` | protected | GENERAL (1000/15m) | `routes/ca.js:402` | | GET | `/api/v1/ca/cert/:domain` | protected | GENERAL (1000/15m) | `routes/ca.js:176` | | GET | `/api/v1/ca/certs` | protected | GENERAL (1000/15m) | `routes/ca.js:354` | | GET | `/api/v1/ca/info` | public | GENERAL (1000/15m) | `routes/ca.js:15` | | GET | `/api/v1/ca/install-script` | public | GENERAL (1000/15m) | `routes/ca.js:63` | | GET | `/api/v1/ca/root.crt` | public | GENERAL (1000/15m) | `routes/ca.js:45` | ## Updates / workflows _6 routes_ | Method | Full path | Auth | Rate limit | Defined in | |---|---|---|---|---| | GET | `/api/v1/workflows/` | protected | GENERAL (1000/15m) | `routes/workflows.js:44` | | POST | `/api/v1/workflows/:workflowId/disable` | protected | GENERAL (1000/15m) | `routes/workflows.js:58` | | POST | `/api/v1/workflows/:workflowId/enable` | protected | GENERAL (1000/15m) | `routes/workflows.js:50` | | GET | `/api/v1/workflows/:workflowId/history` | protected | GENERAL (1000/15m) | `routes/workflows.js:86` | | POST | `/api/v1/workflows/:workflowId/run` | protected | GENERAL (1000/15m) | `routes/workflows.js:66` | | GET | `/api/v1/workflows/history` | protected | GENERAL (1000/15m) | `routes/workflows.js:79` | ## Auto-restart _5 routes_ | Method | Full path | Auth | Rate limit | Defined in | |---|---|---|---|---| | GET | `/api/v1/policies` | protected | GENERAL (1000/15m) | `routes/auto-restart.js:30` | | DELETE | `/api/v1/policies/:serviceId` | protected | GENERAL (1000/15m) | `routes/auto-restart.js:103` | | GET | `/api/v1/policies/:serviceId` | protected | GENERAL (1000/15m) | `routes/auto-restart.js:39` | | POST | `/api/v1/policies/:serviceId` | protected | GENERAL (1000/15m) | `routes/auto-restart.js:60` | | POST | `/api/v1/policies/:serviceId/test` | protected | GENERAL (1000/15m) | `routes/auto-restart.js:123` | ## OpenClaw integration _5 routes_ | Method | Full path | Auth | Rate limit | Defined in | |---|---|---|---|---| | DELETE | `/api/v1/openclaw/` | protected | GENERAL (1000/15m) | `routes/openclaw.js:467` | | POST | `/api/v1/openclaw/deploy` | protected | GENERAL (1000/15m) | `routes/openclaw.js:373` | | GET | `/api/v1/openclaw/proxy/*` | protected | GENERAL (1000/15m) | `routes/openclaw.js:439` | | POST | `/api/v1/openclaw/proxy/*` | protected | GENERAL (1000/15m) | `routes/openclaw.js:453` | | GET | `/api/v1/openclaw/status` | protected | GENERAL (1000/15m) | `routes/openclaw.js:339` | ## Config drift _4 routes_ | Method | Full path | Auth | Rate limit | Defined in | |---|---|---|---|---| | POST | `/api/v1/fix` | protected | GENERAL (1000/15m) | `routes/config-drift.js:51` | | GET | `/api/v1/last` | protected | GENERAL (1000/15m) | `routes/config-drift.js:39` | | POST | `/api/v1/polling` | protected | GENERAL (1000/15m) | `routes/config-drift.js:66` | | GET | `/api/v1/report` | protected | GENERAL (1000/15m) | `routes/config-drift.js:30` | ## Licensing _4 routes_ | Method | Full path | Auth | Rate limit | Defined in | |---|---|---|---|---| | POST | `/api/v1/license/activate` | protected | GENERAL (1000/15m) | `routes/license.js:29` | | POST | `/api/v1/license/deactivate` | protected | GENERAL (1000/15m) | `routes/license.js:55` | | GET | `/api/v1/license/feature/:feature` | public | GENERAL (1000/15m) | `routes/license.js:66` | | GET | `/api/v1/license/status` | public | GENERAL (1000/15m) | `routes/license.js:48` | ## File browser _3 routes_ | Method | Full path | Auth | Rate limit | Defined in | |---|---|---|---|---| | GET | `/api/v1/browse/directories` | protected | GENERAL (1000/15m) | `routes/browse.js:52` | | GET | `/api/v1/browse/roots` | protected | GENERAL (1000/15m) | `routes/browse.js:34` | | GET | `/api/v1/media/detected-mounts` | protected | GENERAL (1000/15m) | `routes/browse.js:137` | ## Theming _3 routes_ | Method | Full path | Auth | Rate limit | Defined in | |---|---|---|---|---| | GET | `/api/v1/themes` | public | GENERAL (1000/15m) | `routes/themes.js:40` | | DELETE | `/api/v1/themes/:slug` | protected | GENERAL (1000/15m) | `routes/themes.js:65` | | POST | `/api/v1/themes/:slug` | protected | GENERAL (1000/15m) | `routes/themes.js:45` | ## Service credentials _2 routes_ | Method | Full path | Auth | Rate limit | Defined in | |---|---|---|---|---| | GET | `/api/v1/credentials/list` | protected | GENERAL (1000/15m) | `routes/credentials.js:15` | | POST | `/api/v1/credentials/rotate-key` | protected | GENERAL (1000/15m) | `routes/credentials.js:21` | ## Events _2 routes_ | Method | Full path | Auth | Rate limit | Defined in | |---|---|---|---|---| | GET | `/api/v1/events/clients` | protected | GENERAL (1000/15m) | `routes/events.js:154` | | GET | `/api/v1/events/stream` | protected | GENERAL (1000/15m) | `routes/events.js:126` | ## Mount Point Map | Route file(s) | Mounted at | |---|---| | `routes/billing` | `/api/v1/billing` | | `routes/ca` | `/api/v1/ca` | | `routes/calendar` | `/api/v1/calendar` | | `routes/containers` | `/api/v1/containers` | | `routes/dependencies` | `/api/v1/dependencies` | | `routes/deploys` | `/api/v1/deploys` | | `routes/disk-space` | `/api/v1/disk` | | `routes/dns` | `/api/v1/dns` | | `routes/docker-resources` | `/api/v1/docker` | | `routes/events` | `/api/v1/events` | | `routes/license` | `/api/v1/license` | | `routes/mcp` | `/api/v1/mcp` | | `routes/network-lifecycle` | `/api/v1/network` | | `routes/network-access` | `/api/v1/network/access` | | `routes/network-groups` | `/api/v1/network/groups` | | `routes/network-invites` | `/api/v1/network/invites` | | `routes/network-people` | `/api/v1/network/people` | | `routes/network-resources` | `/api/v1/network/resources` | | `routes/network-wizard` | `/api/v1/network/wizard` | | `routes/notifications` | `/api/v1/notifications` | | `routes/openclaw` | `/api/v1/openclaw` | | `routes/recipes/` | `/api/v1/recipes` | | `routes/security` | `/api/v1/security` | | `routes/tailscale` | `/api/v1/tailscale` | | `routes/tailscale-admin` | `/api/v1/tailscale` | | `routes/workflows` | `/api/v1/workflows` | | `routes/auth/` | `/api/v1 (root)` | | `routes/config/` | `/api/v1 (root)` | | `routes/share` | `/api/v1 (root)` | | `routes/services` | `/api/v1 (root)` | | `routes/health` | `/api/v1 (root)` | | `routes/monitoring` | `/api/v1 (root)` | | `routes/i18n` | `/api/v1 (root)` | | `routes/discover` | `/api/v1 (root)` | | `routes/discover-adopt` | `/api/v1 (root)` | | `routes/catalog` | `/api/v1 (root)` | | `routes/wizard` | `/api/v1 (root)` | | `routes/disaster-recovery` | `/api/v1 (root)` | | `routes/caddycode` | `/api/v1 (root)` | | `routes/fleet` | `/api/v1 (root)` | | `routes/updates` | `/api/v1 (root)` | | `routes/sites` | `/api/v1 (root)` | | `routes/credentials` | `/api/v1 (root)` | | `routes/arr/` | `/api/v1 (root)` | | `routes/apps/` | `/api/v1 (root)` | | `routes/logs` | `/api/v1 (root)` | | `routes/backups` | `/api/v1 (root)` | | `routes/browse` | `/api/v1 (root)` | | `routes/errorlogs` | `/api/v1 (root)` | | `routes/themes` | `/api/v1 (root)` | | `routes/ai-intent` | `/api/v1 (root)` | | `routes/log-insights` | `/api/v1 (root)` | | `routes/audit-log` | `/api/v1 (root)` | | `routes/auto-restart` | `/api/v1 (root)` | | `routes/config-drift` | `/api/v1 (root)` | | `routes/ssl-monitor` | `/api/v1 (root)` | | `routes/caddy-upstreams` | `/api/v1 (root)` | ## OpenAPI Spec Cross-Check - Unique paths in code: **367** - Unique (method, path) operations in code: **440** - Handler rows exceed unique operations when the same (method, path) is registered more than once (e.g. GET /api/v1/auth/me, GET+POST /api/v1/config appear in more than one route file). - Paths in openapi.yaml: **290** - Note: openapi.yaml lags the code (spec documents the 2026-07 surface); code-derived rows above reflect the declared router (static extraction). ### In code but NOT documented (100) - `/api/v1/audit-logs/actions` - `/api/v1/auth/sso-handoff` - `/api/v1/ca/backup` - `/api/v1/caddy/upstreams` - `/api/v1/caddy/upstreams/:host/mute` - `/api/v1/caddy/upstreams/:host/unmute` - `/api/v1/caddy/upstreams/incidents` - `/api/v1/caddy/upstreams/mute` - `/api/v1/caddycode/generate` - `/api/v1/caddycode/templates` - `/api/v1/caddycode/validate` - `/api/v1/catalog` - `/api/v1/catalog/:appId` - `/api/v1/catalog/search` - `/api/v1/certificates` - `/api/v1/certificates/:serviceId` - `/api/v1/check` - `/api/v1/check/:serviceId` - `/api/v1/containers/` - `/api/v1/deploys/catalog/apps` - `/api/v1/deploys/catalog/deploy` - `/api/v1/deploys/deploy` - `/api/v1/deploys/gitea-repos` - `/api/v1/deploys/install` - `/api/v1/deploys/journal` - `/api/v1/deploys/repos` - `/api/v1/deploys/rollback` - `/api/v1/deploys/services` - `/api/v1/deploys/status` - `/api/v1/disaster/backup` - ... and 70 more ### Documented but NOT in code (23) - `/api/v1/auto-restart/policies` - `/api/v1/auto-restart/policies/:serviceId` - `/api/v1/auto-restart/policies/:serviceId/test` - `/api/v1/config-drift/fix` - `/api/v1/config-drift/last` - `/api/v1/config-drift/polling` - `/api/v1/config-drift/report` - `/api/v1/csrf-token` - `/api/v1/disk` - `/api/v1/mcp` - `/api/v1/metrics` - `/api/v1/openclaw` - `/api/v1/ssl/certificates` - `/api/v1/ssl/certificates/:serviceId` - `/api/v1/ssl/check` - `/api/v1/ssl/check/:serviceId` - `/api/v1/ssl/config` - `/api/v1/workflows/workflows` - `/api/v1/workflows/workflows/:workflowId/disable` - `/api/v1/workflows/workflows/:workflowId/enable` - `/api/v1/workflows/workflows/:workflowId/history` - `/api/v1/workflows/workflows/:workflowId/run` - `/api/v1/workflows/workflows/history` ## Known Limitations - Literal single-line `router.('path', ...)` declarations only; multiline, computed, chained, `router.route()`, and `app.all()` registrations may be omitted. Mount resolution relies on the maintained composition map above. Treat this file as a high-coverage declarative inventory, not a guaranteed-complete listing. - Duplicate registrations (3): the handler-row total exceeds unique operations because of these: - GET /api/v1/auth/me: routes/auth/admin.js:112, routes/auth/index.js:158 - GET /api/v1/config: routes/config/settings.js:26, routes/ssl-monitor.js:80 - POST /api/v1/config: routes/config/settings.js:43, routes/ssl-monitor.js:90