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

# Fast preview, then full parse

> Show a LiteParse result as soon as it is ready while a heavier engine keeps running.

Use this when the UI should update early, and you are willing to run two engines on the same document. Both executions start together, so you pay for both successful parses.

If you want to **avoid** starting the expensive engine until the cheap one looks weak, use [Cheap path, then escalate](/guides/cheap-path) instead.

## Pattern

1. Store the document once.
2. Create one job with a fast engine and a stronger engine.
3. `waitForExecution` on the fast provider and render.
4. `waitForExecution` on the strong provider and replace or merge.
5. Release the stored artifacts when you are done.

```ts theme={null}
import { Unfold } from "@file_router/sdk"

const router = new Unfold()

const document = await router.documents.create("./invoice.pdf", {
  fileName: "invoice.pdf",
  mimeType: "application/pdf",
})

try {
  const job = await router.jobs.create({
    documentId: document.id,
    providers: [
      {
        key: "preview",
        outputs: ["markdown", "pages"],
        provider: "liteparse",
        pageFields: ["markdown"],
        providerOptions: { ocr: "auto" },
      },
      {
        key: "full",
        outputs: ["markdown", "pages"],
        provider: "llamaparse",
      },
    ],
  })

  const previewRef = job.executions.find((item) => item.key === "preview")
  if (!previewRef) throw new Error("Preview execution was not created.")
  const preview = await router.jobs.waitForExecution(job, previewRef)
  if (preview.status === "complete" && preview.resultAvailable) {
    const fast = await router.executions.result(preview.id)
    // Render draft UI from fast.outputs.markdown
    console.log("preview", fast.outputs.markdown?.slice(0, 200))
  }

  const fullRef = job.executions.find((item) => item.key === "full")
  if (!fullRef) throw new Error("Full execution was not created.")
  const strong = await router.jobs.waitForExecution(job, fullRef)
  if (strong.status === "complete" && strong.resultAvailable) {
    const full = await router.executions.result(strong.id)
    // Replace draft UI with full.outputs.markdown
    console.log("final", full.timing.durationMs, full.pageCount)
  }
} finally {
  await router.documents.release(document.id)
}
```

## Why this works

* One stored document. Both engines see the same bytes.
* Executions are independent. A slow or failed LlamaParse run does not erase a finished LiteParse result.
* `waitForExecution` returns when that execution hits `complete` or `failed`. Sibling work can keep running.
* `preview` and `full` are caller-defined keys for this application; Unfold does not assign those roles.

## Output rules

Hosted job creation validates outputs per provider. If any selected provider does not advertise an output, the job create fails with `unsupported_provider_output`.

| Provider | Useful shared outputs |
| - | - |
| `liteparse` | `markdown`, `pages`, `text`, `images`, `metadata` |
| `pdf-inspector` | `markdown`, `pages`, `metadata` |
| `llamaparse` / `mistral-ocr` / `datalab` | broader sets including `tables` on some adapters |

For a shared job, stick to the intersection (usually `markdown` or `markdown` + `pages`). Need tables only from LlamaParse? Prefer [Cheap path, then escalate](/guides/cheap-path) with a second job, or set per-provider `outputs` on each target.

## Related

* [Cheap path, then escalate](/guides/cheap-path)
* [How Unfold works](/concepts/how-it-works)
* [Documents and jobs](/api/jobs)


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