Flagship Reference

Parse PDF

POST /v1/parse turns one uploaded PDF into a structured document tree plus optional Markdown, HTML, plain text, and annotated PDF artifacts. For up to 10 files in one request, use [Parse Batch](/parse-batch).

Reference
View as Markdown

Overview

Artifacts

Select artifacts with formats. Structured JSON is always produced; only one markdown-style format is allowed per job.

`formats` valueWhat it isUse it for
jsonHierarchical document tree — headings, paragraphs, lists, tables, cells, captions, images, with bounding boxes where availableAutomation, indexing, citations, structured QA
markdownFlattened text in reading orderPreviews, search indexing, LLM ingestion
markdown_with_htmlMarkdown that retains richer inline and table markupContent that loses meaning as plain Markdown
markdown_with_imagesImage-capable Markdown; a zip when image_output=externalDocuments where figures carry the meaning
htmlStyled companion documentRendering and human review
textPlain textLightweight search and simple ingestion
annotated_pdfSource pages overlaid with detected structureDebugging extraction before you trust it
tagged_pdfGenerated structure tree — inference, not a PDF/UA guaranteeAccessibility review workflows

Capabilities

Extraction Controls

Tuning knobs that change how text is extracted. Artifact selection is separate — see the table above. The parse status payload also includes result.metadata so you can inspect which extraction-tuning options were applied to a completed job.

ControlDefaultEffect
reading_order=xycut|offLayout-awareForce or disable reading-order reconstruction.
table_method=default|clusterdefaultUse cluster when the default path misses cell groupings.
use_struct_tree=truefalsePrefer the PDF's native structure tags when it has usable ones.
keep_line_breaks=truefalsePreserve source line breaks in text-oriented output.
include_header_footer=truefalseKeep repeated page furniture instead of dropping it.
sanitize=truefalseMask visible emails, URLs, and phone numbers in extracted output.
image_output=off|embedded|externalembeddedImage handling for image-capable formats.
page_rangeAll pagesSelect pages, e.g. 1-3,5,9-11. Selected pages set the credit cost.
hybrid_mode=auto|fullBackend-gatedRequires the hybrid backend to be enabled by operations.
OCR for scanned PDFsBackend-gatedWithout the hybrid OCR profile, image-only PDFs return ocr_required.
Formula and chart enrichmentBackend-gatedOnly when the active backend profile includes those enrichments.

Endpoint

Single-File Endpoint

POST/v1/parse

Submit a PDF for queued parsing and receive structured JSON plus Markdown, HTML, plain text, and annotated PDF debug output.

Auth

Bearer token required on submit, status, and artifact download requests.

Idempotency

Server-minted job_id values with optional Idempotency-Key replay support.

Content Type

multipart/form-data

Headers

NameTypeRequiredLocationDescription
AuthorizationBearer <API_KEY>YesheaderUser-owned API key created in the DocuShell dashboard.
Idempotency-KeystringNoheaderRecommended for safely retrying submit requests without creating duplicate jobs.

Request Fields

NameTypeRequiredLocationDescription
filefileYesmultipartPDF upload. The gateway validates PDF magic bytes before forwarding the file.
file_namestringNomultipartOptional file name override used for storage metadata and downstream artifact names.
page_rangestringNomultipartComma-separated pages or ranges such as 1-3,5,9-11.
include_header_footerbooleanNomultipartSet to true to keep header and footer content in the extracted output.Default: false
use_struct_treebooleanNomultipartSet to true to prefer native tagged-PDF structure when the source document includes a usable structure tree.Default: false
sanitizebooleanNomultipartSet to true to mask email addresses, URLs, and phone numbers in extracted output.Default: false
reading_order`xycut` | `off`NomultipartOptional reading-order strategy. Omit it to keep the current default extraction behavior.
table_method`default` | `cluster`NomultipartOptional table-detection strategy. Omit it to keep the current default extraction behavior.
keep_line_breaksbooleanNomultipartSet to true to preserve source line breaks more aggressively in text-oriented output.Default: false
output_mode`json` | `both` | `html` | `all`NomultipartBackward-compatible artifact bundle selector. json keeps only structured JSON, both adds Markdown, html adds HTML, and all returns the common legacy bundle: JSON, Markdown, HTML, text, and annotated PDF.Default: both
formats`json` | `markdown` | `html` | `text` | `annotated_pdf` | `markdown_with_html` | `markdown_with_images` | `tagged_pdf`NomultipartOptional explicit artifact list. Send as repeated fields or a comma-separated value, such as formats=json,text.
hybrid_mode`auto` | `full`NomultipartOptional per-job hybrid triage override. Requires the hybrid backend to be enabled by operations.
image_output`off` | `embedded` | `external`NomultipartControls image handling for image-capable outputs. markdown_with_images defaults to embedded images unless external is requested.

