# Parse (/features/parse)

<!-- agent-signals: reading_time_min: 4 · est_tokens: 1633 · updated: 2026-07-30 -->
Related: [Search](/features/search.md), [Search Highlights](/features/search-highlights.md), [Research Index](/features/research.md), [Scrape](/features/scrape.md), [Faster Scraping](/features/fast-scraping.md), [Batch Scrape](/features/batch-scrape.md)

The `/parse` endpoint converts local or non-public documents into clean, LLM-ready data. Upload file bytes via `multipart/form-data` and get back Markdown, JSON, HTML, links, images, or a summary — with reading order and tables preserved.

* Turn PDF, DOCX, XLSX, HTML, and more into Markdown or structured JSON
* Up to **5x faster** parsing via a Rust-based engine
* Files up to **50 MB** per request
* Zero Data Retention support

## When to use `/parse` [#when-to-use-parse]

Use `/parse` when the source document is **a local file** or **not publicly accessible by URL**. If you have a public URL that points to a document, prefer [`/scrape`](/features/scrape) — it auto-detects the file type from the extension or content type and parses it the same way.

| Source                                                           | Endpoint                                         |
| ---------------------------------------------------------------- | ------------------------------------------------ |
| Public URL to a document (e.g. `https://example.com/report.pdf`) | [`POST /scrape`](/api-reference/endpoint/scrape) |
| Local file or non-public bytes (PDF, DOCX, XLSX, HTML, ...)      | [`POST /parse`](/api-reference/endpoint/parse)   |

<Tip>
  **Using Firecrawl through MCP?** Use `firecrawl_parse` for local files. Local MCP can read the file directly when configured with `FIRECRAWL_API_URL`. Remote hosted MCP returns a short-lived upload command first, then parses the returned `uploadRef`. Public document URLs should still use `/scrape`.
</Tip>

<Tip>
  **Have a public PDF URL?** Use `/scrape` instead -- it auto-detects document types and returns clean markdown. No need for a separate PDF library.

  ```python title="Python"
  doc = firecrawl.scrape("https://example.com/report.pdf", formats=["markdown"])
  ```
</Tip>

## Parsing [#parsing]

### /parse endpoint [#parse-endpoint]

Used to upload a file and receive parsed content. The request is `multipart/form-data` with a required `file` part and an optional `options` JSON part.

**Supported extensions:** `.html`, `.htm`, `.pdf`, `.docx`, `.doc`, `.odt`, `.rtf`, `.xlsx`, `.xls`.

### Usage [#usage]

<CodeGroup>
  <CodeBlockTabs defaultValue="Python" groupId="curl+node+python">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="Python">
        Python
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="Node">
        Node
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="cURL">
        cURL
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="Python">
      ```python  
      from firecrawl import Firecrawl

      firecrawl = Firecrawl(api_key="fc-YOUR-API-KEY")

      doc = firecrawl.parse("./report.pdf")

      print(doc.markdown)
      ```
    </CodeBlockTab>

    <CodeBlockTab value="Node">
      ```javascript  
      import { Firecrawl } from "firecrawl";
      import fs from "node:fs";

      const firecrawl = new Firecrawl({ apiKey: "fc-YOUR-API-KEY" });

      const doc = await firecrawl.parse({
        data: fs.readFileSync("./report.pdf"),
        filename: "report.pdf",
      });

      console.log(doc.markdown);
      ```
    </CodeBlockTab>

    <CodeBlockTab value="cURL">
      ```bash  
      curl -X POST https://api.firecrawl.dev/v2/parse \
        -H 'Authorization: Bearer YOUR_API_KEY' \
        -F 'file=@./report.pdf' \
        -F 'options={"formats":["markdown"]};type=application/json'
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>

### Response [#response]

SDKs return the document object directly. cURL returns the JSON payload.

```json
{
  "success": true,
  "data": {
    "markdown": "# Annual Report\n\n...",
    "metadata": {
      "title": "Annual Report",
      "numPages": 42,
      "totalPages": 42,
      "sourceFile": "report.pdf"
    }
  }
}
```

<Note>
  `numPages` is the number of pages actually parsed; `totalPages` is the document's
  true page count. They match unless `maxPages` truncated the result — e.g. parsing
  a 100-page PDF with `maxPages: 10` returns `numPages: 10` and `totalPages: 100`, so
  `totalPages > numPages` tells you the output was truncated. `totalPages` is omitted
  when the page count can't be determined.
</Note>

## Options [#options]

`/parse` accepts a subset of scrape options under the `options` field. Common settings:

* `formats`: Array of output formats. Defaults to `["markdown"]`. Supported: `markdown`, `html`, `rawHtml`, `links`, `images`, `summary`, and `json` (with a schema or prompt).
* `onlyMainContent`: Only return the main content of the document. Defaults to `true`.
* `includeTags` / `excludeTags`: Tag-level inclusion or exclusion (HTML inputs).
* `redactPII`: Redact personally identifiable information from returned markdown.
* `timeout`: Request timeout in milliseconds. Defaults to `30000`, max `300000`.
* `parsers`: File-parser controls. For PDFs, set `{ "type": "pdf", "mode": "fast" | "auto" | "ocr", "maxPages": <int> }`.

<Note>
  `/parse` does not support browser-only options like `actions`, `waitFor`, `location`, `mobile`, or change tracking.
</Note>

### PDF parser modes [#pdf-parser-modes]

```bash title="cURL"
curl -X POST https://api.firecrawl.dev/v2/parse \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -F 'file=@./scan.pdf' \
  -F 'options={"parsers":[{"type":"pdf","mode":"ocr","maxPages":50}]};type=application/json'
```

* `fast`: text-only extraction, fastest path.
* `auto` (default): text-first with OCR fallback for image-only pages.
* `ocr`: OCR every page — use for scanned documents.

### Structured JSON output [#structured-json-output]

Pass a JSON schema or prompt to extract structured data directly from the document:

```bash title="cURL"
curl -X POST https://api.firecrawl.dev/v2/parse \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -F 'file=@./invoice.pdf' \
  -F 'options={"formats":[{"type":"json","schema":{"type":"object","properties":{"total":{"type":"number"},"vendor":{"type":"string"}}}}]};type=application/json'
```

## Considerations [#considerations]

* Maximum file size is **50 MB** per request.
* Parsing very large or scanned PDFs in `ocr` mode may take longer — increase `timeout` or use `maxPages` to bound the work.
* For batches of files, call `/parse` per file in parallel; there is no batch upload variant.

> Are you an AI agent that needs a Firecrawl API key? See [firecrawl.dev/agent-onboarding/SKILL.md](https://www.firecrawl.dev/agent-onboarding/SKILL.md) for automated onboarding instructions.
