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).
Overview
Artifacts
Select artifacts with formats. Structured JSON is always produced; only one markdown-style format is allowed per job.
| `formats` value | What it is | Use it for |
|---|---|---|
json | Hierarchical document tree — headings, paragraphs, lists, tables, cells, captions, images, with bounding boxes where available | Automation, indexing, citations, structured QA |
markdown | Flattened text in reading order | Previews, search indexing, LLM ingestion |
markdown_with_html | Markdown that retains richer inline and table markup | Content that loses meaning as plain Markdown |
markdown_with_images | Image-capable Markdown; a zip when image_output=external | Documents where figures carry the meaning |
html | Styled companion document | Rendering and human review |
text | Plain text | Lightweight search and simple ingestion |
annotated_pdf | Source pages overlaid with detected structure | Debugging extraction before you trust it |
tagged_pdf | Generated structure tree — inference, not a PDF/UA guarantee | Accessibility 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.
| Control | Default | Effect |
|---|---|---|
reading_order=xycut|off | Layout-aware | Force or disable reading-order reconstruction. |
table_method=default|cluster | default | Use cluster when the default path misses cell groupings. |
use_struct_tree=true | false | Prefer the PDF's native structure tags when it has usable ones. |
keep_line_breaks=true | false | Preserve source line breaks in text-oriented output. |
include_header_footer=true | false | Keep repeated page furniture instead of dropping it. |
sanitize=true | false | Mask visible emails, URLs, and phone numbers in extracted output. |
image_output=off|embedded|external | embedded | Image handling for image-capable formats. |
page_range | All pages | Select pages, e.g. 1-3,5,9-11. Selected pages set the credit cost. |
hybrid_mode=auto|full | Backend-gated | Requires the hybrid backend to be enabled by operations. |
| OCR for scanned PDFs | Backend-gated | Without the hybrid OCR profile, image-only PDFs return ocr_required. |
| Formula and chart enrichment | Backend-gated | Only 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
| Name | Type | Required | Location | Description |
|---|---|---|---|---|
| Authorization | Bearer <API_KEY> | Yes | header | User-owned API key created in the DocuShell dashboard. |
| Idempotency-Key | string | No | header | Recommended for safely retrying submit requests without creating duplicate jobs. |
Request Fields
| Name | Type | Required | Location | Description |
|---|---|---|---|---|
| file | file | Yes | multipart | PDF upload. The gateway validates PDF magic bytes before forwarding the file. |
| file_name | string | No | multipart | Optional file name override used for storage metadata and downstream artifact names. |
| page_range | string | No | multipart | Comma-separated pages or ranges such as 1-3,5,9-11. |
| include_header_footer | boolean | No | multipart | Set to true to keep header and footer content in the extracted output.Default: false |
| use_struct_tree | boolean | No | multipart | Set to true to prefer native tagged-PDF structure when the source document includes a usable structure tree.Default: false |
| sanitize | boolean | No | multipart | Set to true to mask email addresses, URLs, and phone numbers in extracted output.Default: false |
| reading_order | `xycut` | `off` | No | multipart | Optional reading-order strategy. Omit it to keep the current default extraction behavior. |
| table_method | `default` | `cluster` | No | multipart | Optional table-detection strategy. Omit it to keep the current default extraction behavior. |
| keep_line_breaks | boolean | No | multipart | Set to true to preserve source line breaks more aggressively in text-oriented output.Default: false |
| output_mode | `json` | `both` | `html` | `all` | No | multipart | Backward-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` | No | multipart | Optional explicit artifact list. Send as repeated fields or a comma-separated value, such as formats=json,text. |
| hybrid_mode | `auto` | `full` | No | multipart | Optional per-job hybrid triage override. Requires the hybrid backend to be enabled by operations. |
| image_output | `off` | `embedded` | `external` | No | multipart | Controls 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=truewhen 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, andimage_outputare extraction-tuning knobs.output_modeandformatscontrol which companion artifacts are emitted.- Request newer artifact types such as
markdown_with_html,markdown_with_images, andtagged_pdfwithformats; only one markdown-style format (markdown,markdown_with_html, ormarkdown_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=trueis 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 withformat=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.
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"
}
}Artifacts
- Structured JSON is always generated. It carries the document root,
numberOfPages, and the hierarchicalkidsarray with bounding boxes where the layout provides them. - Only one markdown-style artifact can be requested per job:
markdown,markdown_with_html, ormarkdown_with_images. markdown_with_imagesreturns a self-contained file whenimage_output=embedded, and a zip whenimage_output=external.tagged_pdfis automated structure inference for accessibility review, not a PDF/UA compliance guarantee.
Poll And Download
- Poll
GET /v1/jobs/:jobIduntilstatusbecomesdoneorfailed. - 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_pdfcovers invalid file types and malformed uploads rejected before the worker starts.corrupt_pdfis reserved for damaged PDFs that fail deeper validation or parser execution.password_protectedis returned when the document requires a password.ocr_requiredis returned for scans or image-only PDFs when hybrid OCR is disabled, unavailable, or still produces too little extractable text.invalid_page_rangeis returned when the submitted page selector is malformed or selects no valid pages.page_limit_exceededis returned when the requested page set is larger than the plan-specific parse cap.server_busyorbackend_unavailableindicate 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_protectedThe 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_requiredThe 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_rangeThe 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_exceededThe 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