Request Notes

  • Plan limits are enforced before the job is queued. Starter keeps the 50 MB per-file cap; Pro, Growth, and Scale raise upload size, per PDF/job page limits, and concurrency as monthly credits grow.
  • Set use_struct_tree=true when tagged PDFs should favor their native structure tree. Leave it off for the default reading-order-oriented extraction path.
  • Structured JSON remains the canonical parse result and is always generated for successful jobs so status responses can keep returning result.document.
  • sanitize, reading_order, table_method, keep_line_breaks, hybrid_mode, and image_output are extraction-tuning knobs. output_mode and formats control which companion artifacts are emitted.
  • Request newer artifact types such as markdown_with_html, markdown_with_images, and tagged_pdf with formats; only one markdown-style format (markdown, markdown_with_html, or markdown_with_images) can be requested per job because the parse engine emits one Markdown-family file per run.
  • DocuShell keeps rendering-mismatch safety filters enabled for Parse PDF output. sanitize=true is a separate optional control for masking visible sensitive data.
  • OCR, formula extraction, and chart/image descriptions follow the active DocuShell backend profile. They are not per-request fields on the shared public API.
  • Status polling stays on /v1/jobs/:jobId. Artifact streaming happens through the shared download route with format=json|markdown|html|text|annotated_pdf|markdown_with_html|markdown_with_images|tagged_pdf.

Multipart submit

bash

curl -X POST "https://api.docushell.com/api/v1/parse" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Idempotency-Key: parse-demo-001" \
  -F "file=@./quarterly-report.pdf;type=application/pdf" \
  -F "file_name=quarterly-report.pdf" \
  -F "page_range=1-3" \
  -F "include_header_footer=true" \
  -F "use_struct_tree=true" \
  -F "sanitize=true" \
  -F "reading_order=xycut" \
  -F "table_method=cluster" \
  -F "keep_line_breaks=true" \
  -F "formats=json,markdown_with_images" \
  -F "image_output=embedded"

Try It Now

Console placeholder for safe sandbox execution.

Coming soon

Queued response

json

{
  "job_id": "job_01JX8Y5YJ2M2D8N1AQ5F7Q3KVT",
  "status": "queued",
  "cost": 24,
  "service": "parse-pdf",
  "request_id": "req_01JX8Y62XCDNZ2BM7TBM2M9Q8E",
  "links": {
    "status": "/v1/jobs/job_01JX8Y5YJ2M2D8N1AQ5F7Q3KVT"
  }
}

Parse job status

json

{
  "job_id": "job_01JX8Y5YJ2M2D8N1AQ5F7Q3KVT",
  "status": "done",
  "service": "parse-pdf",
  "request_id": "req_01JX8Y62XCDNZ2BM7TBM2M9Q8E",
  "result": {
    "document": {
      "fileName": "quarterly-report.pdf",
      "numberOfPages": 2,
      "kids": [
        {
          "type": "section",
          "children": [
            {
              "type": "heading",
              "content": "Executive summary",
              "heading level": 1,
              "page number": 1,
              "bounding box": { "x": 0.88, "y": 0.74, "w": 6.15, "h": 0.33 }
            },
            {
              "type": "paragraph",
              "content": "Revenue rose 18% year over year across the managed-services portfolio.",
              "page number": 1,
              "bounding box": { "x": 0.88, "y": 1.21, "w": 6.21, "h": 0.52 }
            },
            {
              "type": "list",
              "children": [
                { "type": "listItem", "content": "Renewals remained above 92%." },
                { "type": "listItem", "content": "Average contract value increased in EMEA." }
              ]
            },
            {
              "type": "table",
              "children": [
                {
                  "type": "tableRow",
                  "children": [
                    { "type": "tableCell", "content": "Region" },
                    { "type": "tableCell", "content": "Growth" }
                  ]
                },
                {
                  "type": "tableRow",
                  "children": [
                    { "type": "tableCell", "content": "North America" },
                    { "type": "tableCell", "content": "21%" }
                  ]
                }
              ]
            },
            {
              "type": "caption",
              "content": "Table 1. Regional growth by quarter."
            }
          ]
        }
      ]
    },
    "artifacts": {
      "markdown_download": "/v1/jobs/job_01JX8Y5YJ2M2D8N1AQ5F7Q3KVT/download?format=markdown",
      "json_download": "/v1/jobs/job_01JX8Y5YJ2M2D8N1AQ5F7Q3KVT/download?format=json",
      "html_download": "/v1/jobs/job_01JX8Y5YJ2M2D8N1AQ5F7Q3KVT/download?format=html",
      "text_download": "/v1/jobs/job_01JX8Y5YJ2M2D8N1AQ5F7Q3KVT/download?format=text",
      "annotated_pdf_download": "/v1/jobs/job_01JX8Y5YJ2M2D8N1AQ5F7Q3KVT/download?format=annotated_pdf"
    },
    "metadata": {
      "engine": "docushell_parse",
      "output_mode": "all",
      "include_header_footer": true,
      "use_struct_tree": true,
      "sanitize": true,
      "reading_order": "xycut",
      "table_method": "cluster",
      "keep_line_breaks": true
    }
  },
  "metrics": {
    "queue_wait_ms": 214,
    "duration_ms": 1789
  },
  "links": {
    "status": "/v1/jobs/job_01JX8Y5YJ2M2D8N1AQ5F7Q3KVT",
    "download": "/v1/jobs/job_01JX8Y5YJ2M2D8N1AQ5F7Q3KVT/download"
  }
}
The JSON artifact preserves reading order and exposes the structured document tree through `numberOfPages` and `kids`.

