API surface. Jobs are REST (integrators monitor and retry their own work). Job schedules are GraphQL Interface.
Logistics runs on background work: nightly product syncs, end-of-day closes, 5,000-label print runs, route optimizations, tracking refreshes, dataset exports. Before this chapter, each of those had its own async object with its own status vocabulary. This interface gives them one envelope: every asynchronous operation is a job. Clients, dashboards and agents monitor, cancel and retry all of them the same way, and recurring work is declared once as a job_schedule. Existing async objects keep their shape and gain a job field linking to their envelope:

1. The job object

2. Endpoints

  • POST /v1/jobs is the generic way to start any registered job type. The domain-specific endpoints (POST /v1/batches, POST /v1/document_jobs, createOptimization (GraphQL Interface mutation)) remain, and return their domain object with job set.
  • Concurrency. Each account has published concurrency limits per job type. Excess jobs stay queued, and GET /v1/jobs?status=queued shows the position in progress.stage.
  • Idempotency. Idempotency-Key on POST /v1/jobs follows chapter 00 §8. Items inside a job derive their own keys ({job_id}:{index}), so a retried job never duplicates side effects such as labels.

3. Job schedules

Recurring work is declared once:
  • recurrence is the shared Recurrence (chapter 01 §13).
  • overlap is skip (do not start while the previous run is still running), queue, or cancel_previous.
  • System schedules are visible. The implementer’s own recurring work for the account (connection end_of_day closes, pickup schedule bookings, route run generation, tracker sweeps) appears as read-only job_schedules with system_metadata.source: "system". A support team can read one list to answer “what runs automatically on this account?“.

4. Events

job.queued, job.started, job.progressed (at most every 10 seconds, opt-in by subscribing explicitly), job.succeeded, job.partially_succeeded, job.failed, job.cancelled, job_schedule.created, job_schedule.paused, job_schedule.resumed, job_schedule.run_skipped. Domain events still fire as before (batch.completed, document_job.completed, optimization.completed). job.* events are the generic layer for dashboards and agents that watch everything.