Extract structured data from documents

View as Markdown
Runs JSON-Schema extraction with per-field citations over one or more files. Send exactly one of `file` or `files`, and at most one output shape: - **`schema`** — an inline JSON Schema object, written in the [extraction schema dialect](https://docs.cloudraker.com/capabilities/extract/schema). - **`action`** — a [saved action](https://docs.cloudraker.com/api/cloud-raker-api/actions/get-action) by id or slug. Inline config fields (`instructions`, `unit`, `judge`, …) are merged over the saved action's, so one saved action can be refined per call. - **neither** — the shape is inferred from the documents themselves. Add `hints` to steer it in prose. The finished run reports what was inferred as `config.schema`, ready to save as an action for the next run. **What you get back.** `output.value` holds the extracted object for a single-document run, `output.documents[]` one entry per file. `output.citations` maps each JSON path inside the value to where it came from — `fileId` plus page and bounding box, or a timecode for audio. Send `citations: false` to skip grounding. ```json { "file": { "url": "https://www.irs.gov/pub/irs-pdf/fw9.pdf" }, "schema": { "type": "object", "properties": { "business_name": { "type": ["string", "null"] }, "tax_classification": { "type": ["string", "null"] } } } } ``` ### Waiting for the result Sync by default: the call holds open until the run finishes, up to `?wait=` seconds (default `60`, max `120`, `0` returns immediately). | Outcome | Response | | --- | --- | | Finished inside the window | `200` with the full run | | Still running at the cap | `202` with `{object, id, status, statusUrl}` | | Parked for a human | `202` right away, `status: "needs_input"` plus `tasks[]` | <Note> The `202` is a graceful degrade, never an error — poll [the run](https://docs.cloudraker.com/api/cloud-raker-api/runs/get-run) or wait for a [webhook](https://docs.cloudraker.com/api/cloud-raker-api/webhooks/create-webhook-endpoint). Replaying an `idempotency-key` returns the original run alongside an `idempotent-replay: true` response header. </Note> **Learn more:** [Extraction guide](https://docs.cloudraker.com/capabilities/extract) · [Schema dialect](https://docs.cloudraker.com/capabilities/extract/schema)

Authentication

AuthorizationBearer

Bearer authentication of the form Bearer <token>, where token is your auth token.

Query parameters

waitintegerOptional0-120Defaults to 60
How many seconds to hold the request open waiting for the run to finish. Defaults to `60`, maximum `120`. Finishing inside the window returns `200` with the full run; running past it returns `202` with a `statusUrl` to poll. Send `0` to skip waiting entirely and always get the `202`.

Request

This endpoint expects an object.
schemamap from strings to anyOptional

The shape to extract, as a JSON Schema object. Send action instead to use a saved shape, or neither to have one inferred.

The root must be {"type": "object"}. The dialect is deliberately narrow — no \$ref, \$defs, oneOf, anyOf, allOf, const or pattern — with a maximum nesting depth of 5 and a 64 KB size limit. Make primitives nullable ({"type": ["string", "null"]}) so a missing value reads as null rather than a hallucination.

actionstringOptional>=1 character

A saved action to run, by id or slug. An alternative to schema.

The action carries the output shape and any saved settings. Config you send inline on the same call is merged over it, so action plus instructions refines a saved action for one run without redefining it.

hintsstringOptional<=2000 characters

Prose guidance for schema inference — only valid when you send neither schema nor action.

Say what the documents are and what matters in them (“freight bills of lading; I care about the load number, the shipper and the total”) and the shape is inferred from the document itself. Sending hints alongside schema or action is a 400: the shape is already decided.

instructionsstringOptional

Free-form guidance for the extraction, applied on top of the schema — house rules, formatting preferences, how to handle ambiguity.

citationsbooleanOptional

Whether to ground each extracted value in the source document. On by default.

When on, output.citations maps every JSON path in the result to where it came from — fileId plus page and bounding box for documents, or a timecode for audio. Set to false to skip grounding when you only need the values.

unitenumOptional

What one extraction result covers.

  • per_document — one result object per file (the default).
  • across_documents — one result object for the whole set, read as a single body of evidence.
  • rows_per_document — a list of results per file, for documents that hold repeated records.
modelstringOptional
Pin the extraction to a specific model. Leave it unset to use the current default, which tracks the best available.
judgebooleanOptional

Run a second review pass over the extracted values to catch mistakes. Slower and more thorough — worth it on documents where an error is expensive.

fileobjectOptional

A single input file. Send this or files, never both.

fileslist of objectsOptional

Several input files, up to 100. Send this or file, never both.

Each file gets its own entry in output.documents[] unless unit says otherwise.

metadatamap from strings to anyOptional

Arbitrary JSON you attach to the run and get back on every read of it.

Use it to carry your own identifiers — an order number, a customer id — so a webhook or a polled run reconciles without a lookup table. Capped at 10 KB serialized.

webhookobjectOptional

Where to deliver this run’s events, given one of two ways.

  • { "url": "…" } — a one-off https endpoint for this run only.
  • { "id": "whe_…" } — a saved endpoint from POST /v1/webhooks. Runs hold the reference, so pausing or re-pointing that endpoint applies to this run too.

Deliveries are at-least-once and signed — dedupe on eventId and verify against GET /v1/webhooks/jwks.json.

ttlintegerOptional1-604800

How long, in seconds, to keep this run and its files before purging them automatically.

Defaults to 24 hours; the maximum is 604800 (7 days). The deadline comes back as expiresAt on every read of the run. Call POST /v1/runs/{id}/keep before then to clear the TTL and move the results into a space permanently.

E-signature runs are exempt — an envelope waits for its signers however long that takes.

Response

The finished run.
object"extract_run"
idstring
statusenum

Where the run is in its life.

StatusMeaning
queuedAccepted, not started
processingWork in flight
needs_inputParked for a person — see tasks[]
processedFinished; output is populated
failedFinished unsuccessfully
cancelledStopped on request
expiredTTL elapsed and the data was purged

The last four are terminal.

expiresAtstring or null
statusUrlstring
fileslist of objects
fileobject
errorobject

Why the run failed. Present whenever status is failed, and only then.

code is the stable, snake_case reason (input_unavailable, parse_failed, …); message is the human-readable detail. Per-file and per-step failures are also reported in files[].error and, for a pipeline, steps[].error.

metadatamap from strings to any
taskslist of objects

The human steps currently blocking the run. Present while status is needs_input.

Each task has a url — a ready-made page you can send a person to — or you can drive it yourself through GET and POST /v1/runs/{id}/task. E-signature runs never carry tasks[]: their signing links are signer-held secrets, so use envelopeUrl instead.

configobject

The output shape this run actually applied.

On an inference run — one sent with neither schema nor action — this is where you read the schema that was inferred, ready to review and save as an action for the next run.

outputobject

The extracted data. Present once status is processed.

documents[] always has one entry per input file. For a single-document run, value and citations are lifted to the top as aliases of documents[0] so the common case reads without indexing.

Errors

400
Bad Request Error
422
Unprocessable Entity Error
429
Too Many Requests Error