DrydockDrydock
API

Container API

This API allows to query the state of the watched containers.

This API allows to query the state of the watched containers.

Get all containers

This operation lets you get all the watched containers.

curl "http://drydock:3000/api/v1/containers?limit=25&offset=0"

{
  "data": [
    {
      "id": "31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816",
      "name": "homeassistant",
      "watcher": "local",
      "status": "running"
    }
  ],
  "total": 42,
  "limit": 25,
  "offset": 0,
  "hasMore": true
}

Query parameters

ParameterTypeDefaultDescription
limitinteger0Maximum number of containers to return (0 means unbounded; max 200)
offsetinteger0Number of matching containers to skip
includeVulnerabilitiesbooleanfalseInclude full vulnerability arrays in data
sortstringSort order: name, -name, status, -status, age, -age, created, -created (prefix - for descending)
orderstringOptional sort direction override: asc or desc
statusstringFilter by update/runtime status: update-available, up-to-date, running, stopped, exited, paused, restarting, dead, created
kindstringFilter by update kind or watched state: major, minor, patch, digest, watched, unwatched, all
watcherstringFilter by watcher name
maturitystringFilter by update maturity: hot, mature, established. The hot/mature boundary is controlled by DD_UI_MATURITY_THRESHOLD_DAYS (default 7 days); updates older than 30 days are always established.
containerIdsstringComma-separated list of container IDs to pre-filter results to a specific set. Used by the Security view Update action and dashboard row navigation.

Maturity filter configuration

The hot/mature age boundary used by the maturity query parameter is set server-side:

Env varRequiredDescriptionSupported valuesDefault value when missing
DD_UI_MATURITY_THRESHOLD_DAYSAge threshold (days) that separates hot updates from mature updates. Updates younger than this value are classified hot; updates at or older than this value (up to 30 days) are classified mature; updates older than 30 days are always established.integer (>0)7

Get container summary

Returns a lightweight summary of container and security counts, used by the dashboard sidebar.

curl http://drydock:3000/api/v1/containers/summary

{
  "containers": {
    "total": 12,
    "running": 10,
    "stopped": 2
  },
  "security": {
    "issues": 3
  }
}

Response fields

FieldTypeDescription
containers.totalintegerTotal number of watched containers
containers.runningintegerNumber of running containers
containers.stoppedintegerNumber of stopped containers
security.issuesintegerNumber of containers with critical or high vulnerabilities
hotUpdatesintegerNumber of containers with updates less than 24 hours old
matureUpdatesintegerNumber of containers with updates between 24 hours and 7 days old

Get recent container status

Returns a map of container names to their most recent update status, derived from the last 100 audit log entries. Used by the dashboard to show status badges on containers.

curl http://drydock:3000/api/v1/containers/recent-status

{
  "statuses": {
    "homeassistant": "updated",
    "nginx": "pending",
    "postgres": "failed"
  },
  "statusesByIdentity": {
    "::local::homeassistant": "updated",
    "edge-a::docker-prod::nginx": "pending",
    "edge-b::docker-prod::postgres": "failed"
  }
}

Response fields

FieldTypeDescription
statusesobjectMap of container name to status (last-write-wins when names collide across hosts)
statuses[name]stringupdated (update applied), pending (update available), or failed (update failed)
statusesByIdentityobjectMap of identity key (agent::watcher::name) to status. Provides unambiguous per-container status when the same container name exists on multiple hosts.
statusesByIdentity[key]stringupdated, pending, or failed

Watch all Containers

This operation triggers a manual watch on all containers.

curl -X POST http://drydock:3000/api/v1/containers/watch

{
  "data": [{
  "id":"31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816",
  "name":"homeassistant",
  "watcher":"local",
  "includeTags":"^\\d+\\.\\d+.\\d+$",
  "image":{
    "id":"sha256:d4a6fafb7d4da37495e5c9be3242590be24a87d7edcc4f79761098889c54fca6",
    "registry":{
      "url":"123456789.dkr.ecr.eu-west-1.amazonaws.com"
    },
    "name":"test",
    "tag":{
      "value":"2021.6.4",
      "semver":true
    },
    "digest":{
      "watch":false,
      "repo":"sha256:ca0edc3fb0b4647963629bdfccbb3ccfa352184b45a9b4145832000c2878dd72"
    },
    "architecture":"amd64",
    "os":"linux",
    "created":"2021-06-12T05:33:38.440Z"
  },
  "result":{
    "tag":"2021.6.5"
  },
  "updateAvailable": true
  }],
  "total": 42,
  "limit": 0,
  "offset": 0,
  "hasMore": false
}

