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

# Idempotency and cleanup

> Safe retries, retention windows, and cleaning up hosted documents.

Hosted Unfold is a job system: store a document, run executions, retain results for a while, then clean up. Treat document IDs, job IDs, and idempotency keys as part of your application contract.

## Idempotent creates

Document and job creates require an `Idempotency-Key` header. The SDK generates a UUID when you omit one. Replaying the **same key with the same body** returns the existing resource instead of starting a second billed run. Changing the body with the same key conflicts.

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

const router = new Unfold()
const claimId = "claim_123"

const document = await router.documents.create("./claim.pdf", {
  fileName: "claim.pdf",
  mimeType: "application/pdf",
  idempotencyKey: `doc:${claimId}`,
})

// Job idempotency key is the second argument, not a field on the job body.
const accepted = await router.jobs.create(
  {
    documentId: document.id,
    providers: [
      { key: "primary", outputs: ["markdown"], provider: "liteparse" },
    ],
  },
  { idempotencyKey: `job:${claimId}:liteparse` }
)
```

Derive keys from your business ID when a queue consumer or webhook might retry.

`parse` and `compare` also accept `idempotencyKey`. The client uses it for the job (and a derived key for the document) so a retried convenience call does not double-submit.

## Retention

From the hosted product rules:

| Resource | Retention |
| - | - |
| Source document | 7 days from upload (`expiresAt` on the document) |
| Normalized results | Available while retained; tied to the document cleanup window |
| Job records | Scheduled for deletion after 30 days |

Storage in these windows does not consume credits. Do not rely on expiry for sensitive data. Release stored artifacts when the workflow finishes.

## Cleanup after a job

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

const router = new Unfold()
const claimId = "claim_123"

const document = await router.documents.create("./claim.pdf", {
  fileName: "claim.pdf",
  mimeType: "application/pdf",
  idempotencyKey: `doc:${claimId}`,
})

try {
  const accepted = await router.jobs.create(
    {
      documentId: document.id,
      providers: [
        { key: "primary", outputs: ["markdown"], provider: "liteparse" },
      ],
    },
    { idempotencyKey: `job:${claimId}:liteparse` }
  )

  const job = await router.jobs.wait(accepted)
  const execution = job.executions.find((item) => item.key === "primary")

  if (execution?.status === "complete" && execution.resultAvailable) {
    const result = await router.executions.result(execution.id)
    // Persist result.outputs.markdown (and any other fields you need) in your DB
    console.log(result.pageCount, result.timing.durationMs)
  }
} finally {
  await router.documents.release(document.id)
}
```

`documents.release` removes the source and retained results while preserving job and execution records. It refuses while a job is active.

`documents.delete` removes the document, related jobs, and retained results. Use it when you do not need the history.

For hosted `parse` / `compare`, release via the returned resources when you no longer need retained outputs:

```ts theme={null}
const parsed = await router.parse("./claim.pdf", {
  provider: "liteparse",
  outputs: ["markdown"],
})
await router.documents.release(parsed.resources.documentId)
```

## Partial failure

In a multi-provider job, one execution can fail while another completes. Read per-execution `status` and `resultAvailable`. Do not treat the whole job as useless because a single engine timed out.

## Related

* [Documents and jobs](/api/jobs)
* [Processing modes](/concepts/processing-modes)
* [How Unfold works](/concepts/how-it-works)


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