Skip to main content

Async jobs

Some Spectral operations take longer than a request should wait, so they run in the background. These endpoints return a job straight away: a handle you poll until the work finishes.

The envelope

An endpoint that kicks off background work returns the resource it created and the job building it:

Response
{
...,
"job": {
"id": "job_8f2a1...",
"status": "queued",
"kind": "...",
"resource": { ... },
"created_at": "2026-06-19T12:00:00Z",
}
}

The resource already has an id, but its status is queued or running: it exists, but it is not ready to use. Keep the job.id and poll it before relying on the resource.

The job object

FieldDescription
idThe job identifier. Pass it to GET /api/v1/jobs/{job_id}.
statusOne of queued, running, succeeded, failed.
kindWhat the job is doing (for example, populate_knowledge_base, create_run, build_report).
resourceThe type and id of what the job is building.
created_at, started_at, ended_atTimestamps for the job's lifecycle. started_at and ended_at are null until the job reaches each stage.

queued and running are in-progress states. succeeded and failed are terminal.

Polling a job

Fetch the job with GET /api/v1/jobs/{job_id} and repeat until status is terminal:

Request
curl https://spectral.principled.app/api/v1/jobs/job_8f2a1... \
-H "Authorization: Bearer ak_****"
Response
{
"id": "job_8f2a1...",
"status": "succeeded",
"kind": "populate_knowledge_base",
"resource": { "type": "knowledge_base", "id": "3b1f7..." },
"created_at": "2026-06-19T12:00:00Z",
"started_at": "2026-06-19T12:00:03Z",
"ended_at": "2026-06-19T12:02:18Z"
}

When status is succeeded, the resource is ready to use.

warning

We recommend polling on an interval of at least 60 seconds. There is no need to poll more aggressively, and doing so may result in rate limiting.