Get a Container by id

This operation lets you get a container by id.

curl http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816

{
  "id":"31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816",
  "name":"homeassistant",
  "watcher":"local",
  "includeTags":"^\\d+\\.\\d+.\\d+$",
  "image":{
    "id":"sha256:d4a6fafb7d4da37495e5c9be3242590be24a87d7edcc4f79761098889c54fca6",
    "registry":{
      "url":"123456789.dkr.ecr.eu-west-1.amazonaws.com"
    },
    "name":"test",
    "tag":{
      "value":"2021.6.4",
      "semver":true
    },
    "digest":{
      "watch":false,
      "repo":"sha256:ca0edc3fb0b4647963629bdfccbb3ccfa352184b45a9b4145832000c2878dd72"
    },
    "architecture":"amd64",
    "os":"linux",
    "created":"2021-06-12T05:33:38.440Z"
  },
  "result":{
    "tag":"2021.6.5"
  },
  "updateAvailable": true
}

Get all triggers associated to the container

This operation lets you get the list of triggers associated to the container.

curl http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/triggers

{
  "data": [
    {
      "id": "ntfy.one",
      "type": "ntfy",
      "name": "one",
      "configuration": {
        "topic": "235ef38e-f1db-414a-964f-ce3f2cc8094d",
        "url": "https://ntfy.sh",
        "threshold": "major",
        "mode": "simple",
        "once": true,
        "simpletitle": "New ${kind} found for container ${name}",
        "simplebody": "Container ${container.name} running with ${container.updateKind.kind} ${container.updateKind.localValue} can be updated to ${container.updateKind.kind} ${container.updateKind.remoteValue}${container.result && container.result.link ? "\\n" + container.result.link : ""}",
        "batchtitle": "${containers.length} updates available",
      }
    }
  ],
  "total": 1
}

Watch a Container

This operation triggers a manual watch on a container.

curl -X POST http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/watch

{
  "id":"31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816",
  "name":"homeassistant",
  "watcher":"local",
  "includeTags":"^\\d+\\.\\d+.\\d+$",
  "image":{
    "id":"sha256:d4a6fafb7d4da37495e5c9be3242590be24a87d7edcc4f79761098889c54fca6",
    "registry":{
      "url":"123456789.dkr.ecr.eu-west-1.amazonaws.com"
    },
    "name":"test",
    "tag":{
      "value":"2021.6.4",
      "semver":true
    },
    "digest":{
      "watch":false,
      "repo":"sha256:ca0edc3fb0b4647963629bdfccbb3ccfa352184b45a9b4145832000c2878dd72"
    },
    "architecture":"amd64",
    "os":"linux",
    "created":"2021-06-12T05:33:38.440Z"
  },
  "result":{
    "tag":"2021.6.5"
  },
  "updateAvailable": true
}

Run a trigger on the container

This operation lets you manually run a trigger on the container.

curl -X POST http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/triggers/ntfy/one

For containers managed by a remote agent, use the 4-segment variant to route the trigger through the agent:

curl -X POST http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/triggers/ntfy/one/agent1

Update a container

This operation queues a direct container update — pulling the new image, stopping the old container, and recreating it with the updated image. This is equivalent to clicking "Update now" in the UI. Requires the Docker trigger to be configured for the container's watcher and DD_SERVER_FEATURE_CONTAINERACTIONS to be enabled.

Returns 202 Accepted with an operation id when the update is queued successfully, 400 if no update is available, 403 if container actions are disabled, 404 if the container or Docker trigger is not found, 409 if the update conflicts with the current container state (already queued/in progress, blocked by security, or targeting a temporary rollback container), or 500 on update failure.

Example success response:

{
  "message": "Container update accepted",
  "operationId": "ea7c33a4-c1e3-4f34-9b95-9662cc7a40d6"
}
curl -X POST http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/update

Update container update policy (skip/snooze)

