Pipelines

Run several capabilities over one set of files in a single call.
View as Markdown

POST /v1/pipeline takes one file set and a list of steps. CloudRaker parses each file once. Each step then runs over the parsed set. This JSON, inline-config API replaces the multipart /process API.

Steps run in parallel over the same files. Steps are not chained. A step never consumes the output of a different step. You cannot redact the output of a fill step. Each step reads the original file set.

How it works

  1. You send files (URLs or file ids) and steps.
  2. Each step is one of {"extract": {…}}, {"redact": {…}}, {"fill": {…}}, or {"sign": {…}}. Each takes the same inline config as the matching verb. A step can also be {"action": "<id or slug>", "params": {…}} for a saved config. There is no parse step. Parsing is automatic.
  3. The response is 202. It contains the pipeline id (plr_…) and one typed id per step, in the order you sent them.
  4. GET /v1/runs/plr_… returns steps[]. Each step has its own id, capability, status, and result.

Quickstart

$curl -X POST https://api.cloudraker.com/v1/pipeline \
> -H "Authorization: Bearer $CLOUDRAKER_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{
> "files": [{ "url": "https://www.irs.gov/pub/irs-pdf/fw9.pdf", "name": "w9.pdf" }],
> "steps": [
> { "extract": { "citations": true, "schema": { "type": "object", "properties": { "form_number": { "type": ["string", "null"] } } } } },
> { "redact": { "categories": ["ein"], "mode": "targeted" } }
> ],
> "ttl": 86400
> }'

Example response

The create call returns the handle and the step ids:

1{
2 "object": "pipeline_run",
3 "id": "plr_01KYD7F40BGQA7WXB50ENSQEK1",
4 "status": "queued",
5 "statusUrl": "/v1/runs/plr_01KYD7F40BGQA7WXB50ENSQEK1",
6 "steps": [
7 { "id": "exr_01KYD7F40B35TT7XR1KPMFZXJ6", "capability": "extract" },
8 { "id": "rdr_01KYD7F40BDN07JRKXRERJYTRE", "capability": "redact" }
9 ]
10}

Poll GET /v1/runs/plr_…. The response returns the same step ids with attached results:

1{
2 "object": "pipeline_run",
3 "id": "plr_01KYD7F40BGQA7WXB50ENSQEK1",
4 "status": "processed",
5 "expiresAt": "2026-07-26T18:09:16.204Z",
6 "statusUrl": "/v1/runs/plr_01KYD7F40BGQA7WXB50ENSQEK1",
7 "files": [
8 { "id": "39c1759c-5f47-425a-9ef2-6b9efe51fb7a", "name": "w9.pdf", "status": "processed" }
9 ],
10 "steps": [
11 {
12 "id": "exr_01KYD7F40B35TT7XR1KPMFZXJ6",
13 "capability": "extract",
14 "status": "processed",
15 "output": {
16 "value": { "form_number": "W-9" },
17 "citations": {
18 "form_number": [
19 {
20 "fileId": "39c1759c-5f47-425a-9ef2-6b9efe51fb7a",
21 "page": 0,
22 "bbox": { "x": 0.0918, "y": 0.0376, "width": 0.0653, "height": 0.0364 },
23 "text": "Form W-9",
24 "confidence": 5
25 }
26 ]
27 },
28 "documents": [ /* one entry per input document */ ]
29 }
30 },
31 {
32 "id": "rdr_01KYD7F40BDN07JRKXRERJYTRE",
33 "capability": "redact",
34 "status": "processed",
35 "output": {
36 "file": { "id": "e130ad59-6309-44c7-bb27-1106a1c32621", "name": "w9 (redacted).pdf", "url": "https://cdn.cloudraker.com/…/latest?token=…" },
37 "files": [ /* one redacted file per input document */ ],
38 "entities": { "ein": 11 },
39 "skipped": 0
40 }
41 }
42 ]
43}

Key fields

FieldWhat it is
objectAlways pipeline_run.
idThe pipeline id (plr_…).
statusThe status of the pipeline: queued, processing, needs_input, processed, failed, cancelled, or expired.
files[]The shared, parsed-once input set.
steps[].idThe typed step id: exr_, rdr_, flr_, sgr_. null for a bare {"action": …} step.
steps[].capabilityextract, redact, fill, sign, or action.
steps[].statusThe status of that step. A failed step does not erase the results of the other steps.
steps[].outputExactly the output the matching verb returns.

Some sub-routes address the sign step: /envelope, /void, /audit, and /signers/:id/resend. A pipeline without a sign step answers 404 not_found.

Configuration

FieldTypeWhat it does
files[]array of {url, name?, processing?} or {id}, 1–100Required. Parsed once, shared by every step.
steps[]array, 1–20Required. The capabilities to run.
metadataobjectYour own key/values. The API echoes them back on the run body, not on webhook deliveries. Max 10 KB.
webhook{url} or {id}Where to deliver events. See Webhooks.
ttlinteger seconds, 1–604800How long the pipeline and its files live. Default 24 hours, max 7 days. A pipeline with a sign step is exempt while the envelope is open.

The API validates step configs the same way as the standalone verbs. An extract step without schema or action fails with 400 invalid_request. A schema that breaks the schema dialect fails with 400 invalid_schema. The codes and messages match POST /v1/extract. Defaults also match. An extract step is ungrounded unless it carries "citations": true. Without that flag, output.citations is absent.

Sync vs async

Pipelines are always asynchronous. POST /v1/pipeline returns 202 and takes no ?wait=. Poll GET /v1/runs/plr_…?wait=<seconds> (0–120) to long-poll for a terminal state. Or subscribe a webhook and wait for processing.completed.

Send an idempotency-key to make retries safe. A replay returns the original pipeline: its id, its current status, and its original step ids. The response carries an idempotent-replay: true header. The API does not start a second run.

Save as an action

Each step accepts a saved config instead of inline config. You can combine the two. Inline fields win:

1{
2 "files": [{ "id": "a04d6597-4e34-4a99-94ea-964c289a4c68" }],
3 "steps": [
4 { "extract": { "action": "medical-intake" } },
5 { "action": "hr-offboarding" }
6 ]
7}

{"extract": {"action": …}} keeps the step typed, so its id is exr_…. It also lets you override fields inline. A bare {"action": …} step runs the saved config with no changes. Its step id is null. See Saved configs.

Next steps