API Reference¶
Portalcrane's backend is a FastAPI application; every REST route lives
under /api, and the registry proxy lives at /v2 (standard Docker
Registry HTTP API path, unauthenticated in the OpenAPI schema on purpose —
see below).
Interactive docs (Swagger UI)¶
Set SWAGGER_ENABLED=true and browse to /api/docs. It's disabled by
default and self-hosted (no CDN dependency), authenticated the same way as
the rest of the API:
- Click Authorize, choose PersonalAccessToken, and paste an
api-scoped Personal Access Token — every request in that session is then authenticated as you. - The raw OpenAPI schema is served at
/api/openapi.json(also gated behindSWAGGER_ENABLED).
The /v2/... registry proxy routes are deliberately excluded from the
schema (include_in_schema=False) — they implement the Docker Registry
HTTP API and only make sense to a Docker client, never to a Swagger/REST
consumer.
Authenticating requests¶
Three credential types work against the REST API, all resolving to the
same UserInfo context:
| Credential | Where it goes | Typical use |
|---|---|---|
| Session JWT | pc_token HttpOnly cookie (set by /api/auth/login) |
Browser sessions |
| Session JWT | Authorization: Bearer <token> (the access_token from /api/auth/login's JSON response) |
Short-lived scripts, same lifetime as a login session |
Personal Access Token (api scope) |
Authorization: Bearer <token> |
Long-lived automation, CI, external tools |
See Users, Groups & Permissions and Personal Access Tokens for how accounts and tokens are provisioned.
Health check¶
Unauthenticated; returns a JSON status payload. Used by the container's built-in Docker healthcheck.
Endpoint groups¶
Every route below is prefixed with /api unless noted. Full request/response
shapes, permission requirements, and examples are covered on each feature's
own page — this table is the map.
| Prefix | Tag | Covers | Docs |
|---|---|---|---|
/auth |
Authentication | Login/logout, current user, local user CRUD, password change | Authentication & OIDC, Users, Groups & Permissions |
/auth/tokens |
Personal Access Tokens | Create/list/revoke PATs | Personal Access Tokens |
/oidc |
OIDC | Public config, callback, admin settings, connectivity test | Authentication & OIDC |
/groups |
Groups | CRUD for permission groups + membership | Users, Groups & Permissions |
/folders |
Folders | CRUD for folders, per-group permission grants, discovery endpoints | Folder-Based Access Control |
/images |
Images | Browse/search/delete repositories & tags, retag, copy | Image & Tag Management |
/registries |
Registries | CRUD for external registries, connectivity tests | External Registries & Transfers |
/staging |
Staging | Docker Hub search, pull/scan/push pipeline, job tracking | Staging Pipeline |
/transfer |
Transfer | Bulk cross-registry copy jobs | External Registries & Transfers |
/trivy |
Trivy | On-demand scans, DB status/update, scan-policy override | Vulnerability Scanning |
/dashboard |
Dashboard | Aggregate registry/user/Trivy statistics | Dashboard |
/network |
Network | Proxy, syslog, and email configuration + tests | Notifications, TLS & Reverse Proxy |
/system |
System | Process status, audit logs, GC, orphan OCI cleanup | System Maintenance |
| `` (root) | About | Version info, latest-release check | — |
/v2 |
Registry Proxy | Standard Docker Registry HTTP API v2 (for docker CLI) |
Getting Started → Quick Start |
Error conventions worth knowing¶
404instead of403for ownership checks — fetching a registry (or similar owned resource) you don't have access to returns404 Not Foundrather than403 Forbidden, so its existence — and any credentials it might hold — is never confirmed to a user who shouldn't see it.503for an unreachable backing registry — image-browsing endpoints catch connection/timeout errors against the target registry and return503 Service Unavailableinstead of an unhandled500.409for a GC already in progress — starting a garbage-collect while one is running returns409 Conflict; pollGET /api/system/gcinstead of retrying blindly.
Rate limits¶
All /api/* routes are subject to the per-IP rate limiter described in
TLS & Reverse Proxy → Rate limiting
unless RATE_LIMIT_ENABLED=false. The login endpoint has its own, stricter
budget.