This operation lets you control per-container update suppression policy (stored in drydock DB):

  • skip-current: skip the currently detected remote tag or digest
  • remove-skip: remove a single previously skipped tag or digest (requires kind and value)
  • clear-skips: remove skipTags and skipDigests
  • snooze: suppress update notifications until a date (supports days or explicit snoozeUntil)
  • unsnooze: remove snoozeUntil
  • clear: remove all update policy
  • set-maturity-policy: require updates to be at least N days old before triggering (requires mode and optionally minAgeDays)
  • clear-maturity-policy: remove maturityMode and maturityMinAgeDays
curl -X PATCH http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/update-policy \
  -H 'Content-Type: application/json' \
  -d '{"action":"skip-current"}'
# Remove a single skipped tag
curl -X PATCH http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/update-policy \
  -H 'Content-Type: application/json' \
  -d '{"action":"remove-skip","kind":"tag","value":"1.2.3"}'
# Remove a single skipped digest
curl -X PATCH http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/update-policy \
  -H 'Content-Type: application/json' \
  -d '{"action":"remove-skip","kind":"digest","value":"sha256:abc123..."}'
curl -X PATCH http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/update-policy \
  -H 'Content-Type: application/json' \
  -d '{"action":"snooze","days":7}'
# Require updates to be at least 14 days old before triggering
curl -X PATCH http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/update-policy \
  -H 'Content-Type: application/json' \
  -d '{"action":"set-maturity-policy","mode":"mature","minAgeDays":14}'
# Remove maturity policy (allow all updates regardless of age)
curl -X PATCH http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/update-policy \
  -H 'Content-Type: application/json' \
  -d '{"action":"clear-maturity-policy"}'

Get security vulnerability overview

This operation returns pre-aggregated vulnerability data grouped by image across all scanned containers. Used by the Security view to display vulnerability summaries without loading every container individually.

curl http://drydock:3000/api/v1/containers/security/vulnerabilities

The response includes total and scanned container counts, the latest scan timestamp, and an images array where each entry groups vulnerabilities by image name with container IDs and an optional update severity summary.

Get latest vulnerability scan result

This operation returns the latest persisted vulnerability scan (safe-pull gate result) for a container. When no scan was run yet, it returns status: "not-scanned" with an empty result set.

curl http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/vulnerabilities

Run an on-demand security scan

This operation triggers a vulnerability scan, optional signature verification, and optional SBOM generation for a container. The scan targets the update candidate image when available, falling back to the current image tag. Results are persisted to container.security and the updated container is returned.

Requires DD_SECURITY_SCANNER=trivy to be configured.

curl -X POST http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/scan

Rate-limited to 30 requests per minute.

Returns 200 with the updated container on success, 400 if security scanner is not configured, 404 if the container is not found, or 500 on scan failure.

Run bulk security scan

This operation triggers a vulnerability scan on all watched containers server-side. Streams per-container progress over the SSE channel and emits a single security-scan-cycle-complete event when finished. Respects client-disconnect aborts.

curl -X POST http://drydock:3000/api/v1/containers/scan-all

Rate-limited to 1 request per 60 seconds per IP. Authenticated admins bypass the rate limit.

Returns 202 Accepted when the bulk scan is started, or 429 if the rate limit is exceeded.

Get SBOM for a container

This operation returns the latest SBOM document for a container in the requested format.

curl http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/sbom?format=spdx-json

Returns 200 with the SBOM document, 404 if the container is not found, or 503 ("Security scanner is disabled or misconfigured") if the Trivy scanner is disabled or not configured. A 503 indicates the feature is intentionally off, not a generation failure.

Download container logs

Returns stdout/stderr output from a container as a downloadable text file. Supports gzip compression via Accept-Encoding: gzip header. For agent-managed containers, the request is proxied through the agent connection.

curl "http://drydock:3000/api/v1/containers/{id}/logs?tail=1000&stdout=true&stderr=true"

Query parameters

ParameterTypeDefaultDescription
stdoutbooleantrueInclude stdout output
stderrbooleantrueInclude stderr output
tailinteger1000Number of lines to return from the end of the log
sincestring0Unix timestamp (seconds) or ISO 8601 string — only return logs after this time
timestampsbooleantrueInclude timestamps in output

