> ## Documentation Index
> Fetch the complete documentation index at: https://unfold-0a6049eb.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Documents and jobs

> Store a document and run explicit provider executions.

## Store a document

Every create request requires an `Idempotency-Key` between 8 and 255 characters.

```bash theme={null}
curl https://unfold.unfold-app.workers.dev/api/v1/documents \
  --request POST \
  --header "Authorization: Bearer $FILEROUTER_API_KEY" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: document-01J2Y9QX3M" \
  --data '{"url":"https://example.com/report.pdf"}'
```

For an upload, send `application/octet-stream` with the original filename and
content type:

```bash theme={null}
curl https://unfold.unfold-app.workers.dev/api/v1/documents \
  --request POST \
  --header "Authorization: Bearer $FILEROUTER_API_KEY" \
  --header "Content-Type: application/octet-stream" \
  --header "X-Unfold-Content-Type: application/pdf" \
  --header "X-Unfold-Filename: report.pdf" \
  --header "Idempotency-Key: document-01J2Y9QX3M" \
  --data-binary @report.pdf
```

The response contains an immutable document ID that can be reused across jobs
until its `expiresAt` time, seven days after upload.

Release the source and retained results while preserving job history when you
no longer need the artifacts. Every job for the document must be terminal;
release returns `409 document_active` while any job is queued or running.

```bash theme={null}
curl https://unfold.unfold-app.workers.dev/api/v1/documents/DOCUMENT_ID/release \
  --request POST \
  --header "Authorization: Bearer $FILEROUTER_API_KEY"
```

## Create a job

Each provider entry is an independent execution. Provider-specific options stay
on that entry instead of leaking into the rest of the job.

```bash theme={null}
curl https://unfold.unfold-app.workers.dev/api/v1/jobs \
  --request POST \
  --header "Authorization: Bearer $FILEROUTER_API_KEY" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: job-01J2Y9QX3M" \
  --data '{
    "documentId": "550e8400-e29b-41d4-a716-446655440000",
    "providers": [
      {
        "key": "primary",
        "provider": "llamaparse",
        "outputs": ["markdown", "tables"]
      },
      {
        "key": "inspection",
        "provider": "liteparse",
        "outputs": ["pages"],
        "pageFields": ["markdown"],
        "providerOptions": { "ocr": "auto" }
      }
    ]
}'
```

`key` is a caller-defined identifier unique within the job. It lets one
provider appear more than once with different options. If an entry omits
`outputs`, Unfold requests `markdown`. `pageFields`
requires the `pages` output and limits the fields retained on each page.
`pageNumber` and `warnings` are always retained.

A new job returns `202 Accepted`. Reusing the same `Idempotency-Key` header with
the same request returns the existing job and `Idempotent-Replayed: true`;
changing the request with that header returns a conflict.

## Poll and retrieve results

```bash theme={null}
curl https://unfold.unfold-app.workers.dev/api/v1/jobs/550e8400-e29b-41d4-a716-446655440000 \
  --header "Authorization: Bearer $FILEROUTER_API_KEY"
```

Jobs move through `queued`, `running`, and then `complete` or `failed`. The job
contains one execution per provider entry, including its key, provider, status, duration, usage, and
result availability. Results stay separate so one slow or failed provider does
not hide successful work.

```bash theme={null}
curl https://unfold.unfold-app.workers.dev/api/v1/executions/EXECUTION_ID/result \
  --header "Authorization: Bearer $FILEROUTER_API_KEY"
```

The TypeScript SDK's `parse` and `compare` methods perform these steps for you.
Use `router.documents`, `router.jobs`, and `router.executions` when your app
needs to persist IDs or compose its own workflow. Use
`router.jobs.waitForExecution(job, execution)` to consume one execution without
waiting for the complete job. Call
`router.documents.release(documentId)` to remove stored artifacts or
`router.documents.delete(documentId)` to remove the document and its job history.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.