> 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.

# Parse

`POST /v1/parse` takes one document. It returns readable markdown plus a structured JSON representation with layout and page information. It needs no schema and no configuration. Use it when you want the document's content, not specific fields.

## How it works

1. You send a **file**: a URL, or the id of a file you already have.
2. CloudRaker fetches the bytes and reads the document. Born-digital PDFs are read directly, scans through OCR, office files through conversion, and audio through transcription.
3. The call **holds until parsing finishes**, up to `?wait=` seconds (60 by default, 120 max). If parsing finishes in time, you get `200` with download URLs. If not, you get `202` with a run id to poll.
4. The run and its files expire on their own (`ttl`, 24 hours by default).

Extraction parses too, so you do not need to call this first. [`POST /v1/extract`](/paperwork/capabilities/extract) parses as part of the run.

## Quickstart

The sample below uses a blank IRS Form W-9 as a public, stable test document. The call works with no local files.

```bash title="curl"
curl -X POST https://api.cloudraker.com/v1/parse \
  -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" }
  }'
```

```ts title="TypeScript"
const res = await fetch("https://api.cloudraker.com/v1/parse", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CLOUDRAKER_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    file: { url: "https://www.irs.gov/pub/irs-pdf/fw9.pdf", name: "w9.pdf" },
  }),
});

const run = await res.json();
const markdown = run.output?.markdownUrl
  ? await (await fetch(run.output.markdownUrl)).text()
  : undefined;
```

```python title="Python"
import os, requests

res = requests.post(
    "https://api.cloudraker.com/v1/parse",
    headers={"Authorization": f"Bearer {os.environ['CLOUDRAKER_API_KEY']}"},
    json={"file": {"url": "https://www.irs.gov/pub/irs-pdf/fw9.pdf", "name": "w9.pdf"}},
)

run = res.json()
markdown_url = run.get("output", {}).get("markdownUrl")
markdown = requests.get(markdown_url).text if markdown_url else None
```

The TypeScript and Python samples are plain HTTP, so they run with nothing installed. This endpoint is also a top-level method on both [SDKs](/paperwork/developers/sdks) as of 0.3.0: `client.parse(…)`. That page has a full worked example.

## Example response

```json
{
  "object": "parse_run",
  "id": "par_01KYD1M2XT5Q8VB3NRWY7CDEFG",
  "status": "processed",
  "expiresAt": "2026-07-26T15:57:41.907Z",
  "statusUrl": "/v1/runs/par_01KYD1M2XT5Q8VB3NRWY7CDEFG",
  "files": [
    { "id": "4c9de1b7-8a30-42f5-b0e6-1d7f5c2a9b44", "name": "w9.pdf", "status": "processed" }
  ],
  "file": { "id": "4c9de1b7-8a30-42f5-b0e6-1d7f5c2a9b44", "name": "w9.pdf", "status": "processed" },
  "output": {
    "markdownUrl": "https://cdn.cloudraker.com/acme/4c9de1b7-8a30-42f5-b0e6-1d7f5c2a9b44/processed.md?token=…&fn=w9.pdf",
    "jsonUrl": "https://cdn.cloudraker.com/acme/4c9de1b7-8a30-42f5-b0e6-1d7f5c2a9b44/processed.json?token=…&fn=w9.pdf"
  }
}
```

## Key fields

| Field                | What it is                                                                                                                           |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `object`             | Always `parse_run`.                                                                                                                  |
| `id`                 | The run id (`par_…`). Use it with [`GET /v1/runs/:id`](/paperwork/developers/quickstart#track-a-run).                                |
| `status`             | `queued`, `processing`, `processed`, `failed`, `cancelled`, `expired`, or `needs_input`.                                             |
| `expiresAt`          | When the run and its files are purged. Controlled by `ttl`.                                                                          |
| `files[]`            | The input file with its own `status` and, on failure, `error`. `file` is an alias for `files[0]`.                                    |
| `output.markdownUrl` | Time-limited download URL for the markdown rendering. Absent for audio and video.                                                    |
| `output.jsonUrl`     | Time-limited download URL for the structured JSON: text blocks with page and position. For a recording it is the transcript instead. |

`output` appears only after `status` is `processed`. The download URLs are short-lived. Fetch the content instead of storing the URL.

A recording produces no markdown. Its `output.jsonUrl` holds the [transcript](/paperwork/developers/files#audio-transcripts): a `language` and an ordered `segments` array with timings, text, and speaker labels.

Reuse the returned file id (`files[0].id`) in later calls. Pass `{"file": {"id": "<file id>"}}` to [extract](/paperwork/capabilities/extract). The document is then not fetched or parsed again.

## Configuration

| Field      | Type                                  | What it does                                                                                            |
| ---------- | ------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| `file`     | `{url, name?, processing?}` or `{id}` | **Required.** The document to parse.                                                                    |
| `metadata` | object                                | Your own key/values, echoed back on the run body (not on webhook deliveries). Max 10 KB serialized.     |
| `webhook`  | `{url}` or `{id}`                     | Where to deliver the terminal event instead of polling. See [Webhooks](/paperwork/developers/webhooks). |
| `ttl`      | integer seconds, 1–604800             | How long the run and its file live. Default 24 hours, max 7 days.                                       |

`processing` on the file ref picks how the document is read:

| Value                | Use for                                                        |
| -------------------- | -------------------------------------------------------------- |
| `auto`               | Default. Picks per document.                                   |
| `simple`             | Born-digital PDFs with a real text layer. Fastest.             |
| `ocr`                | Scans and photographed pages.                                  |
| `transcribe`         | Audio with one speaker, or when speaker labels are not needed. |
| `transcribe_diarize` | Audio where you need speaker separation.                       |

## Sync vs async

Identical to [extract](/paperwork/capabilities/extract#sync-vs-async): synchronous by default, with `?wait=` between `0` and `120` seconds. When the cap is reached, you get a `202` handle, not a timeout error.

```json
{
  "object": "parse_run",
  "id": "par_01KYD1M2XT5Q8VB3NRWY7CDEFG",
  "status": "processing",
  "statusUrl": "/v1/runs/par_01KYD1M2XT5Q8VB3NRWY7CDEFG"
}
```

Long audio and large scanned documents normally come back as `202`. For those, pass `?wait=0`, then poll or use a webhook.

## Save as a config

Parsing has no configuration to save. There is no `/v1/parse/configs` library and nothing in `GET /v1/actions/catalog`. The [saved-config path](/paperwork/capabilities/actions) applies to extract, redact, and fill.

## Next steps

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

Get specific fields as JSON, with a citation behind each one.

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

Register a file, upload the bytes, and reuse it across runs.

#### [Quickstart](/developers/quickstart)

Key, first call, reusing files, and tracking runs.

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

Get a notification when a run finishes instead of polling.