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/jobsis 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 withjobset.- Concurrency. Each account has published concurrency limits per job type. Excess jobs stay
queued, andGET /v1/jobs?status=queuedshows the position inprogress.stage. - Idempotency.
Idempotency-KeyonPOST /v1/jobsfollows 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:recurrenceis the sharedRecurrence(chapter 01 §13).overlapisskip(do not start while the previous run is still running),queue, orcancel_previous.- System schedules are visible. The implementer’s own recurring work for the account (connection
end_of_daycloses, pickup schedule bookings, route run generation, tracker sweeps) appears as read-onlyjob_schedules withsystem_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.