Artifacts

  • Structured JSON is always generated. It carries the document root, numberOfPages, and the hierarchical kids array with bounding boxes where the layout provides them.
  • Only one markdown-style artifact can be requested per job: markdown, markdown_with_html, or markdown_with_images.
  • markdown_with_images returns a self-contained file when image_output=embedded, and a zip when image_output=external.
  • tagged_pdf is automated structure inference for accessibility review, not a PDF/UA compliance guarantee.

Poll And Download

  • Poll GET /v1/jobs/:jobId until status becomes done or failed.
  • Completed jobs expose artifact links under result.artifacts.
  • Stream one artifact at a time from GET /v1/jobs/:jobId/download?format=<format>. See [Artifact Downloads](#artifact-downloads).

Failure Notes

  • invalid_pdf covers invalid file types and malformed uploads rejected before the worker starts.
  • corrupt_pdf is reserved for damaged PDFs that fail deeper validation or parser execution.
  • password_protected is returned when the document requires a password.
  • ocr_required is returned for scans or image-only PDFs when hybrid OCR is disabled, unavailable, or still produces too little extractable text.
  • invalid_page_range is returned when the submitted page selector is malformed or selects no valid pages.
  • page_limit_exceeded is returned when the requested page set is larger than the plan-specific parse cap.
  • server_busy or backend_unavailable indicate temporary capacity problems. Retry with the same Idempotency-Key when safe.
  • Fixes for each code are on the [Troubleshooting](/troubleshooting) page.

Password-protected PDF

400password_protected

The document cannot be parsed until it is decrypted outside the public API lane.

400 error

json

{
  "error": {
    "code": "password_protected",
    "message": "This PDF is password-protected and cannot be parsed without a password.",
    "type": "invalid_request_error",
    "request_id": "req_01JX8Y62XCDNZ2BM7TBM2M9Q8E"
  }
}

OCR required

400ocr_required

The parser could not extract text from a scan or image-only file.

400 error

json

{
  "error": {
    "code": "ocr_required",
    "message": "This PDF appears to require OCR before it can be parsed.",
    "type": "invalid_request_error",
    "request_id": "req_01JX8Y62XCDNZ2BM7TBM2M9Q8E"
  }
}

Invalid page range

400invalid_page_range

The submitted selector is malformed or does not resolve to valid pages.

400 error

json

{
  "error": {
    "code": "invalid_page_range",
    "message": "The requested page_range is invalid for this PDF.",
    "type": "invalid_request_error",
    "request_id": "req_01JX8Y62XCDNZ2BM7TBM2M9Q8E"
  }
}

Plan page limit exceeded

400page_limit_exceeded

The requested document or selected page range is larger than the active plan allows.

400 error

json

{
  "error": {
    "code": "page_limit_exceeded",
    "message": "Requested page range exceeds your plan limit.",
    "type": "invalid_request_error",
    "request_id": "req_01JX8Y62XCDNZ2BM7TBM2M9Q8E"
  }
}

Webhooks

Completion Webhooks

Use webhook_url and webhook_secret for per-request completion callbacks, or send x-docushell-webhook-url and its matching secret header on batch parse requests.

Receivers must validate x-docushell-signature, deduplicate by x-docushell-delivery, and finish within 10-second request timeouts. Use public HTTPS staging endpoints or approved tunnels for receiver tests.

Terminal event names include pdf.parse.completed, pdf.parse.failed, pdf.parse.batch.completed, pdf.parse.batch.completed_with_failures, pdf.parse.batch.failed, resume.parse.completed, resume.parse.failed, resume.batch.completed, resume.batch.completed_with_failures, and resume.batch.failed.

Artifacts

Artifact Downloads

One artifact per request. Swap format for any value the job produced; binary artifacts need --output.

Download an artifact

bash

curl "https://api.docushell.com/api/v1/jobs/job_01JX8Y5YJ2M2D8N1AQ5F7Q3KVT/download?format=json" \
  -H "Authorization: Bearer YOUR_API_KEY"

# binary artifacts: annotated_pdf, tagged_pdf, and external-image markdown (zip)
curl "https://api.docushell.com/api/v1/jobs/job_01JX8Y5YJ2M2D8N1AQ5F7Q3KVT/download?format=annotated_pdf" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  --output document.annotated.pdf
Requesting a format the job did not produce returns `400`.