All endpoints are served over HTTP. Requests and responses use JSON (Content-Type: application/json) unless noted otherwise.

Health check

GET /health

Returns 200 OK with an empty body. Used by load balancers and orchestrators to verify the service is running.


Jobs

POST /jobs

Creates a new print job and publishes it to RabbitMQ.

Request body

  {
  "photos": [
    { "photoStorageKey": "stand-1-abc123.jpg", "copies": 2 },
    { "photoStorageKey": "stand-1-def456.jpg", "copies": 1 }
  ]
}
  
FieldTypeRequiredDescription
photosarrayyesList of photos to print. At least one required.
photos[].photoStorageKeystringyesObject key in MinIO (e.g. stand-1-abc123.jpg)
photos[].copiesintyesNumber of copies to print. Must be >= 1.

Response 201 Created

  {
  "jobId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "status": "queued",
  "createdAt": "2026-04-13T10:00:00Z"
}
  

Response 400 Bad Request

Returned when the photos array is empty.


GET /jobs

Returns a paginated list of jobs, optionally filtered by status.

Query parameters

ParameterTypeDefaultDescription
statusstring(all)Comma-separated list of statuses to filter by. Accepted values: queued, printing, requeued, done, error.
limitint50Maximum number of jobs to return.
offsetint0Number of jobs to skip.
sortstring(none)Set to status to order by status priority: printing first, then requeued, queued, error, done.

Response 200 OK

  {
  "jobs": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "status": "printing",
      "total": 3,
      "printed": 1,
      "retryCount": 0,
      "createdAt": "2026-04-13T10:00:00Z",
      "updatedAt": "2026-04-13T10:00:05Z"
    }
  ],
  "total": 42
}
  
FieldDescription
jobsArray of job summaries for the current page
totalTotal number of jobs matching the filter (before pagination)
idJob UUID
statusCurrent status: queued, printing, requeued, done, or error
total (job)Total number of photos in the job
printedNumber of photos printed so far
retryCountNumber of times the job has been requeued by the watchdog

GET /jobs/{jobId}

Returns full details for a single job, including the list of photos.

Path parameter

ParameterTypeDescription
jobIdUUIDJob identifier

Response 200 OK

  {
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "status": "done",
  "total": 2,
  "printed": 2,
  "retryCount": 0,
  "createdAt": "2026-04-13T10:00:00Z",
  "updatedAt": "2026-04-13T10:01:00Z",
  "photos": [
    { "photoStorageKey": "stand-1-abc123.jpg", "copies": 2 },
    { "photoStorageKey": "stand-1-def456.jpg", "copies": 1 }
  ]
}
  

Response 404 Not Found

Returned when no job exists with the given jobId.


GET /jobs/{jobId}/stream

Streams job status updates using Server-Sent Events (SSE).

Path parameter

ParameterTypeDescription
jobIdUUIDJob identifier

Response headers

  Content-Type: text/event-stream
Cache-Control: no-cache
X-Accel-Buffering: no
  

Event format

Each event is a data: line followed by a blank line:

  data: {"jobId":"3fa85f64...","status":"printing","printed":1,"total":3,"error":null}

data: {"jobId":"3fa85f64...","status":"done","printed":3,"total":3,"error":null}
  
FieldDescription
jobIdJob UUID as a string
statusCurrent status
printedPhotos printed so far
totalTotal photos in the job
errorError message if status is error, otherwise null

The first event is sent immediately with the current job state. The connection closes automatically once status is done or error. The client can reconnect at any time and will receive the current state on connect.

Response 404 Not Found

Returned when no job exists with the given jobId.


Photos

GET /photos

Returns a paginated list of photos available in MinIO, with pre-signed URLs.

Query parameters

ParameterTypeDefaultDescription
limitint50Maximum number of photos to return.
offsetint0Number of photos to skip.

Photos are listed from the low/ prefix in the configured MinIO bucket and sorted lexicographically by key before pagination.

Response 200 OK

  {
  "photos": [
    {
      "key": "low/stand-1-abc123.jpg",
      "url": "https://minio.example.com/photostand/low/stand-1-abc123.jpg?X-Amz-..."
    }
  ],
  "total": 120
}
  
FieldDescription
photosArray of photo entries for the current page
photos[].keyObject key in MinIO
photos[].urlPre-signed URL valid for 1 hour
totalTotal number of photos in the bucket (before pagination)