Skip to main content
Lists page at up to 100 rows per request, which is right for an app and wrong for a BI load. Exports produce one file with the complete filtered dataset of an entity (processes, actuaciones or defendants), up to 100,000 rows, and hand you a download URL.
Because a large portfolio takes longer than a single request should hold, an export runs as an async job: the same request can resolve three ways, and you choose which fits your app.
Small exports feel synchronous. By default the request waits up to 20 seconds and, if the file is ready, returns 200 { data } with the URL. The other modes are opt-in, for when you’d rather not hold the connection open.

The request

Unknown fields in the body (or in filters) are rejected with 400. The result, once the file exists:
  • url is unguessable but not authenticated: anyone holding it can download the file. It is guaranteed until expires_at (24 hours after completion) and removed shortly after; download promptly and don’t post it anywhere public.
  • truncated: true means the 100,000-row cap was hit and the file is not the complete dataset. Narrow the filters (for instance by date range) and export again.

The three ways to get the result

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 file is ready (up to 20 seconds by default) and returns { data }.
Control how long to wait with the standard Prefer: wait=N header (seconds, clamped to 55):
  • 200: done. Body is { "data": … } as above.
  • 202: not done 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 generating, come back for it.” A portfolio of tens of thousands of actuaciones routinely takes longer than the default 20-second wait.

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.
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. Polling has its own generous rate-limit bucket. Jobs are scoped to your organization; a job belonging to another organization 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 file is ready, with no polling.
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.
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:
  • data is populated only when status is completed. Otherwise it’s null.
  • error is populated only when the job has failed, as { "type", "code", "message" } with code: "job_failed".

Statuses

What’s in the file

Columns are the same whether you pick csv or jsonl. Nested values (metadata) are serialized as JSON text in CSV cells.
id, registration_number, plaintiff_name, defendant_name, defendant_id, office, status, registration_date, last_discovery_date, is_private, latest_action_message, latest_action_date, metadata.The two latest_action_* columns carry the most recent actuación of each case, so the file reads like the portfolio view in the dashboard.

Headers reference

POST /v1/exports

Full request and response schema, with the filters per entity.

Errors

How failures and the error object work.