Jobs

Exports, imports, and evictions run as jobs. A job row carries its kind, state, progress, and the cartridge and remote it works on. Cartridge actions on the cartridges page create jobs; this page reads and controls them.

The job object

{
  "id": 42,
  "kind": "export",
  "cart_label": "OVB001L5",
  "remote_id": 1,
  "generation": "20260831T001507Z",
  "state": "uploading",
  "trigger": "manual",
  "bytes_total": 22548578304,
  "bytes_done": 10737418240,
  "chunks_total": 3,
  "chunks_done": 1,
  "created_at": "2026-08-31T00:15:07Z",
  "updated_at": "2026-08-31T00:15:52Z"
}
Field Values
kind export, import, evict. Rows of kind pool_create / pool_remove can exist from earlier releases; they are not runnable.
trigger manual (API or UI), ie-watcher (a host eject with the vault watcher on), policy (eviction pressure), recover (whole-library recovery).
generation YYYYMMDDTHHMMSSZ, the bucket generation the job writes or reads.
error Present on a failed job.
finished_at Present once terminal.
system_name, target_library Present on an import into a specific local library (a foreign or DR import).

States

Kind Path
export detected → quiescing → chunking ⇄ uploading → verifying → unvaulting → done
import queued → fetching → verifying → unpacking → (slotting) → done
evict queued → evicting → done

failed and cancelled are terminal for every kind. slotting appears only when the import lands in a library the cartridge was not already in.

GET /api/jobs

read-only

The most recent jobs, newest first.

Query Default Notes
limit 100 1 to 1000.
curl -sk "https://appliance:8443/api/jobs?limit=20" -H "Authorization: Bearer $OVTL_KEY"

GET /api/jobs/search

read-only

A free-text search over the whole job table: id, kind, state, label, trigger, generation, system, and error text. Newest first.

Query Default Notes
q Substring to match. Empty returns everything up to limit.
limit 500
curl -sk "https://appliance:8443/api/jobs/search?q=OVB001L5" -H "Authorization: Bearer $OVTL_KEY"

GET /api/jobs/{id}

read-only

One job with its state-transition timeline and, for exports, the chunk ledger.

{
  "job": {"id": 42, "kind": "export", "state": "done", "…": "…"},
  "events": [
    {"id": 301, "job_id": 42, "ts": "2026-08-31T00:15:07Z", "to_state": "detected", "detail": "export requested"},
    {"id": 302, "job_id": 42, "ts": "2026-08-31T00:15:08Z", "from_state": "detected", "to_state": "quiescing", "detail": "verifying cart is idle and out of any drive"}
  ],
  "chunks": [
    {"job_id": 42, "idx": 0, "s3_key": "demo01/OVTL280164/OVB001L5/20260831T001507Z/chunk-00000.tar.zst", "raw_bytes": 10737418240, "stored_bytes": 573741824}
  ]
}

404 for an unknown id.

POST /api/jobs/{id}/retry

admin

Re-queues a failed or cancelled job. An export resumes from its chunk ledger: chunks already in the bucket under the same generation are skipped. Any other state is a 400. Refused with 409 while a graceful restart is draining.

curl -sk -X POST https://appliance:8443/api/jobs/42/retry -H "Authorization: Bearer $OVTL_KEY"

Returns the job in its new initial state (detected for exports, queued otherwise).

POST /api/jobs/{id}/cancel

admin

Cancels a running job (its work stops at the next checkpoint and the state becomes cancelled) or a queued one (marked cancelled before start). A terminal job is a 400. A cancelled export leaves its uploaded chunks in the bucket, so a later retry does not re-upload them.

curl -sk -X POST https://appliance:8443/api/jobs/42/cancel -H "Authorization: Bearer $OVTL_KEY"
{"ok": true}