Skip to main content
Some Croma lookups take longer to return, anywhere from a few seconds to a couple of minutes. These run as async jobs: the same request can resolve three different ways, and you choose which one fits your app.
You don’t have to do anything special. By default these endpoints behave like any other: you POST and get { "data": … } back. The options below are opt-in, for when you’d rather not hold a connection open.

Which endpoints are async?

These lookups run as async jobs: Everything else (Rama Judicial, Registraduría, Web Search) answers synchronously, with no job involved.

The three ways to get a result

ModeYou sendYou get back
Wait inline (default)nothing extra, or Prefer: wait=N200 { data } if it finishes in time, else 202
PollPrefer: wait=0202 now, then GET /jobs/:id until done
Callbackcallback_url in the body202 now, then a POST to your URL when done
All three are backed by the same job, so pick per request.

Mode 1: Wait inline (default)

Just call the endpoint. The request holds open until the job finishes (up to 55 seconds) and returns the result in the usual { data } shape, identical to a synchronous endpoint.
curl https://api.croma.run/co/policia/criminal-records/v1 \
  -H "Authorization: Bearer $CROMA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "document_number": "1234567890" }'
Control how long to wait with the standard Prefer: wait=N header (seconds, clamped to 55):
curl https://api.croma.run/co/policia/criminal-records/v1 \
  -H "Authorization: Bearer $CROMA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Prefer: wait=30" \
  -d '{ "document_number": "1234567890" }'
  • 200: finished. Body is { "data": … }, same as the synchronous shape.
  • 202: not finished within the wait. Body is a job envelope; follow its status_url to poll. The X-Job-Id header carries the job id.
Always handle both 200 and 202. A 202 is not an error; it just means “still working, come back for it.”

Mode 2: Poll

Send Prefer: wait=0 to get a 202 immediately, then GET the job’s status_url until it reaches a terminal state.
# 1. Start the job (returns 202 immediately)
curl -i https://api.croma.run/co/policia/criminal-records/v1 \
  -H "Authorization: Bearer $CROMA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Prefer: wait=0" \
  -d '{ "document_number": "1234567890" }'

# 2. Poll the status_url from the response (or Location header)
curl https://api.croma.run/jobs/run_abc123 \
  -H "Authorization: Bearer $CROMA_API_KEY"
GET /jobs/:id always returns 200 with the envelope. While the job is still running it includes a Retry-After header (seconds); use it to pace your polling. Jobs are scoped to your organization; a job belonging to another org reads as 404.

Mode 3: Callback (webhook)

Include a callback_url in the request body. You get a 202 right away, and Croma POSTs the result to your URL once the job finishes, with no polling.
curl -i https://api.croma.run/co/policia/criminal-records/v1 \
  -H "Authorization: Bearer $CROMA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "document_number": "1234567890",
        "callback_url": "https://your-app.com/webhooks/croma"
      }'
callback_url must be an absolute HTTPS URL on a public host (localhost and private ranges are rejected). When the job finishes, Croma sends a POST to it:
  • Body: the same job envelope as the poll endpoint.
  • x-croma-job-id: the job id.
  • x-croma-signature: sha256=<hmac>, an HMAC-SHA256 of the raw request body, so you can verify the payload’s integrity.
POST /webhooks/croma HTTP/1.1
content-type: application/json
x-croma-job-id: run_abc123
x-croma-signature: sha256=9f86d081…

{ "job": { "id": "run_abc123", "status": "completed",  }, "data": {  }, "error": null }
Signature verification uses a shared secret issued by Croma; reach out if you want it enabled for your callbacks. Respond 2xx quickly; non-2xx responses are retried.

The job envelope

The 202 response, GET /jobs/:id, and the callback body all share one shape:
{
  "job": {
    "id": "run_abc123",
    "status": "completed",
    "endpoint": "/co/policia/criminal-records/v1",
    "created_at": "2026-06-01T01:04:55.045Z",
    "finished_at": "2026-06-01T01:05:39.809Z",
    "status_url": "https://api.croma.run/jobs/run_abc123"
  },
  "data": { },
  "error": null
}
  • data is populated only when status is completed (and matches the endpoint’s normal data payload). Otherwise it’s null.
  • error is populated only when the job has failed, as { "type", "code", "message" }.

Statuses

statusTerminal?Meaning
queuednoAccepted, waiting to run.
runningnoIn progress.
completedyesDone. Read data.
failedyesThe job errored. Read error.
canceledyesThe run was canceled.
expiredyesThe run expired before completing.

Headers reference

HeaderWhereMeaning
Prefer: wait=NrequestSeconds to wait inline before returning 202. Clamped to 55. wait=0 returns 202 immediately.
Preference-Applied: wait=N200 responseEchoes the wait that was applied.
Location202 responseThe job’s status_url.
Retry-After202 / running pollSuggested seconds before polling again.
X-Job-Id202 / 200 responseThe job id.

Errors

How failures and the error object work.