Returns 200 with the log text (Content-Disposition: attachment), 404 if the container is not found, or 500 on failure.

Stream container logs (WebSocket)

Opens a WebSocket connection for real-time container log streaming. The server demultiplexes Docker's binary stream format and sends individual JSON frames.

ws://drydock:3000/api/v1/containers/{id}/logs/stream?follow=true&tail=100

Query parameters

ParameterTypeDefaultDescription
stdoutbooleantrueInclude stdout output
stderrbooleantrueInclude stderr output
tailinteger100Number of initial lines to load
sincestring0Unix timestamp (seconds) or ISO 8601 string — only stream logs after this time
followbooleantrueContinue streaming new output (set false for one-shot fetch)

Message format

Each WebSocket message is a JSON object:

{
  "type": "stdout",
  "ts": "2026-03-18T19:18:38.485902360Z",
  "line": "Server started on port 3000"
}
FieldTypeDescription
typestringstdout or stderr
tsstringISO 8601 timestamp from Docker
linestringLog line content (may contain ANSI escape codes)

Close codes

CodeMeaning
1000Normal close (stream ended or client disconnect)
4001Container is not running
4004Container not found
1011Watcher unavailable or stream error

Authentication

WebSocket upgrade requests require a valid session cookie. Unauthenticated requests receive HTTP 401 during the upgrade handshake.

Rate limiting

WebSocket connections are rate-limited to 1,000 connections per 15-minute window per client IP (or per authenticated user when identity-aware rate limiting is enabled).

Reveal container environment variables

Returns the full (unredacted) runtime environment variables for a container. Environment values in the standard container response are redacted to *** for sensitive keys. This endpoint reveals the actual values and creates an audit trail entry.

Rate-limited to 10 requests per minute.

curl -X POST http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/env/reveal

{
  "env": [
    { "key": "TZ", "value": "America/New_York", "sensitive": false },
    { "key": "DATABASE_PASSWORD", "value": "s3cret", "sensitive": true }
  ]
}

Response fields

FieldTypeDescription
env[].keystringEnvironment variable name
env[].valuestringUnredacted value
env[].sensitivebooleanWhether the key matches known sensitive patterns (passwords, tokens, secrets)

Returns 200 with the env array on success, 404 if the container is not found, or 429 if rate-limited.

Container action auth model: /start, /stop, /restart, and /update are authentication-gated only. In current single-operator deployments, any authenticated user can execute these actions for any container.

Start a container

This operation starts a stopped container. Requires DD_SERVER_FEATURE_CONTAINERACTIONS to be enabled.

curl -X POST http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/start

Stop a container

This operation stops a running container. Requires DD_SERVER_FEATURE_CONTAINERACTIONS to be enabled.

curl -X POST http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/stop

Restart a container

This operation restarts a container. Requires DD_SERVER_FEATURE_CONTAINERACTIONS to be enabled.

curl -X POST http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/restart

Preview an update

This operation returns a dry-run preview of what an update would change, without executing it.

curl -X POST http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/preview

List all backups

Returns all image backups across all containers, optionally filtered by container name.

curl "http://drydock:3000/api/v1/containers/backups?containerName=homeassistant"

{
  "data": [
    {
      "id": "abc123",
      "containerId": "31a61a8305ef...",
      "containerName": "homeassistant",
      "imageName": "homeassistant/home-assistant",
      "imageTag": "2024.11.3",
      "imageDigest": "sha256:...",
      "timestamp": "2024-12-01T10:00:00.000Z",
      "triggerName": "docker.local"
    }
  ],
  "total": 1
}

Query parameters

ParameterTypeDescription
containerNamestringFilter backups by container name

Get container backups

This operation returns all image backups for a container, sorted by most recent first.

curl http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/backups

{
  "data": [
    {
      "id": "abc123",
      "containerId": "31a61a8305ef...",
      "containerName": "homeassistant",
      "imageName": "homeassistant/home-assistant",
      "imageTag": "2021.6.4",
      "imageDigest": "sha256:...",
      "timestamp": "2021-06-15T10:30:00.000Z",
      "triggerName": "docker.local"
    }
  ],
  "total": 1
}

Rollback a container

