> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.cloudraker.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.cloudraker.com/_mcp/server.

# Quickstart

One `POST` turns a document into JSON. `"citations": true` adds the evidence behind every field. This page gets you there. It then shows two moves you need next: how to avoid blocking on long documents, and how to reuse a file you already sent.

## What you'll need

* A CloudRaker account with the **admin** role in your organization. Only admins can create keys.
* A terminal with `curl`.

## Get a key

In the CloudRaker web app, open **Admin → API keys** and click **Create API key**. The app shows the full key value **once**. Copy it and store it in a safe place. The walkthrough with screenshots is in [API keys](/workspace/admin/api-keys).

The API returns the plaintext key only once. You can never retrieve it again. If you lose it, revoke the key and create a new one.

```bash
export CLOUDRAKER_API_KEY="sk_…"
```

## Extract a document

The call below reads a blank IRS Form W-9 from a URL. There is no upload, no local file, and no setup. Replace the URL with your own document when ready. Or download the fictional sample invoice and [upload it](/paperwork/developers/files#presigned-upload) to try a business document.

```bash
curl -X POST https://api.cloudraker.com/v1/extract \
  -H "Authorization: Bearer $CLOUDRAKER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "file": { "url": "https://www.irs.gov/pub/irs-pdf/fw9.pdf", "name": "w9.pdf" },
    "citations": true,
    "schema": {
      "type": "object",
      "properties": {
        "business_name": { "type": ["string", "null"] },
        "tax_classification": { "type": ["string", "null"] }
      }
    }
  }'
```

The response is the finished run. Read two things:

* **`output.value`** — your data, shaped like your schema.
* **`output.citations`** — for each field, the source file, page, and region on the page. Use this to show a human the evidence. Page indexes are 0-based. Boxes are normalized to the page (`0`–`1`, top-left origin).

Citations are an add-on. Turn them on per request with `"citations": true`. When off, the output has no `citations` key. When on, every filled field comes back cited or declared absent. A field the documents do not contain gets `{"fileId": "…", "notFound": true}` and a `null` value, never a guess.

```json
{
  "object": "extract_run",
  "id": "exr_01KYD1J8QW2RN4T6VXZ0ABCDEF",
  "status": "processed",
  "expiresAt": "2026-07-26T15:57:41.907Z",
  "statusUrl": "/v1/runs/exr_01KYD1J8QW2RN4T6VXZ0ABCDEF",
  "files": [{ "id": "b88ea8f9-20d4-4704-b379-ddee5a23c678", "name": "w9.pdf", "status": "processed" }],
  "output": {
    "value": { "business_name": null, "tax_classification": "Individual/sole proprietor or single-member LLC" },
    "citations": {
      "tax_classification": [
        { "fileId": "b88ea8f9-20d4-4704-b379-ddee5a23c678", "page": 0, "bbox": { "x": 0.086, "y": 0.379, "width": 0.261, "height": 0.016 }, "text": "Individual/sole proprietor or single-member LLC", "confidence": 5 }
      ],
      "business_name": [
        { "fileId": "b88ea8f9-20d4-4704-b379-ddee5a23c678", "notFound": true }
      ]
    },
    "documents": [{ "fileId": "b88ea8f9-20d4-4704-b379-ddee5a23c678", "name": "w9.pdf", "status": "done", "value": { "business_name": null, "tax_classification": "Individual/sole proprietor or single-member LLC" } }]
  }
}
```

`null` means the document does not contain the field. For this reason, declare every field in the schema nullable. This is also why `business_name` above comes back with a `notFound` citation, not a value. This rule and the other four schema rules are in the [extraction schema dialect](/paperwork/capabilities/extract/schema).

## Don't block on slow documents

The call above is synchronous. It holds until the run finishes, up to **60 seconds** by default and **120** at most (`?wait=`). At the cap you do not get a timeout error. You get a `202` with a handle to the same run:

```json
{
  "object": "extract_run",
  "id": "exr_01KYD1J8QW2RN4T6VXZ0ABCDEF",
  "status": "processing",
  "statusUrl": "/v1/runs/exr_01KYD1J8QW2RN4T6VXZ0ABCDEF"
}
```

Long audio, hundred-page scans, and large batches usually land here. If your caller cannot hold a request open, ask for the handle immediately with `?wait=0`:

```bash
curl -X POST "https://api.cloudraker.com/v1/extract?wait=0" \
  -H "Authorization: Bearer $CLOUDRAKER_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: invoice-4471" \
  -d '{ "file": { "url": "https://www.irs.gov/pub/irs-pdf/fw9.pdf" }, "schema": { "type": "object", "properties": { "business_name": { "type": ["string", "null"] } } } }'
```

An `Idempotency-Key` makes retries safe. A replay returns the original run and an `idempotent-replay: true` response header. It does not start a second run.

## Track a run

```bash
curl "https://api.cloudraker.com/v1/runs/exr_01KYD1J8QW2RN4T6VXZ0ABCDEF?wait=30" \
  -H "Authorization: Bearer $CLOUDRAKER_API_KEY"
```

`GET /v1/runs/:id` returns the same run body as the original call. It takes the same `?wait=`, so you can long-poll instead of polling in a tight loop. `status` moves through:

| Status        | Meaning                                                      |
| ------------- | ------------------------------------------------------------ |
| `queued`      | Accepted, not started yet.                                   |
| `processing`  | Reading the document or running the capability.              |
| `processed`   | Finished. `output` is present.                               |
| `failed`      | Terminal failure. Per-file causes are on `files[].error`.    |
| `cancelled`   | You cancelled it.                                            |
| `expired`     | Past its `ttl`. The run and its files are gone.              |
| `needs_input` | Waiting on a human step. Not reachable for extract or parse. |

Runs clean themselves up. `ttl` (seconds, default **24 hours**, max **7 days**) sets when the run and its files are purged. `expiresAt` on the run body gives the time. The [Runs](/paperwork/developers/runs) page covers cancelling, purging early, downloading a produced file, and keeping a result in the product.

To avoid polling, point `webhook` at your endpoint. You get notified when the run reaches a terminal state. See [Webhooks](/paperwork/developers/webhooks).

## Reuse a file

Every run returns file ids. Pass one back as `{"id": …}`. The API does not fetch or parse the document again. The second extraction starts from the existing parse. This is faster and cheaper than sending the URL twice.

```bash
curl -X POST https://api.cloudraker.com/v1/extract \
  -H "Authorization: Bearer $CLOUDRAKER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "file": { "id": "b88ea8f9-20d4-4704-b379-ddee5a23c678" },
    "schema": { "type": "object", "properties": { "requester_name": { "type": ["string", "null"] } } }
  }'
```

This works across capabilities. [Parse](/paperwork/capabilities/parse) a document once, then run several narrow extractions against its file id. Send up to 100 files in one run with `files: [...]` instead of `file`.

File ids live as long as the run that created them. A `DELETE` on the run removes the files. So does the `ttl` elapsing. Reuse the ids inside the window, or set a longer `ttl` on the first call.

## Where to go next

#### [Extract](/capabilities/extract)

Every configuration field — actions, instructions, `unit`, judging, batches.

#### [Redact, fill, sign](/capabilities/redact)

The other capabilities: [redact](/paperwork/capabilities/redact), [fill](/paperwork/capabilities/fill), [sign](/paperwork/capabilities/sign).

#### [Pipelines](/capabilities/pipeline)

Several capabilities over one file set, in a single call.

#### [Saved configs](/capabilities/actions)

Save a configuration once and call it by name.

#### [Files](/developers/files)

Register a document once — by URL or presigned upload — and reuse it.

#### [Runs](/developers/runs)

Statuses, outputs, TTL, and keeping a result in the product.

#### [Webhooks](/developers/webhooks)

Signed events instead of polling, with saved endpoints and a delivery log.

#### [Errors](/developers/errors)

The error envelope, the codes, and the failures worth a retry.