API¶
The API is described by its OpenAPI specification,
pubgrade/api/pubgrade.yaml.
A running Pubgrade serves it at /openapi.json, with a web interface to try
the endpoints at /ui/. Pubgrade validates requests and responses against it.
Endpoint Who
GET /repositories anyone
POST /repositories anyone, while registration is open
GET /repositories/{id} anyone
PUT /repositories/{id} the repository (its access token)
DELETE /repositories/{id} the repository
GET /repositories/{id}/builds anyone
POST /repositories/{id}/builds the repository: publish an image
GET /repositories/{id}/builds/{build_id} anyone
PUT /repositories/{id}/builds/{build_id} the repository's build pods (internal), builds on only
DELETE /repositories/{id}/builds/{build_id} the repository: cancel a build
POST /users/register anyone, while registration is open
DELETE /users/register the user
GET /users admins
PUT /users/{uid}/verify admins
PUT /users/{uid}/unverify admins
GET /subscriptions verified users: their subscriptions
POST /subscriptions verified users, while registration is open
GET /subscriptions/{subscription_id} the subscription's user
DELETE /subscriptions/{subscription_id} the subscription's user
PUT /repositories/{id} changes only the repository's URL. DELETE
/repositories/{id} also deletes the repository's builds and subscriptions
(see Usage).
DELETE /repositories/{id}/builds/{build_id} withdraws a build: it is kept,
with the status CANCELED (see Usage); a
repeated request gets 409 Conflict. Builds can't be changed: a changed
build is a new POST /repositories/{id}/builds. PUT
/repositories/{id}/builds/{build_id} is the internal callback with which
build pods report their completion (with builds switched on only, else
403); for a canceled build, it gets a 409.
Registrations are open until they are closed in the configuration. The specification is the reference for the request and response bodies and the headers that carry the tokens. See Usage for the typical flow.
Pubgrade also calls subscribers: the notification of a new image, a PUT to
the subscription's callback_url, is described as the callback
notification of POST /subscriptions, with the body NotificationRequest
(see Usage).
Version 2.1.0 of the API completes the subscriptions API; see Upgrading to API 2.1.0.
Since version 2.0.0 of the API, errors are
problem details
(application/problem+json), with title, status (an integer) and
detail, e.g.:
Before, errors had msg and status_code (a string) instead.
Requests that don't match the API's schemas (e.g., a subscription without
type) also get type, code and errors, e.g.:
{
"type": "https://foca.readthedocs.io/en/latest/problems/invalid-request/",
"title": "Bad Request",
"status": 400,
"detail": "Invalid fields: #/type (required)",
"code": "invalid-request",
"errors": [
{"detail": "Is required.", "pointer": "#/type", "code": "required"}
]
}
errorslists the invalid fields: each by its location (pointerin the body orparameter) and a stablecode(see FOCA's invalid request).- Values of the request are left out, but names of unknown parameters and body fields are echoed.
- Unknown query parameters are always invalid fields. Unknown body fields
are invalid fields only where the schema forbids them (e.g.,
POST /repositories); elsewhere (e.g.,POST /subscriptions) they are accepted and dropped, neither stored nor returned. detailnames the invalid fields.- Other invalid requests get no
errors: bodies that aren't JSON or arenullget"detail": "The request is malformed.", and Pubgrade's own checks (e.g., an unknown branch inhead_commit) their owndetail.
Request bodies larger than 1 MiB are rejected with 413. Timestamps
(started_at, finished_at and updated_at) are in UTC with time zone
(e.g., 2026-11-06T14:04:04.619000+00:00), and finished_at of a build is
null until it has finished (before: "NULL").