AACSearch

Jobs

Long-running operations answer 202 with a job id. Poll GET /jobs/{jobId} for progress and cancel with DELETE before the alias swap.

Operations that can take longer than a request — rebuilding an index, crawling a documentation site, importing uploaded files, writing or restoring a snapshot — never run inside the HTTP request. The endpoint validates the input, queues a job and answers 202 Accepted. A scheduler worker claims the job under a lease; if the process dies mid-job, the lease expires and the job is picked up again.

Job typeStarted byScope needed to read / cancel
reindexPOST /indexes/{slug}/reindexsettings:write
crawlPOST /indexes/{slug}/docsearch/previewdocuments:write
file_importRunning a file connectorsettings:write
snapshotPOST /indexes/{slug}/snapshotssettings:write
restorePOST /indexes/{slug}/snapshots/{id}/restoresettings:write
evalPOST /quality/sets/{setId}/runsettings:write
reembedPOST /indexes/{slug}/reembed?all=truesettings:write (started with documents:write)

The 202 response

curl -sS -X POST "$AAC_API/indexes/products/reindex" \
  -H "Authorization: Bearer $AAC_KEY"
{
	"index": "products",
	"job_id": "clx8f2k9q0001",
	"status": "queued",
	"status_url": "/api/v1/jobs/clx8f2k9q0001",
	"request_id": "req_…"
}

The snapshot endpoints return job_id (plus snapshot_id on create) in the same spirit; see Snapshots.

GET /jobs/{jobId}

curl -sS "$AAC_API/jobs/clx8f2k9q0001" -H "Authorization: Bearer $AAC_KEY"
{
	"job": {
		"id": "clx8f2k9q0001",
		"type": "reindex",
		"status": "running",
		"phase": "loading",
		"progress": 42,
		"attempts": 1,
		"index": "products",
		"documents_processed": 7731,
		"error": null,
		"result": null,
		"created_at": "2026-10-25T09:00:00.000Z",
		"started_at": "2026-10-25T09:00:02.000Z",
		"finished_at": null
	},
	"request_id": "req_…"
}
FieldMeaning
statusqueued · running · completed · partial · failed · cancelled
phaseStep inside the job. Reindex: queued → loading → copying → swapping → done; crawl: crawling → done
progress0–100
attemptsHow many times a worker claimed it (a crash and retry increments it)
resultSet when finished, by type (below)

result by type:

Typeresult
reindex{ documents, duration_ms, source, snapshot_kept }
crawl{ pages, skipped, errors[], total, records[] } — the first 25 records, nothing written to the index
file_import{ loaded, indexed, failed, skipped, ocr_pages, files[] }
snapshot{ snapshot_id, documents, bytes }
restore{ snapshot_id, documents, duration_ms, snapshot_kept }
reembed{ documents, failed, restored, embed_model, embed_model_version, duration_ms }
evalnone — read the metrics from GET /quality/runs/{runId}

DELETE /jobs/{jobId}

Cancels a job that is queued or running and has not reached the alias swap:

curl -sS -X DELETE "$AAC_API/jobs/clx8f2k9q0001" -H "Authorization: Bearer $AAC_KEY"

Returns the job envelope with status: "cancelled". A job that finished or is already swapping answers:

{
	"error": {
		"code": "JOB_NOT_CANCELLABLE",
		"message": "The job has finished or already reached the alias swap",
		"details": { "status": "running", "phase": "swapping" },
		"request_id": "req_…"
	}
}

with status 409. Cancellations are written to the audit log.

What a cancel does depends on the job:

TypeAfter the cancel
reindex, restoreThe worker stops between pages and drops the half-built collection; the live index is untouched
snapshotNothing is published; partial objects are removed
file_import, reembedStops between files / batches; what was already written stays
crawlThe crawl finishes in the background, but its result is discarded
evalThe run is closed as failed

Isolation

A job id is always resolved inside the key's organization. A job of another tenant — or, for an index-bound key, of another index — is 404 JOB_NOT_FOUND, never 403.

Conflicts

Only one rebuild per index runs at a time. Starting a reindex or a restore while a reindex or restore is queued or running answers 409 JOB_CONFLICT with the active job_id in details. The same applies to ?sync=true. Only one reembed job per index runs at a time either.

Synchronous reindex for tests

POST /indexes/{slug}/reindex?sync=true keeps the old blocking behaviour and answers 200 with { index, job_id, documents, duration_ms }. It exists for acceptance test suites; do not use it in production — a large index holds the request for minutes. POST /quality/sets/{setId}/run?sync=true likewise keeps the old blocking evaluation.

On this page