This operation rolls back a container to a previously backed-up image. If no backupId is provided, the most recent backup is used. Rollback is destructive and requires explicit confirmation via X-DD-Confirm-Action: container-rollback.

curl -X POST http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/rollback \
  -H 'X-DD-Confirm-Action: container-rollback' \
  -H 'Content-Type: application/json' \
  -d '{"backupId": "abc123"}'

Returns 200 on success, 404 if the container/backup/trigger is not found, or 428 if confirmation is missing.

Get update/rollback history

Returns the persisted update and rollback operation history for a container, sorted by most recent first. Each entry tracks the full lifecycle of an update (phases, status, versions, rollback reason if applicable).

curl http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/update-operations

{
  "data": [
    {
      "id": "a1b2c3d4-...",
      "containerName": "homeassistant",
      "status": "succeeded",
      "phase": "succeeded",
      "createdAt": "2024-12-01T10:00:00.000Z",
      "updatedAt": "2024-12-01T10:01:30.000Z",
      "containerId": "31a61a8305ef...",
      "triggerName": "docker.local",
      "fromVersion": "2024.11.3",
      "toVersion": "2024.12.0",
      "targetImage": "homeassistant/home-assistant:2024.12.0"
    },
    {
      "id": "e5f6a7b8-...",
      "containerName": "homeassistant",
      "status": "rolled-back",
      "phase": "rolled-back",
      "createdAt": "2024-11-20T08:00:00.000Z",
      "updatedAt": "2024-11-20T08:02:00.000Z",
      "containerId": "31a61a8305ef...",
      "fromVersion": "2024.11.2",
      "toVersion": "2024.11.3",
      "rollbackReason": "Health check failed"
    }
  ],
  "total": 2,
  "limit": 0,
  "offset": 0,
  "hasMore": false
}

Response fields

FieldTypeDescription
idstringUnique operation ID
containerNamestringContainer name
statusstringqueued, in-progress, succeeded, rolled-back, failed, or expired (a stuck operation terminalised by the active-TTL sweep; non-notifying)
phasestringCurrent phase: prepare, renamed, new-created, old-stopped, new-started, health-gate, health-gate-passed, succeeded, rollback-started, rolled-back, rollback-failed, expired
createdAtstringISO 8601 timestamp when the operation started
updatedAtstringISO 8601 timestamp of the last phase transition
containerIdstringContainer ID
triggerNamestringTrigger that initiated the update
fromVersionstringPrevious image tag or digest
toVersionstringTarget image tag or digest
targetImagestringFull target image reference
rollbackReasonstringReason for rollback (only present on rolled-back operations)
lastErrorstringError message (only present on failed operations)

Returns 200 with the operations array on success, or 404 if the container is not found.

Get a single update operation

GET /api/v1/update-operations/:id

Returns the current state of a single update or rollback operation by its ID. Use this as an SSE-miss fallback — if a UI client reconnects after losing the SSE stream and needs to reconcile operation state without replaying all events.

curl http://drydock:3000/api/v1/update-operations/ea7c33a4-c1e3-4f34-9b95-9662cc7a40d6

{
  "id": "ea7c33a4-c1e3-4f34-9b95-9662cc7a40d6",
  "containerName": "homeassistant",
  "status": "in-progress",
  "phase": "new-started",
  "createdAt": "2026-01-15T12:00:00.000Z",
  "updatedAt": "2026-01-15T12:00:05.000Z",
  "containerId": "31a61a8305ef...",
  "fromVersion": "2024.11.3",
  "toVersion": "2024.12.0"
}

The response shape matches entries from the GET /api/v1/containers/:id/update-operations array.

Returns 200 with the operation on success, 400 if no ID is provided, or 404 if the operation is not found.

Cancel an update operation

POST /api/v1/operations/:id/cancel

Requests cancellation of a queued or in-progress update operation.

  • Queued operations are terminated immediately. The operation is marked failed with reason "Cancelled by operator". Returns 200 OK with the updated operation.
  • In-progress operations have a cancellation flag set; the update lifecycle checks this flag at safe checkpoints and aborts cleanly when reached. Returns 202 Accepted with the operation (still in-progress until the checkpoint is hit).
  • Terminal operations (succeeded, failed, rolled-back, expired) cannot be cancelled. Returns 409 Conflict.
