> ## Documentation Index
> Fetch the complete documentation index at: https://docs.doconda.com/llms.txt
> Use this file to discover all available pages before exploring further.

# How do I check a PDF for problems before sending it?

> Pass the PDF with operation review: with no AI, Doconda returns the fixed PDF and a report with every problem and its page.

To check a PDF programmatically, upload it and ask for `operation: "review"`. With no AI, Doconda returns the same
PDF with the safe fixes applied (for example, a text layer on scanned pages) and a report with every problem left
and which page it's on.

## Steps

1. Store your API key in `DOCONDA_API_KEY` and install the SDK (`pip install doconda` or `npm install @doconda/sdk`).
2. Upload the PDF with `files.upload`.
3. Ask for the review, read the report and download the fixed PDF.

<CodeGroup>
  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
  from pathlib import Path
  from doconda import Doconda

  doconda = Doconda()  # reads the key from DOCONDA_API_KEY
  file = doconda.files.upload("proposal.pdf")
  reviewed = doconda.documents.create(operation="review", file=file["id"])
  report = doconda.documents.report(reviewed["id"])

  for issue in report["issues"]:
      print(issue["severity"], issue["code"], issue["message"], issue["location"].get("pages"))
  if reviewed["status"] in ("ready", "ready_with_warnings"):
      Path("proposal-reviewed.pdf").write_bytes(doconda.documents.download(reviewed["id"], "pdf"))
  ```

  ```ts TypeScript theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
  import { readFile, writeFile } from "node:fs/promises"
  import { Doconda } from "@doconda/sdk"

  const doconda = new Doconda()
  const file = await doconda.files.upload(await readFile("proposal.pdf"), "proposal.pdf")
  const reviewed = await doconda.documents.create({ operation: "review", file: file.id })
  const report = await doconda.documents.report(reviewed.id)

  for (const issue of report.issues) console.log(issue.severity, issue.code, issue.message, issue.location.pages)
  if (reviewed.status === "ready" || reviewed.status === "ready_with_warnings") {
    await writeFile("proposal-reviewed.pdf", await doconda.documents.download(reviewed.id, "pdf"))
  }
  ```
</CodeGroup>

## What it checks in a PDF

* **Fixed automatically**: scanned pages with no text (`pdf.no_text_layer`, an invisible text layer is added so you can
  search and copy), missing title (`pdf.title_missing`) and missing language (`pdf.language_missing`).
* **Reported**: fonts not embedded, blank pages, mixed page sizes, sideways text, images under 150 dpi, untagged PDF
  (accessibility), broken internal links, empty form fields and leftover comments.
* In every format, an amount in words that doesn't match the figure (`money.words_mismatch`).

## What you get back

* `status`: `ready` (no problems, or all fixed), `ready_with_warnings` (minor warnings) or `needs_review` (something is
  left that can't be fixed without changing your content).
* The report: `ledger` with each fix (applied or rejected, and why) and `issues` with what's left, with its pages in
  `location.pages`.
* It never changes your text or your values: a mistyped amount is flagged, not corrected.

## Limits

* Password-protected PDFs and files that aren't the format they claim are rejected.
* Whatever is removed for safety (actions on open, embedded files…) is listed in `sanitized.removed`.

## FAQ

<AccordionGroup>
  <Accordion title="Does it use AI?">
    No. The review uses no AI.
  </Accordion>

  <Accordion title="Does it work for Word, PowerPoint and Excel?">
    Yes, with the same call. Each format has its own list of checks in [Review](/en/guides/review).
  </Accordion>

  <Accordion title="What if I only want the PDF's text?">
    Use [`extract`](/en/guides/extract): it returns the PDF as Markdown, with OCR for scanned pages.
  </Accordion>
</AccordionGroup>

## Keep reading

* [Review](/en/guides/review) and [Review and fix a Word file](/en/tutorials/review-word).
* [Quickstart](/en/quickstart).


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