curl -X POST http://drydock:3000/api/v1/operations/ea7c33a4-c1e3-4f34-9b95-9662cc7a40d6/cancel

# Queued → 200: operation immediately marked failed
# In-progress → 202: cancellation flag set, update will stop at next safe checkpoint
# Terminal → 409: { "error": "Operation is not active", "status": "succeeded" }

Returns 200 (queued — immediately cancelled), 202 (in-progress — cancellation requested), 404 if not found, or 409 if already terminal.

Get single container stats

GET /api/v1/containers/:id/stats

Returns the latest stats snapshot and history for a single container.

Response

FieldTypeDescription
dataobjectLatest stats snapshot
historyarrayArray of historical snapshots

Stream container stats (SSE)

GET /api/v1/containers/:id/stats/stream

Server-Sent Events stream for real-time container stats. Sends dd:container-stats events with the latest snapshot and dd:heartbeat events every 15 seconds.

Get fleet stats summary

GET /api/v1/stats/summary

Returns a fleet-wide CPU and memory snapshot aggregated across watched local and agent-owned containers. Updated on a configurable polling interval (default 10 s). Use this endpoint for read-only dashboard queries and fleet rollups; per-container telemetry remains available from the single-container stats endpoints.

curl http://drydock:3000/api/v1/stats/summary

{
  "data": {
    "timestamp": "2026-01-15T12:00:00.000Z",
    "watchedCount": 8,
    "avgCpuPercent": 12.4,
    "totalMemoryUsageBytes": 2147483648,
    "totalMemoryLimitBytes": 17179869184,
    "totalMemoryPercent": 12.5,
    "topCpu": [
      { "id": "abc123", "name": "homeassistant", "cpuPercent": 28.1, "memoryUsageBytes": 524288000, "memoryLimitBytes": 2147483648, "memoryPercent": 24.4 }
    ],
    "topMemory": [
      { "id": "abc123", "name": "homeassistant", "cpuPercent": 28.1, "memoryUsageBytes": 524288000, "memoryLimitBytes": 2147483648, "memoryPercent": 24.4 }
    ]
  }
}

Response fields

FieldTypeDescription
data.timestampstringISO 8601 timestamp of the last aggregation tick
data.watchedCountintegerNumber of containers included in this snapshot
data.avgCpuPercentnumberAverage CPU usage percentage across all containers (0–100)
data.totalMemoryUsageBytesnumberSum of memory usage bytes across all containers
data.totalMemoryLimitBytesnumberSum of memory limits across all containers
data.totalMemoryPercentnumberFleet-wide memory usage as a percentage of total limits (0–100)
data.topCpuarrayTop-5 containers by CPU%, sorted descending
data.topMemoryarrayTop-5 containers by memory%, sorted descending
data.topCpu[].idstringContainer ID
data.topCpu[].namestringContainer name
data.topCpu[].cpuPercentnumberCPU usage percentage
data.topCpu[].memoryUsageBytesnumberMemory usage in bytes
data.topCpu[].memoryLimitBytesnumberMemory limit in bytes
data.topCpu[].memoryPercentnumberMemory usage percentage

Stream fleet stats summary (SSE)

GET /api/v1/stats/summary/stream

Server-Sent Events stream that pushes a new dd:stats-summary event whenever the aggregator completes a tick, plus dd:heartbeat events to keep the connection alive. The current snapshot is sent immediately on connect.

The dashboard Resource Usage widget consumes this stream directly.

Event format

event: dd:stats-summary
data: { ...ContainerStatsSummary }

event: dd:heartbeat
data: {}

The data payload shape is identical to the data field from GET /api/v1/stats/summary.

Get container release notes

GET /api/v1/containers/:id/release-notes

Returns GitHub release notes for the container's available update, if available.

Delete a Container

This operation lets you delete a container by id. Requires DD_SERVER_FEATURE_DELETE to be enabled. Delete is destructive and requires explicit confirmation via X-DD-Confirm-Action: container-delete.

curl -X DELETE http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816 \
  -H 'X-DD-Confirm-Action: container-delete'

Returns 204 on success, 403 if delete is disabled, 404 if the container does not exist, or 428 if confirmation is missing.

On this page