8 Best Unstructured.io Alternatives for Document Parsing in 2026

Moving an Unstructured prototype to production often means replacing the parser, the chunker, the connectors, or all three. This guide compares 8 alternatives, including Foxit PDF Services API, LlamaParse, Reducto, and Docling, by cost, table handling, chunking, and file coverage. You also get the element mappings, billing math, and test plan you need before you switch.
If your prototype uses the unstructured library, moving to production raises a practical question: what needs to change? Unstructured describes the library in its own docs as “Not designed for production scenarios.” Costs on long reports or table errors in a RAG index may also prompt a switch from the library or Transform API.
Those are the 3 moments that send engineers looking. In Moda’s 6 Sep 2026 run of Unstructured OSS 0.27.5 on a 48-page NIST AI RMF PDF, the library kept 36 of 40 checked statements and missed 4 table-row continuations. One document, one run, but it illustrates the failure mode.
“Unstructured” now names several products. The open-source unstructured library partitions and chunks on your machines. The Transform API parses single documents via POST. Pipelines connects sources, partitions, chunks, embeds, and writes to destinations. Business adds dedicated infrastructure. Replacing Unstructured can mean replacing the parser, the chunker, the connectors, or all three.
In this article, we compare 8 alternatives (our PDF Services API, LlamaParse, Reducto, Docling, Marker and Datalab, Mistral OCR, Azure Document Intelligence, and Google Document AI Layout Parser) by what they replace, their capabilities and costs, and the work involved in switching.
What Unstructured gives you today
What does unstructured.io do? Its parsing layer produces typed elements such as Title, NarrativeText, ListItem, Table, and Image, with metadata including page numbers, coordinates, parent_id, and text_as_html for tables. Unstructured Pipelines adds the managed workflow for chunking, enrichment, embedding, and delivery to a destination.
Unstructured’s home page.
Is unstructured.io free? The open-source library is free under Apache-2.0. The Transform API includes 10,000 pages once per account, then costs $0.015 a page, and Transform requests fail after the free pages until you upgrade to pay as you go.
Unstructured product | What it does | Price | Limits |
Open-source library (unstructured, Apache-2.0) | Partitions documents into elements and chunks them on your own machines | Free. You run the dependencies (Poppler, Tesseract) and models | Intended for quick prototyping and “Not designed for production scenarios.” No VLM, no fine-tuned OCR, no by-page or by-similarity chunking, no embeddings in the core library |
Transform API (POST /api/v2/parse) | Returns Markdown or elements, with optional schema extraction | 10,000 pages free once per account, then $0.015 a page | 9 extensions (.bmp, .docx, .heic, .jpeg, .jpg, .pdf, .png, .pptx, .tiff), 100 MB, 1 document per request, balanced or best profile only, rate limits not published |
Transform MCP server | Partitions, enriches, chunks, and embeds files from an AI tool | Same per-page rate | 49 extensions, including .eml, .msg, .html and .xlsx; 50 MB per file |
Pipelines | Connects sources, partitions with Auto, VLM, High Res or Fast, then chunks, enriches, embeds, and writes to destinations | Pay as you go at the same per-page rate | Workflows and jobs; 40+ connectors |
Business | Dedicated instance, in-VPC on AWS, Azure or GCP, or bare metal | Custom | Multi-user workspaces |
Under Transform billing, each PDF page, PPTX slide, or TIFF image counts as 1 page. DOCX files use page metadata when available, otherwise file size divided by 100 KB, and most other files count 1 page per 100 KB.
The library is deprioritized, not discontinued. Unstructured no longer actively recommends or promotes the library, Ingest, the JavaScript SDK, and the partition endpoint. The library still ships on PyPI (0.27.36 on 30 Oct 2026, after 6 releases between 19 and 27 Oct) and no end-of-life date is published.
File-type coverage depends on which product you call. The Transform API accepts 9 extensions, the Transform MCP server accepts 49, and the open-source library 27. The Transform API also documents an Extract endpoint for schema-based extraction.
The strengths are real. Pipelines brings 40+ connectors with change detection and incremental processing, chunking by character, title, page, or similarity plus contextual chunking, and embeddings from providers such as OpenAI, Bedrock, VoyageAI, and IBM. Compliance coverage includes SOC 2 Type 2, ISO 27001, and HIPAA, listed in its trust center, plus FedRAMP High, authorized 12 Dec 2025.
Before you compare anything, list what your pipeline actually uses today, including connectors, chunking strategy, element metadata, file types, and embeddings. That list decides which alternative can replace it.
Each alternative replaces a different slice of Unstructured’s pipeline. Only the partition stage is covered by every tool.
Our top picks by reason for switching
The right alternative depends on which part of Unstructured you’re replacing (the parser, the chunker, or the connectors) and where your documents can be processed.
For financial PDFs with broken tables, shortlist parsers that return table structure as cell grids or HTML tables with spans, such as Reducto r-1, LlamaParse on Cost-effective or higher, Azure Document Intelligence Layout, our PDF Structural Extraction, and Docling’s TableFormer, then test on your own worst pages.
If you’re leaving Unstructured because… | Pick | Why it fits |
Per-page fees add up on long PDFs | Foxit PDF Services API | 1 credit per successful request regardless of page count within supported limits; PDF to Markdown, PDF Structural Extraction (Trial) and OCR on a single credit pool |
You want a managed ingestion service with connectors | LlamaParse | 130+ formats, 4 parse tiers from $1.25 to $31.25 per 1,000 pages on Pro, Google Drive, SharePoint, S3 and Confluence connectors on paid plans, 10,000 free credits a month |
Complex tables, and chunks straight from the parser | Reducto | r-1 Parse at $10 per 1,000 pages (r-1 mini at $1), 6 chunk modes and embedding-optimized table summaries |
You want an open-source library you run yourself | Docling | MIT-licensed, reads PDF, Office, HTML and .eml or .msg email, HybridChunker, Docling Serve REST API with chunk endpoints |
Local Markdown conversion with a hosted fallback | Marker and Datalab | Marker code is Apache-2.0 with separately licensed weights. Hosted Convert from $0.50 (lite) to $10 (accurate) per 1,000 pages, with chunks output |
Low-cost Markdown with layout blocks at volume | Mistral OCR | OCR 4.1 at $4 per 1,000 pages, or $2 with the Batch API. Per-page Markdown with blocks, boxes and confidence |
Your stack runs on Azure | Azure Document Intelligence | Layout returns Markdown with HTML tables at $10 per 1,000 pages, reads PDF, images, DOCX, XLSX, PPTX and HTML, and offers Read and Layout containers |
You want chunking inside the parser on Google Cloud | Google Document AI Layout Parser | $10 per 1,000 pages including initial chunking, with chunk size in tokens and ancestor headings |
These are starting points, not exclusive use cases. The feature tables show what each tool covers, and the “Moving from Unstructured” rows explain the output mappings and integration changes to plan for.
Create a free Foxit developer account and turn your first PDF into Markdown or structured JSON with the PDF Services API.
Foxit PDF Services API
Our PDF Services API product page.
Our PDF Services API handles the PDF parsing step, with Markdown, plain text, and typed JSON through PDF Structural Extraction (Trial). Parsing shares a credit pool with conversion, OCR, redaction, and other PDF operations.
Feature | Details |
Covers | Parsing step for PDFs, including PDF to Markdown, PDF Structural Extraction (Trial) for typed JSON, PDF to Text, and an OCR endpoint for scans. No chunking, embeddings, or connectors. |
Inputs | Parsing endpoints take PDFs. Word (.doc, .docx), Excel, PowerPoint (.ppt, .pptx), images (JPEG, PNG, TIFF, BMP, GIF), text, HTML, web pages by URL, and Markdown convert to PDF first on the same account. Uploads up to 100 MB. No email route. |
Outputs | PDF to Markdown with tables as Markdown pipes (default) or HTML tables, and page headers and footers only when requested. Structural Extraction returns a ZIP with JSON (schema v1.0.7), extracted images and table renditions, 12 element types with reading order, bounding boxes and table cell relationships. |
Scans and tables | The OCR endpoint takes language codes and makes scanned PDFs searchable. Structural Extraction returns no text on image-only PDFs, so OCR them first. Tables keep cell structure in Structural Extraction. |
Chunking | The API includes no chunking. Title, head, and paragraph elements arrive in reading order, so split on them in your own code or framework. |
Pricing | 1 credit per successful request, regardless of file size or page count within supported limits. Startup costs $1,750 a year for 5,000 credits; Business costs $4,500 a year for 15,000. The free Developer plan includes 500 credits a year. Uploads, task polling, and downloads use no credits, and failed requests are not billed. |
Limits and deployment | Asynchronous: submit, poll the task, download. 15 requests a minute per application in sandbox, 100 in production. Cloud only. A delete endpoint permanently removes uploaded and generated files, and no retention period is published. Our cloud-hosted PDF APIs are covered by SOC 2 Type II audits, and we support HIPAA BAAs. |
Moving from Unstructured |
|
Where our PDF Services API stands out.
A successful parsing call costs 1 credit for either a 200-page annual report or a 2-page invoice, within supported limits.
Whether that costs less than a per-page API depends on the competing tier and how much of your annual credit pool you use. Conversion, OCR, and redaction use the same pool, but each processing call consumes a separate credit.
Our PDF Structural Extraction API is currently in trial and uses schema version v1.0.7. The API may change, so validate responses against the schema your application expects. Structural Extraction returns a ZIP archive containing JSON, extracted images, and table renditions, so your pipeline needs an unzip step before parsing the JSON.
Prerequisites. To run the example below, you need:
- A shell : Bash or zsh, which macOS and Linux include. On Windows, use WSL.
- curl : macOS, most Linux distributions, and Windows 10 and later include it. If
curl --versionfails, install curl. - jq : Download jq, or install it with Homebrew on macOS or apt on Debian and Ubuntu. Check it with
jq --version. - A Foxit developer account : Sign up for the free Developer plan, which includes 500 credits a year.
Create a working folder for the script’s temporary files and output:
mkdir foxit-parse && cd foxit-parse If jq --version fails, install jq first. On macOS with Homebrew, run this command:
brew install jq On Debian or Ubuntu, run this one instead:
sudo apt-get install -y jq Create your account. Enter your email on the sign-up page to activate the free Developer plan, which needs no credit card.

Our sign-up form activates the free Developer plan.
Get your credentials. After you sign up, open the console and copy the client ID and client secret from the Make your first call panel. The script reads both from environment variables.

The console after sign-up, with credentials pre-filled for a first call.
What a run looks like. Every parsing call follows the same asynchronous pattern, so you can see it end to end with curl and jq. This block sets your credentials, defines 3 small helpers, and converts our sample invoice PDF to Markdown.
Run this command from your terminal:
export FOXIT_CLIENT_ID="your_client_id"
export FOXIT_CLIENT_SECRET="your_client_secret"
API=https://na1.fusion.foxit.com/pdf-services/api
foxit() { curl -s -H "client_id: $FOXIT_CLIENT_ID" -H "client_secret: $FOXIT_CLIENT_SECRET" "$@"; }
submit() {
foxit -w "\nHTTP %{http_code}\n" -H "Content-Type: application/json" -d "$2" "$API/documents/$1" > submit.txt
cat submit.txt
TASK=$(head -1 submit.txt | jq -r '.taskId // empty' 2>/dev/null)
[ -n "$TASK" ] || { echo "Submit failed. Check your credentials and credit balance."; return 1; }
while true; do
foxit "$API/tasks/$TASK" > task.json && jq -c . task.json
STATUS=$(jq -r '.status // "ERROR"' task.json 2>/dev/null || echo ERROR)
case "$STATUS" in
COMPLETED) return 0 ;;
FAILED|ERROR) echo "Task did not complete."; return 1 ;;
esac
sleep 5
done
}
download() { foxit -o "$1" "$API/documents/$(jq -r .resultDocumentId task.json)/download"; }
curl -sL -o invoice.pdf https://github.com/lucienchemaly/foxit-demo-templates/raw/main/invoice_table_test.pdf
UPLOAD=$(foxit -F "[email protected]" "$API/documents/upload")
DOC=$(echo "$UPLOAD" | jq -r '.documentId // empty' 2>/dev/null)
[ -n "$DOC" ] && echo "documentId: $DOC" || echo "Upload failed: $UPLOAD"
[ -n "$DOC" ] && submit convert/pdf-to-markdown "{\"documentId\": \"$DOC\"}" && download invoice.md
The foxit helper sends your credentials as headers. submit posts the operation, prints its response and HTTP status, then polls GET /tasks/{taskId} every 5 seconds until COMPLETED.
It stops if no taskId is returned, the task reports FAILED, or a poll response has no status. The script uploads the sample PDF, submits pdf-to-markdown, then downloads the result using resultDocumentId.
Only the processing call uses a credit. This example has no overall polling timeout, so add one before using it in an unattended pipeline.
The expected output should look like the following:
documentId: 6aecea9c9036bb553d572b55
{"taskId":"6aecea9d4c382b4f0d060b10"}
HTTP 202
{"taskId":"6aecea9d4c382b4f0d060b10","status":"COMPLETED","progress":100,"resultDocumentId":"6aecea9ec07a611874a472e8"} The script prints the documentId from the upload, the submit response with its HTTP 202 status, and each poll result until the task reports COMPLETED with a resultDocumentId. Your IDs will differ, and a slower task prints one or more IN_PROGRESS lines before the final one.
The default output renders tables as Markdown pipes. The downloaded invoice.md should look like the following:
# INVOICE
Foxit DocGen API Sample Template
Bill To: Meridian Financial Group
Invoice Number: INV-00471
Invoice Date: 01/15/2024
| # | Description | Qty | Unit Price | Line Total |
| --- | --- | --- | --- | --- |
| 1 | API Integration Consulting | 10 | $ 150.00 | $1,500.00 |
| 2 | Compliance Review | 5 | $ 200.00 | $1,000.00 |
| | | | Subtotal: | $2,500.00 |
## Total Due: $2,500.00
Thank you for your business. Payment is due within 30 days of the invoice date.
Common mistakes. These are the failures a first run most often hits:
- Wrong client ID or secret : The upload returns
"allow":falsewith a reason such as Invalid credentials, and the script printsUpload failedand stops. Copy both values again from the console, without surrounding spaces or quotes, and re-run theexportlines. - No credits left: If the sample upload returns
"allow":false, the script printsUpload failedand stops. Check Credits Remaining in the dashboard. Credit-consuming processing calls pause when the balance reaches 0; restore credits through an upgrade, a purchased top-up, or the annual reset. Error responses can differ by endpoint. - jq not installed : The script prints
Upload failed:followed by a response that contains adocumentId, then stops. The upload worked, but the script can’t read the JSON without jq. Runjq --version, and install jq from the Prerequisites if it fails.
What to consider. There is no chunking, embedding, or connector layer in the API. Office files and scans each take 2 API calls (convert or OCR, then parse). Credits are sold as a yearly pool rather than pay as you go, so unused credits raise your effective per-request cost. Email is not supported. The 15 requests-per-minute sandbox rate limit will constrain bulk testing.
Best for. PDF-heavy pipelines with long documents that also convert, OCR, or redact files, and where per-request billing improves the economics over per-page pricing.
Getting started. Create a free Foxit developer account and turn your first PDF into Markdown or structured JSON with the PDF Services API. The free Developer plan includes 500 credits a year, no credit card required. See our PDF Structural Extraction tutorial and invoice extraction guide to get started.
LlamaParse

LlamaParse’s product page on the LlamaIndex site.
LlamaParse (by LlamaIndex, formerly LlamaCloud) is a managed parsing service with 130+ supported formats, 4 price tiers, and source connectors on paid plans.
It covers more of Unstructured’s pipeline than a parser-only API, including an optional managed Index that chunks and embeds.
Feature | Details |
Covers | Parsing (plus Extract, Classify, and Split), a managed Index that chunks and embeds, and connectors on paid plans. |
Inputs | 130+ formats, including PDF, DOCX, PPTX, XLSX, HTML, images, and audio. No email format is documented. |
Outputs | Per-page and full-document Markdown and text, plus a typed items tree (text, heading with level, table, image, list, code, link, header, footer) with bounding boxes in page points. Tables are available as HTML with merged cells, CSV, or Markdown, and an XLSX of all tables. |
Scans and tables | OCR runs automatically on pages without a text layer, with more than 80 language codes. Tables keep cell structure, with an option to merge tables that continue across pages. The Fast tier runs no AI model. |
Chunking | Parse includes no chunking. Index v2 chunks and embeds for you with fixed settings (sentence-based, 1,024 tokens, 200-token overlap) and cannot write to your own vector store. |
Pricing | $1.50 per 1,000 credits on pay as you go and $1.25 on Pro. Parse tiers: Fast 1, Cost-effective 3, Agentic 10, and Agentic Plus 25 credits a page, or about $1.25, $3.75, $12.50, and $31.25 per 1,000 pages at the Pro rate. Pro costs $500 a month for 400,000 credits. Free: 10,000 credits a month. Enriched forms output (Beta) adds 10 credits per page containing a form on Cost-effective, is included in the page price on Agentic and Agentic Plus, and is unavailable on Fast. |
Limits and deployment | Parse takes 512 MB and 10,000 pages per job by default. Concurrent jobs: 5 on pay as you go, 20 on Pro, 100 on Enterprise. SaaS in AWS us-east-1 and eu-central-1. BYOC and self-hosted on Enterprise. Source files and the parse cache are kept 48 hours. SOC 2 Type II and HIPAA compliant, with a BAA on Enterprise. |
Moving from Unstructured |
|
Where LlamaParse stands out. Tiers let you route easy pages down a cheap path (Fast at $1.25 per 1,000 on Pro) and complex pages up an expensive one (Agentic Plus at $31.25 per 1,000 on Pro), which can reduce cost on mixed corpora. Connectors plus the managed Index cover more of Unstructured’s pipeline than any parser-only API in this list. LlamaIndex launched its own OCRia-1 model on 22 Oct 2026, and it now runs Cost-effective and Agentic jobs at the same prices.
What to consider. The Fast tier runs no AI model and returns raw text or layout-preserving spatial text, so pick Cost-effective or higher when you need clean Markdown. Index v2 chunking cannot be configured or pointed at your own vector store. Email formats are not documented. The HIPAA BAA scope is Enterprise only, so teams with PHI must confirm the plan level before sending protected documents.
Best for. Teams that want a managed service to replace parsing and part of the ingestion plumbing, especially with Google Drive or SharePoint sources.
Getting started. LlamaParse pricing and sign-up. The free plan includes 10,000 credits a month.
Reducto

Reducto’s home page.
Reducto is a parsing API with built-in chunking and an r-1 model for complex documents. Parse, Extract, Split, Classify, and Edit all sit behind one API and one authentication credential.
Feature | Details |
Covers | Parse with built-in chunking, plus Extract, Split, Classify, and Edit on the same API. No connectors. |
Inputs | 30+ file types, including PDF, DOCX, DOC, TXT, XLSX, XLS, CSV, PPTX, PPT, HTML, and common image formats. Email (.eml and .msg) is documented for on-premises deployments only. |
Outputs | Chunks with Markdown content, an embedding-optimized version, and blocks ( |
Scans and tables | r-1 targets scans, handwriting, merged cells, and nested headers. Legacy Parse’s standard OCR engine lists 60+ languages, while r-1 publishes no language count. |
Chunking | 6 modes: disabled (default), variable (recommended for RAG, where a chunk_size of 1000 yields 750 to 1,250 characters), section, page, page_sections, and block, with optional overlap and embedding-optimized table summaries. |
Pricing | Per 1,000 pages: r-1 Parse $10 with OCR data and citations included, and r-1 mini Parse $1 (OCR data and citations add $1). Legacy Parse $15 standard and $30 complex (2x in agentic modes), with OCR included. Extract $20 including parsing (over 100 fields per page may incur a surcharge), and the batch queue takes 20% off Parse and Extract. Prompted blocks and custom regions on r-1 and r-1 mini cost $5 per 1,000 blocks. Free: $150 of usage on the Standard plan. |
Limits and deployment | 100 MB direct upload, 5 GB with a presigned upload. No page limit on Standard. Up to 1,000 requests a second per key (300 for job-status polling). Synchronous calls time out at 15 minutes, and results are generally available for 12 hours. SaaS on AWS. EU residency from Growth. Hybrid VPC, full VPC, and on-premises on Enterprise. SOC 2 Type II and HIPAA compliant on all tiers, with a BAA and no training on customer data from Growth up. |
Moving from Unstructured | Chunks replace chunk-by-title output, and blocks replace elements ( |
Where Reducto stands out. Chunks and embedding-ready table summaries come back from the parse call itself, removing a separate chunking step. The r-1 model targets complex layouts including handwriting, merged cells, and nested headers, and r-1 mini offers a lower-cost path at $1 per 1,000 pages. Qualified new customers moving from another provider can apply to Reducto for up to $5,000 in migration credits.
What to consider. When settings.model is unset, Parse runs legacy Parse until 7 Dec 2026 and r-1 after that, so set settings.model to "legacy" if you need the old pipeline’s output to stay stable. No managed source-sync connectors or LangChain/LlamaIndex loaders are documented.
Best for. RAG pipelines with complex PDFs that want chunks and embedding-optimized table summaries returned from the parser itself.
Getting started. Sign up on the Reducto site. The free grant covers your first documents, and Reducto’s docs cover the r-1 model and chunking methods.
Docling

Docling’s documentation home page.
Docling, an LF AI and Data project started at IBM Research, is an open-source option for replacing the unstructured library.
Docling Serve adds a REST API with chunk endpoints. Check the release history when choosing a version to pin.
Feature | Details |
Covers | Open-source replacement for the unstructured library, covering conversion, layout, tables, OCR, and chunking, with Docling Serve as a REST API. Connectors available through Docling Jobkit. |
Inputs | PDF, DOCX, XLSX, and PPTX (legacy DOC, XLS, PPT, and RTF need LibreOffice), HTML and MHTML, .eml and .msg email, EPUB, Markdown, AsciiDoc, LaTeX, CSV, images, audio and video (with the asr extra), and XML formats such as USPTO and JATS. |
Outputs | Markdown, HTML, text, DocTags, lossless JSON (DoclingDocument) with bounding boxes and provenance, and chunks as JSONL. Labels include |
Scans and tables | Pluggable OCR engines (RapidOCR, EasyOCR, Tesseract, macOS Vision, and others); TableFormer in accurate (default) or fast mode; an optional VLM pipeline with GraniteDocling and other presets. Remote services run only with |
Chunking | HybridChunker (token-aware, on top of hierarchical chunking, repeats table headers), HierarchicalChunker (one chunk per element, merging list items by default), and LineBasedTokenChunker; Docling Serve exposes hybrid and hierarchical chunk endpoints. |
Pricing | Free under the MIT license, with model licenses kept separate (Heron and GraniteDocling Apache-2.0, TableFormer CDLA-Permissive-2.0). Docling for IBM watsonx, a managed service, starts at $4 per 1,000 pages pay as you go. |
Limits and deployment | Python 3.10 or later on macOS, Linux, and Windows. Docling Serve ships CPU and CUDA images with async endpoints and no default file-size or page cap. Runs air-gapped with prefetched models. The IBM service caps files at 500 MB. |
Moving from Unstructured | LangChain’s DoclingLoader and LlamaIndex’s Docling Reader and Node Parser replace Unstructured’s loaders. Labels and the document tree differ (body vs. furniture, groups), and tables arrive as cell grids rather than |
Where Docling stands out. Its support for .eml and .msg email, EPUB, and legacy Office files with LibreOffice is useful for mixed-format corpora. Documents stay on your infrastructure when you use local models. LangChain and LlamaIndex integrations provide a starting point for replacing your loader, but you still need to adapt the output schema.
What to consider. You run and scale it. Legacy Office formats (.doc, .xls, .ppt, .rtf) need LibreOffice installed alongside. Default settings may need tuning for scans and charts; in Moda’s 6 Sep 2026 untuned run on its synthetic test set, Docling missed some chart labels. Pin versions, since that release pace can change output between upgrades.
Best for. Teams leaving the unstructured library that want to keep document processing on their own machines, especially with email or legacy Office formats.
Getting started. Docling on GitHub and the Docling Serve docs. Free and MIT-licensed; install with pip install docling.
Marker and Datalab

Datalab’s home page, with a parsed sample document.
Marker is an open-source document converter with Apache-2.0 code and separately licensed model weights.
Datalab provides a hosted Convert API using Chandra and other models. Chandra 2.6 runs the hosted fast, balanced, and accurate modes; lite is a separate lower-cost mode at $0.50 per 1,000 pages.
Feature | Details |
Covers | An open-source converter (Marker) and a hosted Convert API (Datalab) that return Markdown, JSON, HTML, or chunks. Datalab Collections supports S3 sync. |
Inputs | Marker reads PDF, images, PPTX, DOCX, XLSX, HTML, and EPUB (non-PDF files need the full install), and the hosted API adds ODT, ODS, ODP, XLSM, and more. No email formats. |
Outputs | Markdown, a JSON block tree with block types ( |
Scans and tables | Marker 2.0 runs layout, OCR, and tables through a surya VLM (vLLM on NVIDIA GPUs, llama.cpp elsewhere), with an optional LLM pass. Hosted fast, balanced, and accurate modes run Chandra 2.6, and hosted OCR covers 90+ languages. |
Chunking | A chunks output format only, with no chunk-size settings. |
Pricing | Hosted Convert per 1,000 pages: lite $0.50 (CPU OCR, added 22 Oct 2026), fast and balanced $4, accurate $10; EU processing adds 25%. Team costs $400 a month. Free usage: $20 a month on a work email or $10 on a personal email. Commercial self-hosted use requires a license above $5M in prior-year gross revenue or total funding for Marker ($2M for Chandra), or for competing products, with personal/research exceptions applying to the financial thresholds. |
Limits and deployment | Hosted: 200 MB per file, 7,000 pages per request, 15,000 pages in flight per team by default, and results deleted about 1 day after processing. VPC, on-premises, and air-gapped on Enterprise. SOC 2 Type II compliant, with BAAs on Team and Enterprise. |
Moving from Unstructured | Chunks replace chunk-by-title output only loosely (no size control); LlamaIndex has a PDFMarkerReader for local Marker. Basic conversion uses Convert. The custom processor endpoints were deprecated with a 31 Oct 2026 sunset, so run custom processors through /api/v1/agent. |
License history. Marker 2.0.0 code is Apache-2.0, while marker-pdf 1.x on PyPI was GPL-3.0-or-later. The hosted Chandra 2.6 model differs from open-source Chandra 0.2.0, so a local test does not predict hosted output.
Where Marker and Datalab stand out. You can choose local conversion or a hosted API, with Markdown, JSON, and chunks available in both. Shared format names do not make the integrations interchangeable: check the response schema and output on your documents before switching. Lite offers a $0.50-per-1,000-page path for straightforward scans.
What to consider. The weights license thresholds and competing-product clause apply to commercial self-hosting, so review them if you run your own infrastructure at scale. Lite mode drops images and can lose complex table structure. The chunks output format has no size control.
Best for. Markdown-first conversion pipelines that need a choice between self-hosting and a hosted per-page price, especially for straightforward scanned documents.
Getting started. Sign up on the Datalab site. The free tier includes $20 a month on a work email.
Mistral OCR

Mistral’s Document AI and OCR page.
Mistral OCR (OCR 4.1) converts documents to per-page Markdown with blocks, bounding boxes, and confidence scores.
The Batch API halves the price for non-latency-sensitive workloads. OCR 4.0 retired on 30 Sep 2026, so pin model names.
Feature | Details |
Covers | OCR and document structure to Markdown, with optional schema annotations. No chunking or connectors in the OCR API. |
Inputs | PDF, DOCX, DOC, PPTX, PPT, XLSX, CSV, TXT, EPUB, RTF, ODT, and images (JPEG, PNG, AVIF, TIFF, GIF, HEIC, BMP, WebP). No HTML or email in the OCR API. |
Outputs | Per-page Markdown plus images, tables, hyperlinks, header and footer; optional blocks in reading order with labels ( |
Scans and tables | OCR on scans and images. OCR 4 supports 170 languages and performs strongly in more than 40. |
Chunking | The OCR API includes no chunking. Mistral’s separate Search Toolkit (beta, v0.2.0) adds Markdown and token splitters plus HTML and EML or MSG extractors. |
Pricing | OCR 4.1: $4 per 1,000 pages, $2 with the Batch API, $5 per 1,000 annotated pages. OCR 3 (mistral-ocr-2512) is still GA at $2 and $3. Regional inference endpoints exclude the Batch and Files APIs. No free page allowance is published. |
Limits and deployment | 50 MB and 1,000 pages per document. OCR 4 is not intended for “real-time/latency-sensitive processing”. Hosted API plus Amazon SageMaker and Microsoft Foundry; self-managed deployment for enterprise customers. Uploaded files are kept 30 days unless deleted; zero data retention on the OCR endpoint excludes the Files API and batch files; Free mode may use inputs for training. |
Moving from Unstructured | Per-page Markdown replaces partition output; map block labels to element types; chunk in your own code or with the Search Toolkit. Pin model names on every request since OCR 4.0 retired on 30 Sep 2026. |
Where Mistral OCR stands out. One page price already includes blocks, boxes, and confidence at $4 per 1,000 pages, halved to $2 with the Batch API. That makes large batch conversions to Markdown competitive with Azure Layout and Google Layout Parser for teams that already own chunking and orchestration.
What to consider. The API includes no chunking. HTML and email are not supported as inputs. OCR 4 is not designed for latency-sensitive calls. Models retire quickly, so pin model on every request. Zero data retention requires an approved request and has scope limits. No free page allowance is published.
Best for. Large batch conversions to Markdown where you already own chunking and orchestration, and want block-level structure with confidence scores.
Getting started. Mistral API pricing and sign-up. Credits are pay as you go with no free OCR page allowance.
Azure Document Intelligence

Azure Document Intelligence’s product page.
Azure Document Intelligence in Foundry Tools (API v4.0, 2024-11-30), previously called Form Recognizer, is now part of Azure Content Understanding. The Layout model returns Markdown with HTML tables and is the primary pick for RAG pipelines on Azure.
Feature | Details |
Covers | Layout parsing to Markdown, plus Read OCR. No chunking or connectors in the service. |
Inputs | PDF, JPEG, PNG, BMP, TIFF, HEIF, DOCX, XLSX, PPTX, and HTML for Layout; Office and HTML text is extracted as is, without embedded images. No email. |
Outputs | Markdown output ( |
Scans and tables | OCR covers 300 printed-language/script entries and 12 handwritten languages; high-resolution, font, and formula add-ons cost $6 per 1,000 pages; tables that span pages need splitting and stitching; tables in XLSX files are not analyzed. |
Chunking | The service includes no chunking. Microsoft’s RAG guide pairs AzureAIDocumentIntelligenceLoader with LangChain’s MarkdownHeaderTextSplitter. |
Pricing | East US, per 1,000 pages: Layout $10 (batch costs the same), Read $1.50, then $0.60 above 1 million pages; Azure cloud commitment tiers start at $190 a month for 20,000 prebuilt pages. Free F0 tier: 500 pages a month, analyzing only the first 2 pages of each document. |
Limits and deployment | S0: 500 MB and 2,000 pages per analysis; 15 analyze requests a second by default (adjustable); asynchronous. Inputs and results are deleted 24 hours after you submit the analyze request. Read and Layout v4.0 containers, including disconnected containers on commitment plans. |
Moving from Unstructured | Layout Markdown replaces partition output for RAG; paragraph roles map to |
Where Azure Document Intelligence stands out. Markdown with HTML tables arrives straight from the service, with no post-processing needed for merged cells and multirow headers. DOCX, XLSX, PPTX, and HTML inputs expand the file coverage beyond PDF. Read and Layout v4.0 containers let environments that cannot call a cloud API run the models on-premises.
What to consider. The service includes no chunking, and tables that span pages need stitching in post-processing. The free tier reads only the first 2 pages of each document, which limits its usefulness for testing complex layouts.
Best for. RAG pipelines on Azure that want Markdown and HTML tables without running models, and need container deployment for data-residency requirements.
Getting started. Azure Document Intelligence pricing. The free F0 tier includes 500 pages a month.
Google Document AI Layout Parser

Google Cloud’s Document AI product page.
Google Document AI Layout Parser parses documents into a layout tree and chunks them for RAG in the same call. The stable version is v1.0 (2024-06-03).
Gemini-powered versions are available as release candidates or previews, so choose the processor version explicitly.
Feature | Details |
Covers | Layout parsing with built-in chunking for RAG; Enterprise Document OCR for images and scans. No connectors. |
Inputs | PDF, HTML, DOCX, PPTX, XLSX, and XLSM (GA and charged; other types are in free preview). Enterprise Document OCR takes PDF, GIF, TIFF, JPEG, PNG, BMP, and WebP. No email. |
Outputs | A document layout tree and chunked_document.chunks; PDF elements are figure, paragraph, table, title, heading, page header, and page footer (HTML adds lists); optional bounding boxes and image or table annotations. |
Scans and tables | Enterprise Document OCR reads printed and handwritten text in more than 200 languages; PDF tables that span pages “might be split in two tables”; nested DOCX tables are not supported. |
Chunking | chunkingConfig with chunkSize in tokens and includeAncestorHeadings; chunks carry ancestor headings and table headers; re-chunking parsed documents costs $0.02 per 1,000 billable pages (up to 3,000 characters each). |
Pricing | Layout Parser $10 per 1,000 pages including initial chunking, or $9 and $8 on 1- and 3-year savings plans. Enterprise Document OCR: first 1,000 pages free, then $1.50 per 1,000 up to 5 million. |
Limits and deployment | Online: 20 MB and 15 pages per PDF (30 in imageless mode). Batch: 500 pages and 1 GB per PDF; jobs still running after 24 hours are canceled. US and EU multi-regions. Document AI is FedRAMP High and HIPAA compliant, and Google does not use customer content to improve its models. |
Moving from Unstructured | Chunk by title maps most closely to chunkSize with includeAncestorHeadings. Only v1.0 (2024-06-03) is stable; the Gemini versions are release candidates or preview, and the v1.6 versions use a global endpoint that does not meet data-residency standards. LangChain’s DocAIParser is OCR-oriented. |
Where Google Document AI Layout Parser stands out. Chunking with ancestor headings is included in the $10 per 1,000 pages parse price. That token-aware chunking with inherited heading context removes a separate chunking step for pipelines on Google Cloud.
What to consider. The Gemini processor versions are not stable. Online requests allow only 15 pages (30 in imageless mode), which rules them out for long document analysis outside batch. Layout Parser runs as a Google Cloud processor in the US and EU multi-regions, so if documents must stay on your own infrastructure, shortlist the tools with documented container or self-hosted deployment.
Best for. RAG pipelines on Google Cloud that want token-aware chunks with ancestor headings.
Getting started. Document AI Layout Parser docs and Document AI pricing. Layout Parser has no free page allowance, while Enterprise Document OCR includes the first 1,000 pages free.
What changes when you move off Unstructured
Picking a parser is the easy part. Everything downstream that expects Unstructured’s element types, chunk boundaries, file coverage, and billing math changes when you switch.
How elements and metadata map across tools
Every alternative uses different element types, different field names, and different coordinate systems.
The mapping table below uses our PDF Structural Extraction as the worked example, because its reference documents every element type. The same mapping exercise applies to every tool in this list.
Unstructured | Foxit PDF Structural Extraction | What changes |
|
| Heading depth comes from |
|
| Same role; paragraphs also carry styling |
| No list type among the 12 documented types | No list type among the 12 documented types. Check how lists appear in your output and add list-detection logic where needed. |
|
| Read the cell grid, or ask PDF to Markdown for HTML_TABLE output |
|
| One type for page furniture; PDF to Markdown drops it unless |
|
| Images arrive as files referenced from the JSON |
|
| Same role |
|
| Map the different form representations explicitly |
| A bounding box per element | Normalize coordinate systems before you store citations |
|
| Rebuild parent links from |
One JSON list of elements | A ZIP with JSON (schema v1.0.7), images and table renditions | Unzip, then parse |
The closest equivalents elsewhere are LlamaParse items (heading, text, list, table, header, footer), Reducto blocks (Section Header, Text, List Item, Table, Key Value), Docling labels (section_header, text, list_item, table, page_header), Azure paragraph roles (title, sectionHeading, pageHeader, pageFooter), Mistral block labels (title, text, list, table, header, footer), and Datalab block types (SectionHeader, Table, Form, PageHeader, PageFooter).
Moda’s 6 Sep 2026 output-contract test shows what this means in practice. On its synthetic mixed-layout page, Unstructured returned checklist lines as NarrativeText while Docling labeled them checkbox_selected or checkbox_unselected, so any code that branches on element type behaves differently after the switch.
Build an explicit type map and a table adapter before switching. A find-and-replace on field names is a rename, not a migration.
Where chunking lives in each tool
Unstructured chunks elements by character, title, page, or similarity, with contextual chunking available in Pipelines. The open-source library lacks by-page and by-similarity chunking. Each alternative puts chunking somewhere different.
Tool | Where chunking happens | Closest to chunk by title |
Foxit PDF Services API | Your code or framework, on Markdown or ordered elements | Split PDF to Markdown output on headings |
LlamaParse | Index v2 with fixed settings, or your code | Your code on per-page Markdown |
Reducto | The parse call, using variable, section, page, page_sections, or block mode | section mode |
Docling | HybridChunker, HierarchicalChunker, or LineBasedTokenChunker, also in Docling Serve | HybridChunker |
Marker and Datalab | A chunks output format, no size settings | chunks output |
Mistral OCR | Your code, or the Search Toolkit splitters (beta) | The toolkit’s Markdown splitter |
Azure Document Intelligence | Your code; Microsoft’s guide uses MarkdownHeaderTextSplitter | MarkdownHeaderTextSplitter |
Google Document AI Layout Parser | The processor: chunkSize in tokens, includeAncestorHeadings | chunkSize with ancestor headings |
Sizes are measured differently across tools. Unstructured and Reducto use characters, Google uses tokens, and Docling’s HybridChunker works through a tokenizer, so the same number produces different chunks depending on the tool.
Chunk boundaries and IDs change with any parser switch, so plan a full re-index rather than mixing old and new chunks in one index.
If chunk-by-title quality is why you chose Unstructured, shortlist the tools that chunk on document structure (Reducto, Docling, Google Layout Parser), or keep your own chunker and swap only the parser.
Which file types each alternative reads
The unstructured library supports more file types than the Transform API. Before choosing, count your files by extension.
Tool | PDF and images | Word, PowerPoint, Excel | HTML | Email (.eml, .msg) |
Unstructured library (baseline) | Yes | Yes, including .doc, .ppt and .xls | Yes | Yes |
Unstructured Transform API (baseline) | Yes | .docx and .pptx only | No | No (the Transform MCP server accepts both) |
Foxit PDF Services API | Yes; images convert to PDF first | Convert to PDF first | Convert to PDF first | No |
LlamaParse | Yes | Yes | Yes | Not documented |
Reducto | Yes | Yes | Yes | On-premises deployments only |
Docling | Yes | Yes; legacy formats need LibreOffice | Yes | Yes |
Marker and Datalab | Yes | Yes | Yes | No |
Mistral OCR | Yes | Yes | No | No (Search Toolkit extractors only) |
Azure Document Intelligence (Layout) | Yes | .docx, .pptx and .xlsx | Yes | No |
Google Document AI Layout Parser | PDF; images through Enterprise Document OCR | .docx, .pptx, .xlsx and .xlsm | Yes | No |
Our convert-then-parse route costs 2 credits per non-PDF file. Azure counts Word and HTML files at 1 page per 3,000 characters. Unstructured counts most files other than PDF, PPTX, TIFF, and DOCX with page metadata at 1 page per 100 KB, so by our calculation a 2,000 KB JPEG bills as 20 pages.
For formats the 8 tools handle poorly, 2 libraries are useful references rather than picks. Apache Tika (4.2.0, Apache-2.0) reads “over a thousand different file types,” and Microsoft MarkItDown (v0.1.9, MIT) is a lighter option to compare against.
One folder of emails or legacy Office files can decide the pick on its own.
Per page or per request
Billing units differ across every tool in this list. Per-request billing favors long PDFs and per-page billing favors short files.
Tool | Billing unit | Example list price | Free allowance |
Unstructured Transform Pay-As-You-Go (baseline) | Page; most non-PDF files by 100 KB of size | $0.015 a page, or $15 per 1,000 pages | 10,000 pages once per account |
Foxit PDF Services API | Request (1 credit), any page count within limits | Business: $4,500 a year for 15,000 credits, or $0.30 per request when all are used | 500 credits a year |
LlamaParse | Credits per page by tier | Cost-effective: $3.75 per 1,000 pages on Pro | 10,000 credits a month |
Reducto | Pages, priced per product | r-1 Parse: $10 per 1,000 pages; r-1 mini: $1 | $150 of usage |
Docling | No charge when self-hosted | Your compute; IBM’s managed service $4 per 1,000 pages | Unlimited on your hardware |
Marker and Datalab | Pages, priced per mode | Balanced: $4 per 1,000 pages; lite: $0.50 | $20 a month on a work email |
Mistral OCR | Pages | OCR 4.1: $4 per 1,000 pages, or $2 with batch | None published |
Azure Document Intelligence | Pages, priced per model | Layout: $10 per 1,000 pages | 500 pages a month, 2 pages per document |
Google Document AI Layout Parser | Pages, priced per processor | $10 per 1,000 pages, chunking included | First 1,000 OCR pages |
Worked example, long document. A 200-page PDF costs $3.00 on Unstructured Transform and 1 credit on our API, allocated at $0.30 with full use of the Business plan’s 15,000 annual credits or $0.35 on Startup. The same file costs $0.75 on LlamaParse Cost-effective at the Pro rate, $2.00 on Reducto r-1, Azure Layout, or Google Layout Parser, and $0.80 on Mistral OCR 4.1 or Datalab balanced, or $0.40 with Mistral’s Batch API. These are list-price calculations, not comparisons of equivalent output or parsing quality.
Worked example, short document. A 2-page PDF costs $0.03 on Unstructured Transform and still 1 credit on our API, against $0.0075 on LlamaParse Cost-effective, $0.008 on Mistral OCR 4.1, and $0.02 on Reducto r-1, Azure, or Google.
Where the lines cross. At $0.30 a request, our API matches Unstructured Transform at 20 pages, Reducto r-1, Azure Layout, and Google Layout Parser at 30 pages, Mistral OCR at 75 pages, and LlamaParse Cost-effective at 80 pages. We calculated these crossovers from list prices, assuming full use of the annual credit pool. Unused credits raise the effective cost.

List-price arithmetic for one document. The flat line assumes full use of the Business plan’s annual credits.
Our paid plans are yearly credit pools. Most per-page APIs in this list are pay as you go. If your volume is unpredictable, that commitment structure changes the economics. See Credits Explained for the precise billing rules, including which calls are not billed.
Estimate cost from your real page-count distribution.
What stays behind in Unstructured
A new parser doesn’t replace Pipelines. These are the layers you keep owning yourself, or keep paying Unstructured for, after the parser changes.
Connectors and sync. Pipelines reads from sources such as S3, SharePoint, Google Drive, and Confluence, with change detection and incremental processing. Among the picks, LlamaParse has 4 connectors that sync about once a day on paid plans, IBM’s managed Docling service lists its own connectors, Docling Jobkit supports sources, and Datalab Collections supports S3 sync. Parser-only routes need your own orchestration for everything else.
Embeddings and enrichment. Unstructured Pipelines embeds with providers such as OpenAI, Bedrock, VoyageAI, and IBM, and can describe tables and images. Most alternatives stop at parsed output. LlamaParse’s Index v2 embeds only into its own managed store.
Scheduling, retries, and monitoring. Pipelines runs workflows as jobs with built-in scheduling. With a parser-only API, your orchestrator owns retries and alerts.
Compliance scope. Unstructured’s SOC 2 Type 2, ISO 27001, HIPAA, and FedRAMP High coverage, listed earlier, may not carry over to the tool you pick. Compare each alternative’s claims for the plan you would actually buy, not the enterprise tier.
When to keep Unstructured
Keep Unstructured Pipelines if you rely on its source sync from systems such as SharePoint, Confluence, or Slack, or on its enrichment and embedding workflow and a replacement would leave those needs unmet. Check email and legacy-format support before switching, and confirm that the replacement meets your compliance requirements, including FedRAMP High where needed. Replace the layer that fails, not the pipeline that works.
Building a parsing pipeline on the PDF Services API
If the parser is the layer that fails, the PDF Services API slots in at the parsing step and leaves the rest of your pipeline in place. Each file follows the same path.
Upload it, convert or OCR it first if it isn’t a text-layer PDF, submit PDF to Markdown or PDF Structural Extraction (Trial), poll the task, download the Markdown or ZIP, and hand the result to your chunker.

Only the operation calls use credits. Uploads, polling, and downloads are free.
Parsing shares a credit pool with other PDF operations. Convert Office files, images, HTML, and Markdown to PDF before parsing, split long files, and redact sensitive content using text matching, rectangle regions, or form-field targeting before it reaches an index. That covers the pre-processing pipeline without switching APIs or billing systems. Our conversion walkthrough shows the DOCX-to-PDF path, and our text extraction tutorial covers the text extraction route.
The API has no chunking, embedding, or connector layer, so pair the output with your own chunker and orchestrator. Elements arrive in reading order, which means heading-based splitting on title and head elements works without reordering. Our structured JSON tutorial shows how to work with the Structural Extraction output.
Our MCP server exposes structural analysis, extraction, and OCR tools to agents. Our MCP server walkthrough covers the 30+ PDF tools it gives AI agents and the integration details.
Plans and credits. The free Developer plan needs no credit card. See Foxit API pricing for plan details, or Credits Explained for how credits are counted.
What else to know before you switch from Unstructured
This section answers 3 practical questions that come up in the transition.
Which LangChain and LlamaIndex loaders replace UnstructuredLoader?
UnstructuredLoader ships in the langchain-unstructured package. Docling has an official DoclingLoader for LangChain and a Docling Reader and Node Parser for LlamaIndex. Azure has AzureAIDocumentIntelligenceLoader. Google has DocAIParser, which is OCR-oriented. For LlamaParse, the documented pattern wraps each parsed page in a LangChain Document using the llama-cloud SDK.
Reducto, Datalab, and our PDF Services API have no documented LangChain or LlamaIndex loader. For those tools, and for Mistral OCR, check your framework’s integration list or call the SDK or REST API and build Document objects yourself.
How to run multiple parsers in the same pipeline?
You can route by file type or page complexity, sending emails and legacy Office files to Docling or Unstructured, long PDFs to a per-request API, and hard scans to a VLM tier. Normalize every output into one element schema, and chunk in one place so retrieval behaves consistently. Maintaining multiple parsers adds real cost and complexity, but so does forcing all your documents through a single parser that handles some of them poorly.

One router, one element schema, and one chunker keep retrieval consistent across parsers
How to test an alternative against your current Unstructured output?
Published results only go so far. Moda ran 4 synthetic PDFs and the 48-page NIST AI RMF PDF on 6 Sep 2026, and Unstructured OSS 0.27.5 reached 98.3% macro literal recall on the synthetic set, alongside the NIST result described in the introduction. A March 2025 Procycons test of an older Unstructured version measured 75% cell accuracy on 1 sampled complex table. Both are single-run observations with specific dates and document sets, not general benchmarks, so build your own test set.
Keep 20 to 50 of your hardest documents, especially ones that already fail. Run them through Unstructured and 1 or 2 candidates. Compare element types, table cells, chunk boundaries, and answers to a fixed set of questions, plus cost at your real page counts. That comparison on your actual documents is more reliable than any synthetic benchmark
8 Best Amazon Textract Alternatives for Document Data Extraction

Leaving Amazon Textract? First check whether a cheaper Textract API already solves your cost problem. This guide compares 8 AWS Textract alternatives on pricing, language coverage, limits, and data terms, so you can match each API to the calls your pipeline makes.
If your Textract bill is higher than expected, check which API you’re calling before switching vendors.
For invoice fields, AnalyzeExpense costs $0.01 per page, compared with $0.07 for AnalyzeDocument with Forms, Tables, and Queries enabled.
At 100,000 single-page invoices a month, that’s $1,000 vs. $7,000 (our arithmetic from AWS list prices, US East). Check that AnalyzeExpense returns the fields your pipeline needs before changing APIs.
There are real reasons to leave, though. Textract reads printed text in more than 40 languages, but Forms key-value extraction covers only 6 of them, and handwriting, Queries, AnalyzeExpense, and AnalyzeID are English only.
AnalyzeID reads only US passports and US driver’s licenses. Synchronous calls take a single page, and Amazon Augmented AI (A2I), the human-review integration for Textract, closed to new customers on 30 Jul 2026. Some teams also want schema-based extraction, a specific data-residency posture, or pricing that doesn’t compound by feature combination.
In this article, we compare 8 Amazon Textract alternatives based on their extraction features, pricing, usage limits, deployment options, and migration requirements.
Some return document structure; others extract named fields. The right replacement depends on which Textract APIs your pipeline uses.
Our top picks by reason for switching
The best alternatives to Amazon Textract depend on why you’re leaving.
Azure Document Intelligence and Google Document AI cover the broadest set of Textract workflows, with prebuilt models at $10 per 1,000 pages on Azure and the Custom Extractor at $30 per 1,000 pages on Google, while the Foxit PDF Services API, Mistral OCR, and Amazon Bedrock Data Automation offer different billing models that favor long documents, high volume, or staying on AWS.
For teams that can’t move documents off their own infrastructure, Docling is the only open-source option here you can run with no vendor contract.
Because AnalyzeExpense already matches or undercuts most options here on 1-page invoices, the strongest arguments for switching are language coverage, schema extraction, data terms, or long-document pricing rather than invoice cost reduction.
Each API appears once, under the reason it fits best. List prices in US regions at first pricing tier.
If you are leaving Textract because… | Pick | Why it fits |
Long PDFs get billed per page at the selected feature-combination rate | 1 credit per successful PDF Services processing call within supported limits; scans need OCR before structural extraction. Credits are shared with other Foxit APIs, but eSign uses 5 credits per envelope. | |
You want comparable models for common Textract workflows | Prebuilt invoice, receipt, ID, bank statement, tax and mortgage models at $10 per 1,000 pages, query fields, and about 300 printed languages | |
Your documents are handwritten, or need field extraction beyond English | OCR for more than 200 languages including handwriting and a generative Custom Extractor at $30 per 1,000 pages | |
You want to stay on AWS | Blueprint fields with confidence scores at $0.04 a page for up to 30 fields, through your AWS account, with IAM and Amazon S3 integration | |
Per-page cost at high volume | OCR 4.1 at $4 per 1,000 pages, or $2 with the Batch API, with schema annotations at $5 per 1,000 annotated pages | |
Every extracted value needs evidence for review | Per-field citations with bounding boxes (except Turbo) and 0-1 confidence scores, from 8 credits a page (about $0.012 on pay-as-you-go) | |
Mixed document packets, or extraction inside your own VPC | Extract at $20 per 1,000 pages including parsing, Split and Classify endpoints, hybrid and full VPC deployments on Enterprise | |
Documents cannot leave your own servers | MIT-licensed, runs locally or air-gapped, Docling Serve REST API, schema extraction through DocumentExtractor |
If per-request pricing could work for your document mix, you can test it on a free Foxit developer account before deciding.
What Amazon Textract gives you today
The table below uses US East (N. Virginia) list prices from the AWS Price List API feed published 27 Oct 2026. Synchronous and asynchronous calls cost the same.
Textract API or feature | What it returns | Per 1,000 pages, first 1M a month | Above 1M pages a month | Free tier, first 3 months |
DetectDocumentText | Lines and words with confidence and geometry | $1.50 | $0.60 | 1,000 pages a month |
AnalyzeDocument Tables | Tables, cells, merged cells, table titles and footers | $15 | $10 | 100 pages a month |
AnalyzeDocument Forms | Key-value pairs and selection elements | $50 | $40 | 100 pages a month |
AnalyzeDocument Queries | Answers to questions you write (English) | $15 | $10 | 100 pages a month |
Forms and Tables together | Key-value pairs, selection elements and tables in a single call | $50 | 100 pages a month | |
Forms, Tables and Queries together | All 3 in a single call | $70 | $55 | 100 pages a month |
Layout | Titles, headers, paragraphs, lists, figures | $4, free with Forms, Tables or Queries | $3 | 100 pages a month |
Signatures | Signature locations | $3.50, free with Forms, Tables, Queries or Layout | $1.40 | 1,000 pages a month (Signatures only) |
AnalyzeExpense | Invoice and receipt fields and line items (English) | $10 | $8 | 100 pages a month |
AnalyzeID | US passports and US driver’s licenses (English) | $25 for the first 100,000 pages | $10 above 100,000 | 100 pages a month |
AnalyzeLending | Mortgage packages classified, split and extracted | $70 | $55 | 2,000 pages a month |
Custom Queries (adapters) | Queries tuned on your own documents | $25 | $15 | Not available |
How billing works. AnalyzeDocument bills each page at the rate for the feature combination you request, and Forms with Tables bills as the sum of the 2 feature rates, $65 per 1,000 pages. Every AnalyzeDocument response includes OCR. The free tier covers new AWS customers for 3 months.
What are the limitations of Amazon Textract? Synchronous calls take a single-page PDF or TIFF up to 10 MB. Asynchronous PDF/TIFF jobs read up to 3,000 pages and 500 MB from Amazon S3, announce completion on Amazon SNS, and keep results for 7 days by default.
Text detection, Tables, Signatures, and Layout support more than 40 languages, including Arabic, Chinese, Japanese, Korean, and Hindi. Forms covers only English, German, French, Spanish, Italian, and Portuguese.
Handwriting, Queries, AnalyzeExpense, and AnalyzeID are English only, and AnalyzeID reads only US passports and US driver’s licenses. Textract reads horizontally aligned text only, and XFA PDFs and password-protected PDFs are unsupported. Default quotas in US East (N. Virginia) are 10 transactions a second for AnalyzeDocument, 25 for DetectDocumentText, and 5 for AnalyzeExpense.
Data use. AWS may store and use Textract document inputs to improve Textract and other AWS AI services, and may store some of that content in another region, unless you set an AWS Organizations AI services opt-out policy. Textract is HIPAA eligible and compliant with PCI, ISO, and SOC, available in 18 regions including both AWS GovCloud (US) regions.
Human review. Amazon A2I is no longer open to new customers as of 30 Jul 2026, and existing users can keep it. Textract itself is unaffected by that announcement, and AWS shipped a text-detection model update for DetectDocumentText and AnalyzeDocument on 30 Jun 2025.
Before comparing alternatives, list the Textract APIs your pipeline calls, with monthly pages for each. That list tells you whether a cheaper Textract API (often AnalyzeExpense in place of AnalyzeDocument) already solves the cost problem, and if not, which alternative can replace each call and what it will cost.
The 8 Amazon Textract alternatives in detail
In each entry’s feature table, the Covers row maps the API to Textract’s jobs (OCR, Tables, Forms, Queries, Signatures, Layout, AnalyzeExpense, AnalyzeID, AnalyzeLending), and the Moving from Textract row names the biggest change you’ll make in your code.
Foxit PDF Services API

Our PDF Services API product page, which covers conversion, extraction and optimization from one REST API.
The Foxit PDF Services API is our REST API for PDF conversion, OCR, extraction, redaction and form handling.
Feature | Details |
Covers | OCR (Perform OCR endpoint), layout and tables through PDF Structural Extraction (Trial), tables to Microsoft Excel workbooks (XLSX) through PDF to Excel, fillable-form values through Export PDF Form Data, plus Markdown through PDF to Markdown and PDF to text. No counterpart for Queries, Signatures, AnalyzeExpense, AnalyzeID or AnalyzeLending. |
Field extraction | No schema-based extraction and no prebuilt invoice or ID models. Structural Extraction returns 12 element types in reading order (title, head, paragraph, table, image, headerFooter, form, hyperlink, footnote, sidebar, annotation, formula), where text elements carry an 8-number bounding polygon and a confidence score, and table elements carry their polygon under regions and their confidence under scores, returned as cell grids. Export PDF Form Data returns JSON keyed by the PDF’s form field names, reading interactive fields rather than key-value pairs printed on a scan. |
OCR and languages | The Perform OCR endpoint takes a list of OCR language codes in its languages setting, such as en-US. Structural Extraction returns no text on image-only PDFs unless you run the OCR endpoint first, so scanned documents take 2 credits in total. Handwriting support is not documented. |
Pricing | 1 credit per successful request, regardless of page count or file size within supported limits (Credits Explained). Developer (plan pricing): 500 credits/year (free). Startup: $1,750/year (5,000 credits, $0.35/credit). Business: $4,500/year (15,000 credits, $0.30/credit). Volume: by quote. Credits reset yearly with no rollover. |
Free allowance | 500 credits a year on the Developer plan. |
Limits | 100 MB upload. Per application: 15 requests a minute in sandbox, 100 in production. Asynchronous: upload, start the operation, poll the task, download the result. Page limit per request is not published. |
Deployment and data | Cloud only, through one global API gateway. A delete endpoint removes uploaded and generated files. Our cloud-hosted PDF APIs are covered by SOC 2 Type II audits, and we support HIPAA BAAs. Our MCP server (v1.1.2), built on the Model Context Protocol, exposes pdf_structural_analysis, pdf_extract and pdf_ocr tools. |
Moving from Textract | Upload the file instead of pointing at S3, poll the task instead of waiting for SNS, parse an elements array instead of Blocks and Relationships, and send your client ID and client secret as request headers instead of signing requests with IAM. |
Where Foxit PDF Services API stands out is per-request pricing. A 50-page digital statement costs 1 credit where Textract bills all 50 pages at the selected feature-combination rate.
On the Business plan with all 15,000 annual credits used, that works out to $0.30 per request, which is less than Textract Tables above roughly 20 pages and less than Forms with Tables from about 5 pages (our arithmetic from list prices, not an equivalent-output benchmark).
Extraction also sits on the same credit pool as conversion, redaction, eSign and document generation, so a pipeline that already converts, signs or redacts consolidates billing in one place. For fillable PDFs, Export PDF Form Data returns exact field values without any OCR layer.
What to consider. Our PDF Structural Extraction API is currently in Trial and uses schema version v1.0.7. The API may change, so validate responses against the schema your application expects. There’s no key-value detection on scanned forms, no Queries counterpart and no prebuilt invoice or ID model, so a team replacing AnalyzeExpense or AnalyzeID will need to pick a different option.
Scanned documents take 2 credits (OCR then extraction), equivalent to $0.60 to $0.70 at full use of the Business or Startup annual credit pool, respectively. That is 60 to 70 times AnalyzeExpense’s $0.01 per page, without the same prebuilt invoice fields.
Credits reset annually with no rollover; mid-cycle top-ups are available and expire at the same reset date. Our retention period for uploaded files is not published, so call the delete endpoint after each job. We don’t use the documents you submit to train AI models unless you authorize it.
Best for. Long, structured PDFs (statements, contracts, reports) and fillable forms in pipelines that also convert, OCR, redact or sign documents.
Getting started. A free Foxit developer account includes 500 credits a year, enough to test PDF Structural Extraction on a few of your own long documents.

Our developer sign-up page, where a new account comes with live API credentials and 500 free credits a year.
Azure Document Intelligence

Azure Document Intelligence product page, now listed under Foundry Tools and Azure Content Understanding.
Azure Document Intelligence (first Form Recognizer, then Azure AI Document Intelligence) is Microsoft’s document analysis service in Foundry Tools (API v4.0, 2024-11-30), now part of Azure Content Understanding.
Feature | Details |
Covers | Read (OCR), Layout (tables, selection marks, key-value pairs with keyValuePairs feature), prebuilt invoice, receipt, ID, bank statement, check, pay stub, contract, US tax and US mortgage models, query fields, and custom classification for splitting packets. Counterparts exist for OCR, Tables, Forms, Queries, AnalyzeExpense, AnalyzeID and AnalyzeLending workflows. Signature detection is supported by custom neural and custom template models. |
Field extraction | Prebuilt models return named fields with confidence scores and polygons. Custom template, custom neural and custom generative models cover layouts the prebuilt models miss. Query fields extend Layout and most prebuilt models, similar to Textract Queries. |
OCR and languages | Read and Layout cover about 300 printed languages and 12 handwritten languages in v4.0 (language support). |
Pricing | East US pay-as-you-go, per 1,000 pages (from the Azure Retail Prices API, checked 5 Nov 2026): Read $1.50, then $0.60 above 1 million. Layout and prebuilt models cost $10, custom extraction or custom generative extraction costs $30, add-ons cost $6, and query fields cost $10. Batch costs the same as standard. Azure cloud commitment tiers start at $190/month for 20,000 prebuilt pages. |
Free allowance | 500 pages/month on the F0 tier, which analyzes only the first 2 pages of each document (4 MB cap, 1 request/second). |
Limits | S0: 500 MB and 2,000 pages per analysis; 15 analyze requests/second by default, adjustable. Submit, then poll the operation, plus a batch API. |
Deployment and data | Azure regions. v4.0 containers cover Read and Layout only, including disconnected tiers (prebuilt invoice, receipt and ID containers are supported in v3.1). Inputs and results are deleted 24 hours after analysis completes, or earlier through the Delete Analyze Result API. |
Moving from Textract | Forms become Layout key-value pairs or a prebuilt model; Queries become query fields; AnalyzeExpense becomes the invoice and receipt models; AnalyzeID becomes the ID model; Custom Queries adapters become custom models. S3 and SNS give way to URL or Azure Blob Storage input and polling. |
Where Azure Document Intelligence stands out is the breadth of prebuilt counterparts for Textract’s most-used workflows. The prebuilt invoice and receipt models price at $10 per 1,000 pages, matching AnalyzeExpense.
Handwriting covers 12 languages where Textract reads handwriting only in English, and the prebuilt invoice model supports many locales where AnalyzeExpense is English only. For teams that can’t call a cloud API from every environment, v4.0 containers cover Read and Layout without a network connection.
What to consider. The v4.0 container images cover only Read and Layout, so if you need containerized invoice, receipt or ID extraction, you’re on v3.1.
The free tier reads only 2 pages per document, which means a 20-page invoice returns 2 pages during evaluation. Content Understanding‘s LLM-powered analyzers (GA with API 2025-11-01, from $5 per 1,000 pages for Standard content extraction plus contextualization and model tokens) are worth evaluating alongside the prebuilt models.
Best for. Teams moving invoices, receipts, IDs and tax forms off Textract that want like-for-like prebuilt models, or that already run on Azure.
Getting started. Azure Document Intelligence quickstart.
Google Document AI

Google Document AI product page, which positions it as a processor platform for extracting, classifying and splitting documents.
Google Document AI is Google Cloud’s document understanding platform, with a range of prebuilt parsers, a Layout Parser, a Form Parser and a generative Custom Extractor built on Gemini. Its OCR reads more than 200 languages, including handwriting.
Feature | Details |
Covers | Enterprise Document OCR, Layout Parser, Form Parser (key-value pairs, checkboxes, tables), Custom Extractor, prebuilt Invoice, Expense, Bank statement, Pay slip, W2, US driver license, US passport and ID proofing parsers, and custom classifiers and splitters. Counterparts for OCR, Tables, Forms, Queries, AnalyzeExpense, AnalyzeID and lending packets. |
Field extraction | Custom Extractor defines up to 150 labels by schema (generative with Gemini, or trained), at the same prediction price. Versions v1.5 and v1.5-pro are GA, while v1.5.1, v1.6, v1.6-pro, v3.1-lite and v3.5 are Public Preview. Prebuilt parsers and Form Parser return entities and key-value pairs with confidence and bounding boxes. |
OCR and languages | Enterprise Document OCR reads printed and handwritten text in more than 200 languages, and handwriting support varies by language. |
Pricing | Per 1,000 pages (Document AI pricing, checked 5 Nov 2026): OCR $1.50 (then $0.60 above 5 million); Layout Parser $10; Form Parser and Custom Extractor $30 (then $20 above 1 million). Invoice and Expense parsers cost $0.10 per document (up to 10 pages); ID parsers $0.10 per document; Bank statement $0.75 per document; Pay slip and W2 $0.30 per document. |
Free allowance | The first 1,000 Enterprise Document OCR pages are free. |
Limits | Online requests: up to 15 pages (30 in imageless mode where supported, 10 for Expense, 2 for ID parsers) and 40 MB. Batch caps pages per document by processor (OCR and Layout 500, Custom Extractor and Invoice 200, Form Parser 100, Bank statement 30). Most batch jobs finish 12 to 24 hours after they start running, excluding queue time. |
Deployment and data | US and EU multi-regions plus limited-access regions; VPC Service Controls and customer-managed keys. Online document data is processed in memory and not persisted to disk, and batch documents are deleted after processing, with a 1-day failsafe TTL. Document AI models are not trained on customer data. Custom Extractor v1.6 and v1.6-pro use the Vertex AI global endpoint and are not data-residency compliant, while v3.1-lite supports US and EU multi-region endpoints. |
Moving from Textract | Queries and Custom Queries become Custom Extractor fields; AnalyzeExpense becomes the Invoice or Expense parser; S3 input becomes Cloud Storage for batch; SNS gives way to long-running operation polling. Google deprecated Document AI’s human-in-the-loop review on 16 Jan 2024, so you’ll need to build your own review step. |
Where Google Document AI stands out is handwriting in many languages, where Textract reads handwriting only in English, plus a generative Custom Extractor that defines fields by schema without training data.
What to consider. Per-document parser pricing means a 1-page invoice costs $0.10 through the Invoice parser, which is 10 times AnalyzeExpense. Online page limits vary by processor (up to 15 pages, or 30 in imageless mode where supported), so longer documents go through batch with 12-24 hour turnaround. The newest Custom Extractor versions (v3.5, v3.1-lite) are Preview, and data-residency support varies by version. Human review is deprecated, so budget for your own queue.
Best for. Multilingual or handwritten documents, or pipelines already on Google Cloud.
Getting started. Document AI quickstart.
Amazon Bedrock Data Automation

Amazon Bedrock Data Automation product page, part of Amazon Bedrock and covering documents, images, audio and video.
Amazon Bedrock Data Automation (BDA) is an AWS-managed service for extracting structured data from documents.
It lets teams add schema-defined fields while reusing IAM and S3 rather than moving to another cloud provider.
Feature | Details |
Covers | Standard output (text, Markdown, HTML or CSV tables at page, element or word level, with bounding boxes and summaries) and custom output through blueprints, plus document splitting and routing across up to 40 document blueprints per project. Blueprints can stand in for Forms, Queries, AnalyzeExpense, AnalyzeID and AnalyzeLending. AWS catalog blueprints reference a US driver license and a W-2. |
Field extraction | Blueprints define typed fields (strings, numbers, booleans, arrays and tables) with natural-language normalization and validation instructions. Document fields return confidence scores and page references. Up to 100 leaf fields per blueprint. |
OCR and languages | English, German, Spanish, French, Italian and Portuguese, printed and handwritten. Vertical text is not supported. |
Pricing | Standard output $0.010/page, custom output $0.040/page for 1 to 30 fields, plus $0.0005/page for each field above 30, and blueprint optimization $0.010 per example page. |
Free allowance | No BDA-specific free tier published as of 5 Nov 2026. |
Limits | Asynchronous: PDF, TIFF, JPEG, PNG, DOC and DOCX up to 500 MB, up to 3,000 pages with splitting on; 25 concurrent document jobs by default in most regions, 5 in Mumbai, Singapore, Canada (Central), Spain and London. Synchronous: up to 10 pages and 50 MB, 60 requests/minute. |
Deployment and data | AWS-managed service available through your account, including in GovCloud (US-West). Asynchronous output goes to S3, and synchronous JSON can be inline or S3. BDA requires cross-region inference profiles, so requests and results may move outside your primary region while stored data stays there. Bedrock inputs and outputs are not used to train Amazon Nova, Amazon Titan or third-party models. |
Moving from Textract | IAM, S3 and your account stay the same. The Block parser gives way to blueprint JSON. Custom Queries adapters become blueprints. A2I is closed to new customers, so route low-confidence fields to your own review queue. |
Amazon Bedrock Data Automation lets you keep IAM and S3 while adding schema-defined fields with confidence scores. Custom output costs $0.04 per page for up to 30 fields, with an additional charge for each field above 30.
An AWS Builder Center guide to choosing an IDP service points to BDA for “net-new IDP projects” and to Textract with foundation models for “extending an existing Textract implementation.”
What to consider. Custom output at $0.04/page costs 4 times AnalyzeExpense per invoice page. The cross-region inference requirement adds a layer to residency reviews. BDA reads 6 languages, the same set as Textract Forms and far fewer than the 40-plus Textract supports for printed text, though unlike Textract it reads handwriting in all 6.
Best for. AWS-native teams starting a new extraction workload or adding document types without training adapters.
Getting started. What is Bedrock Data Automation, in the Amazon Bedrock user guide.
Mistral OCR

Mistral OCR product page, with sample tabs for contracts, tables, invoices and handwriting.
Mistral OCR is a dedicated OCR and document annotation API from Mistral AI. OCR 4.1 (mistral-ocr-latest, released 16 Jul 2026) returns per-page Markdown at $4 per 1,000 pages, with schema-based field extraction available through document annotations.
Feature | Details |
Covers | OCR to per-page Markdown, tables as Markdown or HTML, header and footer extraction, and blocks with bounding boxes and labels (including a signature label). Document AI annotations return JSON in your schema. Stands in for DetectDocumentText, Tables, Layout and, through annotations, Queries and AnalyzeExpense. Extraction uses a supplied schema. |
Field extraction | document_annotation fills a JSON schema for the whole document; bbox_annotation describes extracted figures. A second model, mistral-small-2603, generates the annotations after OCR. Per-field confidence is not documented for annotations; OCR confidence can be set at page, block or word level. |
OCR and languages | Reads more than 40 languages, and image input works even from low-quality or handwritten sources. |
Pricing | OCR 4.1: $4 per 1,000 pages standard, or $2 per 1,000 pages with the Batch API. Annotations: $5 per 1,000 annotated pages. OCR 3 remains available at $2 per 1,000 pages. OCR 4.0 retired 30 Sep 2026. |
Free allowance | A free mode is available with organization-level rate limits, and it may use inputs and outputs for training unless you opt out. |
Limits | 50 MB and 1,000 pages per document. Rate limits are set per organization. |
Deployment and data | Mistral API, Amazon SageMaker and Microsoft Foundry. Single-container self-hosting for enterprise customers. Zero data retention on /v1/ocr requires approved paid access and excludes batch files and /v1/files. Pay-as-you-go customers can opt out of training. |
Moving from Textract | Rewrite Queries as a JSON schema and line items as a schema array, parse Markdown and blocks instead of Blocks, and use the Batch API for asynchronous volume. |
Where Mistral OCR stands out is cost for OCR with tables. OCR 4.1 returns Markdown with tables at $4 per 1,000 pages, or $2 through the Batch API, well under Textract’s $15 per 1,000 pages for Tables. Annotations then add schema-based extraction to the same API call.
What to consider. OCR 4 is designed for high-throughput processing rather than real-time or latency-sensitive use, which matters if you currently call Textract synchronously. Models retire quickly (OCR 4.0 shipped 23 Jun 2026 and retired 30 Sep 2026, about 3 months later), so plan for version updates. Free mode may train on your documents unless you opt out.
Best for. High-volume invoice or form extraction where per-page cost is the primary constraint and a schema can replace Queries.
Getting started. Mistral OCR API documentation.
LlamaExtract (by LlamaIndex)

LlamaExtract product page, which maps a custom schema to extracted fields.
LlamaExtract is the hosted schema extraction service on LlamaIndex’s LlamaParse platform. Optional citations and confidence scores support field-level review; citation bounding boxes are available on the primary tiers, but not Turbo.
Feature | Details |
Covers | Schema extraction with JSON Schema or Pydantic (Zod in TypeScript), schemas generated from a prompt or a sample file, and a spreadsheet mode. Stands in for Forms, Queries and AnalyzeExpense through your schema. Extract v2 uses schemas you supply or generate. |
Field extraction | Up to 3,200 leaf fields on Cost-effective, Agentic and Agentic Plus, with large schemas on Cost-effective and Agentic requiring version 2.1 or later. Citations return the page, verbatim text and bounding boxes for each field (except Turbo, which has text-level citations only). Confidence is a 0-1 score per field. Both citations and confidence are off by default in the API and slow processing. |
OCR and languages | Primary tiers use LlamaParse OCR with more than 80 OCR language codes. Turbo prepares inputs without a separate Parse step. |
Pricing | $1.50 per 1,000 credits on pay-as-you-go ($0/month), or $1.25 per 1,000 on Pro ($500/month). Credits per page with default parsing: Cost-effective 8 (about $0.012, or $0.010 on Pro), Agentic 25 (about $0.0375, or $0.031), Agentic Plus 60 ($0.09, or $0.075), Turbo 35 (about $0.0525, or $0.044). |
Free allowance | 10,000 free credits a month on pay-as-you-go, about 1,250 Cost-effective pages (our arithmetic). |
Limits | 100 MB and 500 pages per extraction job. Concurrent extract jobs: 5 on pay-as-you-go, 20 on Pro, 100 on Enterprise. |
Deployment and data | Managed SaaS in North America or the EU. Enterprise deployments add single-tenant SaaS, bring-your-own-cloud (AWS, Azure or GCP) and self-hosting. Files are cached 48 hours unless you set do_not_cache. No training on customer data by default. SOC 2 Type II audited, with a HIPAA BAA for Enterprise. |
Moving from Textract | Queries become schema fields, Block geometry becomes per-field citations with boxes on the primary tiers, and confidence moves from Textract’s 0-100 scale to 0-1. |
Where LlamaExtract stands out is the field-level evidence model on the primary tiers, providing a citation box plus a confidence score per field. The Cost-effective tier costs about $0.012 a page on pay-as-you-go and $0.010 on Pro, close to AnalyzeExpense’s $0.01, so teams migrating invoice extraction pay a similar rate and gain citation support.
What to consider. The 500-page cap per extraction job is a real constraint for long documents. Citations and confidence scores are off by default in the API and can add processing time. Enable them when your review workflow needs the evidence, then measure the latency on your documents. Concurrency caps (5 concurrent extract jobs on pay-as-you-go) matter for burst workloads. You’ll need to supply or generate an extraction schema, which adds an upfront build step.
Best for. Teams replacing Queries or AnalyzeExpense with a schema that need field-level evidence for review queues.
Getting started. LlamaExtract documentation.
Reducto

Reducto home page, which presents it as a single platform for every document task.
Reducto is a document extraction API that includes parsing in the extraction price and supports mixed-document packets through its Split and Classify endpoints. Per-product pricing launched on 1 Sep 2026, with pay-as-you-go accounts moving on 1 Oct 2026.
Feature | Details |
Covers | Extract (JSON in your schema, parsing included), Deep Extract, Parse, Split, Classify and Edit. Stands in for Forms, Queries and AnalyzeExpense through schemas, and for AnalyzeLending-style packets through Split and Classify. You define the extraction schema. |
Field extraction | With citations on: normalized 0-1 page boxes for PDFs and images (the same convention as Textract’s BoundingBox), a high or low confidence label, and numeric extract and parse confidence. Some values have empty citation arrays. Extractions over 100 fields per page may carry a per-field surcharge that is not published. |
OCR and languages | Parsing reads scanned documents, and agentic mode handles handwritten or degraded text. Standard OCR covers 60+ languages. |
Pricing | Per 1,000 pages: Extract $20 and Deep Extract $40, both with parsing included; Parse r-1 $10 and Parse r-1 mini $1; Split $20; Classify $7.50. The batch queue takes 20% off Parse and Extract (12-hour completion), not Deep Extract. |
Free allowance | The Standard plan includes $150 in free usage, then list rates apply. Reducto also offers up to $5,000 in migration credits to teams switching processors (vendor offer). |
Limits | 100 MB direct upload (5 GB through presigned upload), no page limit on Standard, synchronous calls have a 15-minute hard timeout, and up to 1,000 requests/second per key (300 for job-status polling). Standard concurrency baselines of 500 pages in the US and 250 in the EU for r-1. |
Deployment and data | SaaS, with EU and Australian endpoints from Growth. Hybrid VPC and full VPC or on-premises on Enterprise. Results are generally available for 12 hours. From Growth up, zero data retention purges API artifacts within 24 hours (except Studio jobs and persist_results) and data is never used for training. The Standard plan training policy is not stated. Has completed a SOC 2 Type II audit and HIPAA BAAs on Growth and Enterprise. |
Moving from Textract | Normalized citation boxes need no coordinate conversion for PDFs and images. Queries become schema fields. AnalyzeLending-style packets map to Split, Classify and Extract. |
Where Reducto stands out is that parsing is included in the extraction price, so you’re not paying separately for a Parse step and an Extract step. Citation boxes use the same 0-1 normalized coordinates as Textract’s BoundingBox, which reduces the coordinate-conversion work during migration. The hybrid VPC option keeps files in your own storage while processing runs on Reducto’s GPUs.
What to consider. An unpublished per-field surcharge above 100 fields per page adds pricing risk for complex schemas. The Standard plan’s training policy is not stated, so confirm training terms before sending regulated documents.
Best for. Long or mixed packets (lending, insurance, logistics) that need splitting and extraction with citations, possibly inside a VPC.
Getting started. Reducto API documentation.
Docling

The Docling home page, which leads with a one-line pip install and local, offline use.
Docling is an open-source document parsing library from IBM Research, now an LF AI & Data project. Its MIT license allows production use at no cost.
Feature | Details |
Covers | Open-source parsing of PDF, Office, HTML and image files to Markdown and lossless JSON with layout, tables and reading order, plus schema extraction through DocumentExtractor. Docling Serve exposes a REST API. Stands in for DetectDocumentText, Tables, Layout and simple Queries-style fields. You supply the field-extraction template. |
Field extraction | DocumentExtractor takes a JSON, dict or Pydantic template and returns extracted data per page, using a vision-language model, on PDFs and images only. DocumentExtractor returns no per-field confidence or bounding boxes. |
OCR and languages | Pluggable OCR engines (RapidOCR, EasyOCR, Tesseract, OcrMac, Nemotron-OCR). Language coverage depends on the engine you choose. |
Pricing | Free under the MIT license (models carry their own licenses). You pay for compute; a GPU helps with the vision-language pipeline. |
Free allowance | Unlimited on your own hardware. |
Limits | Set by your hardware and configuration. |
Deployment and data | Runs locally or air-gapped. Docling Serve (v1.38.2) runs in containers. Docling for IBM watsonx is the managed option. An LF AI & Data project started at IBM Research. |
Moving from Textract | You replace a managed API with a service you run, so you own scaling, monitoring, OCR quality and model updates. |
Where Docling stands out is that with local models and remote services disabled, documents stay in your infrastructure, and there is no per-page software fee.
What to consider. You run and scale it yourself. DocumentExtractor works per page without built-in per-field confidence scores, so quality depends on the models and hardware you choose. Frequent releases mean pinning versions keeps production stable.
Best for. Documents that cannot leave your own servers or network.
Getting started. Docling on GitHub.
What changes when you move off Amazon Textract
Switching changes what you pay per document and which parts of your pipeline you rewrite, starting with cost.
What one document costs on each API
List prices as of November 5, 2026, using US regions and the first pricing tier where applicable. Each invoice is 1 page. These are calculations from list prices, not equivalent-output benchmarks: OCR-only rows do not include named invoice fields, and the statement column uses the mode shown in each cell.
API and mode | 1-page scanned invoice | 50-page digital statement | 100,000 invoices a month |
Amazon Textract, AnalyzeExpense | $0.01 | $0.075 (DetectDocumentText) | $1,000 |
Amazon Textract, Forms, Tables and Queries | $0.07 | $3.50 | $7,000 |
Foxit PDF Services API (Business) | 2 credits (OCR then Structural Extraction), or $0.60 on Business | 1 credit, or $0.30 on Business | Volume pricing by quote: 2.4 million credits a year for scanned invoices, or 1.2 million for digital PDFs, before any additional processing calls |
Azure Document Intelligence, prebuilt invoice | $0.01 | $0.50 (Layout) | $1,000, or $900 on the 100,000-page commitment tier |
Google Document AI, Invoice parser | $0.10 (Custom Extractor prediction $0.03) | $0.50 (Layout Parser) | $10,000 (Custom Extractor $3,000; custom-model hosting extra) |
Amazon Bedrock Data Automation, custom output | $0.04 | $0.50 (standard) | $4,000 (custom) |
Mistral OCR 4.1, OCR only | $0.004 | $0.20 | $400 |
LlamaExtract, Cost-effective (pay-as-you-go) | $0.012 | $0.60 | $1,200, or $1,000 on Pro |
Reducto, Extract | $0.02 | $1.00 | $2,000, or $1,600 with batch |
Docling, self-hosted | Your compute | Your compute | Your compute |
Foxit figures assume full use of the yearly credit pool (Business is $4,500 for 15,000 credits, $0.30 per credit; Startup works out to $0.35). Each successful PDF Services processing call costs 1 credit within supported limits, and each separate call in a batch uses 1 credit.
Invoices. At list price, AnalyzeExpense costs $0.01 per invoice page, matching or undercutting most options here. Azure’s prebuilt invoice model matches it at $0.01, and LlamaExtract’s Cost-effective tier comes close at about $0.012 on pay-as-you-go ($0.010 on Pro). Mistral’s OCR-only rate comes in lower still. Google’s Invoice parser costs 10 times more on 1-page invoices because it bills per document.
Long documents. Per-request billing changes the calculation. On digital PDFs, Foxit at $0.30 per request costs less than Textract Tables above roughly 20 pages and less than Forms with Tables from about 5 pages. On scanned documents (2 credits at $0.30 each), the crossovers shift to roughly above 40 pages and from about 10 pages. That comparison is price only, since Foxit returns document structure and form-field values, while Textract’s Forms feature detects key-value pairs on printed and scanned pages.

List-price arithmetic only. A digital PDF on Foxit costs less than both Forms lines from 5 pages and less than Tables above 20 pages; a scan costs less from 9 pages (Forms, Tables and Queries), 10 pages (Forms and Tables) and above 40 pages (Tables).
Volume. At 100,000 invoices/month, 1-page invoices consume 1.2 million credits/year for digital PDFs or 2.4 million for scans. Both are far beyond the 15,000 credits on the Business plan, so a Volume quote applies. At this scale, per-page APIs like AnalyzeExpense, Azure’s prebuilt models, or Mistral OCR are better matched to 1-page invoice volumes.
Commitment structure. Our credits reset annually and do not roll over. Top-ups expire on the same reset date. The examples here use annual plan prices at full credit utilization; the effective cost rises when credits go unused.
Price your real document mix before deciding, taking into account pages per document, scanned or digital, and which fields you need. Per-page billing favors short documents at high volume; per-request billing favors long ones.
Every migration rewrites the same parts

The 6 rewrite points every migration hits, from input and async plumbing to output parsing, coordinates and confidence, auth, human review and Custom Queries adapters.
Input and async plumbing. Textract’s asynchronous APIs read from S3 and announce completion on an SNS topic, with results kept 7 days unless you set an output bucket. Most alternatives take an upload or a URL and expect you to poll or receive a webhook. Foxit uses task polling, Azure uses operation polling, Google batch reads from Cloud Storage, and BDA keeps S3. Review your S3 paths, completion notifications, and output handling for the destination API. BDA keeps S3, but its job workflow still needs to be integrated.
Output parsing. Code that walks Blocks and Relationships (KEY_VALUE_SET to its value and words, TABLE to CELL, QUERY to QUERY_RESULT) gets replaced entirely. Schema extractors return named fields. Layout parsers return element trees. The parsing logic is new code in every case.
Coordinates and confidence. Textract’s BoundingBox values are ratios of page size (0 to 1), and Confidence runs from 0 to 100. Reducto’s citation boxes use the same 0-1 convention. LlamaExtract’s primary tiers return x, y, width, and height with page dimensions. Foxit’s Structural Extraction returns an 8-number polygon with page size reported in points. Confidence scales differ too, with LlamaExtract using 0-1 and Reducto adding high or low labels, so re-tune your review thresholds after migration.
Auth. Hosted alternatives commonly use API keys or OAuth client credentials instead of IAM and SigV4. BDA retains AWS authentication. For a self-hosted deployment, configure authentication for the service you expose.
Human review. A2I is closed to new customers. Google deprecated Document AI’s human-in-the-loop on 16 Jan 2024. For any destination, budget for your own review queue driven by confidence scores.
Custom Queries adapters. Adapters (5 to 2,500 training documents, at most 10 per account) stay in AWS. Rebuild them as schemas, blueprints, or custom models depending on your destination. There’s no export path.
The safest migration approach is to run both pipelines on the same sample of documents and compare fields one by one before cutting over.
Mapping Textract calls to the Foxit PDF Services API
To see those rewrite points on a real destination, this section maps Textract calls to our own API, then runs an extraction on a sample invoice. The mapping is conceptual, since Textract output doesn’t carry over automatically.

A digital PDF takes 1 billable call; a scanned PDF adds the OCR call first, for 2 credits in total.
Amazon Textract | Foxit PDF Services API | What changes |
DetectDocumentText | Perform OCR on PDF, then PDF to Text or PDF Structural Extraction | OCR returns a searchable PDF; text and structure come from a second call (1 credit each) |
AnalyzeDocument with Tables | PDF Structural Extraction (Trial) table elements, or PDF to Excel | Tables come back as cell grids with row and column indexes, or as an XLSX file |
AnalyzeDocument with Layout | PDF Structural Extraction, or PDF to Markdown | One call returns 12 element types in reading order; filter them in your code |
AnalyzeDocument with Forms, on fillable PDFs | Export PDF Form Data | JSON keyed by form field names, with no OCR involved |
Forms on scanned pages, Queries, AnalyzeExpense | No direct equivalent | Map elements to your fields in code, as our invoice extraction tutorial shows |
Signatures, AnalyzeID, AnalyzeLending | No equivalent | Keep them on Textract or choose another API from this list |
S3 input and SNS notification | Upload, start the operation, poll the task | Polling, uploads and downloads use no credits |
Blocks with ratio geometry and 0-100 confidence | An elements array where text elements carry a page, an 8-number polygon and a score, and table elements carry them under regions and scores | Convert coordinates and re-tune thresholds |
IAM and SigV4 | client_id and client_secret request headers | No request signing; the same 2 headers authenticate every PDF Services call |
Billed per page at the selected feature-combination rate | 1 credit per request | Within supported limits; scanned PDFs take 2 calls |
Prerequisites
To try the flow on your own account, you need:
- A bash shell: bash ships with macOS and Linux; on Windows, use WSL
- curl: the command-line HTTP client that makes every API call
- jq: the JSON processor that reads the API responses
- unzip: UnZip, which opens the result ZIP
- A Foxit developer account: a free Foxit developer account, whose Developer plan includes 500 credits a year
Once you’re signed in, the Make your first call card on the console dashboard shows your client ID and client secret, with a copy button beside each.

The Make your first call card, where the copy buttons beside CLIENT ID and CLIENT SECRET give you the 2 values the script reads.
The same dashboard tracks how many of your yearly credits you’ve used.
Run this block to create a working folder, download our extraction script, the sample digital invoice, the image-only scan of the same invoice and the fillable form, and export your credentials:
mkdir textract-foxit && cd textract-foxit
B=https://github.com/lucienchemaly/foxit-demo-templates/raw/main/textract-alternatives
curl -LO $B/foxit_extract.sh -LO $B/invoice_table_test.pdf -LO $B/scanned_invoice.pdf -LO $B/fillable_test.pdf
chmod +x foxit_extract.sh
export FOXIT_CLIENT_ID="your_client_id"
export FOXIT_CLIENT_SECRET="your_client_secret" The code above creates a textract-foxit folder, downloads the script and the 3 sample PDFs into it from our demo repository, makes the script executable, and sets the 2 environment variables the script reads to authenticate every request.
Run this command from your terminal to extract the digital invoice:
./foxit_extract.sh structure invoice_table_test.pdf The expected output should look like the following:
uploaded invoice_table_test.pdf as 6aecea0a69750a7eaa41a4a1
started pdf-structural-extract (task 6aecea0becfabd07d2ee482d)
zip contents: page_p0.pdf_0.png StructureInfo.json
{"version":{"schema":"1.0.7","software":"FoxitPDFAnalyzer","model":"idp-analysis"}}
{"pages":[{"pageNumber":1,"state":"success","messages":null}]}
{"elementTypes":{"head":1,"paragraph":5,"table":1,"title":1}}
{"textChars":220}
{"firstParagraph":{"text":"Foxit DocGen API Sample Template","page":1,"boundingBox":[90,113,268,113,268,127,90,127],"score":0.8891659975051880}}
{"firstTable":{"rows":4,"columns":5,"scores":[0.9757168889045715],"image":"page_p0.pdf_0.png","firstCells":[{"rowIndex":0,"columnIndex":0,"text":"#"},{"rowIndex":0,"columnIndex":1,"text":"Description"},{"rowIndex":0,"columnIndex":2,"text":"Qty"}]}} Text elements carry an 8-number boundingBox in points and a score. Table elements leave region empty and carry their polygon under regions and their confidence under scores, and they come back as a row and column grid with a PNG crop of the table region. The script saves the full extraction to out/StructureInfo.json, the table crop to .out/page_p0.pdf_0.png and the original ZIP to result.zip, all in your working folder.

The table crop from the result ZIP holds only the line-item table region, not a render of the whole page.
The same script covers the other routes. Run this command from your terminal to extract the image-only scan of the same invoice, which runs OCR before extraction:
./foxit_extract.sh ocr-structure scanned_invoice.pdf The expected output should look like the following:
uploaded scanned_invoice.pdf as 6aecea16e5e7ff0dd225d2db
started analyze/pdf-ocr (task 6aecea17ecfabd07d2ee4ee6)
started pdf-structural-extract (task 6aecea1fecfabd07d2ee5341)
zip contents: page_p0.pdf_0.png StructureInfo.json
{"version":{"schema":"1.0.7","software":"FoxitPDFAnalyzer","model":"idp-analysis"}}
{"pages":[{"pageNumber":1,"state":"success","messages":null}]}
{"elementTypes":{"head":1,"paragraph":5,"table":1,"title":1}}
{"textChars":220}
{"firstParagraph":{"text":"Foxit DocGen API Sample Template","page":1,"boundingBox":[89,112,268,112,268,128,89,128],"score":0.8857628107070923}}
{"firstTable":{"rows":4,"columns":5,"scores":[0.9737526178359985],"image":"page_p0.pdf_0.png","firstCells":[{"rowIndex":0,"columnIndex":0,"text":"#"},{"rowIndex":0,"columnIndex":1,"text":"Description"},{"rowIndex":0,"columnIndex":2,"text":"Qty"}]}} The 2 started lines are the 2 billable calls, OCR then Structural Extraction, so this run costs 2 credits. The OCR result document becomes the extraction input, and the scan comes back with the same 220 text characters and the same table grid as the digital PDF, with slightly different coordinates and scores.
The script has 2 more modes. form-data returns a fillable form’s values as JSON keyed by the PDF’s own field names, with every value as a string, and excel converts the tables to an Excel workbook. Each costs 1 credit.
Common mistakes
Each of these failures came up while running the script above, and each one stops the run with a specific message.
- Missing exports in a new terminal: the environment variables only last for the shell session that set them, so a fresh terminal stops at the first check with
./foxit_extract.sh: line 8: FOXIT_CLIENT_ID: set FOXIT_CLIENT_IDto the client ID from your Foxit API console. Run the 2 export lines again in that terminal. - Wrong client ID or secret: a mistyped or swapped value fails on the first request, the upload, with HTTP 401 and
{"allow":false,"reason":"Invalid credentials or access token"}. Copy both values again from the Make your first call card. - No credits left: Check Credits Remaining before a batch run. The sample handles an upload response with “allow”:false and “Access denied or insufficient quota”. Our current credit reference documents HTTP 429 with QUOTA_EXCEEDED for exhausted processing credits, so handle the response returned by the endpoint you use. Restore credits through an upgrade, a purchased top-up, or the annual reset.
structureon an image-only scan: the task still completes, but the page comes back with"state":"fail"and the messageNo element tag or tag element less than 50%.Tag Failed!, with no elements and 0 text characters, and the call still costs a credit. Useocr-structurefor scanned PDFs so OCR adds a text layer before extraction.
Where your documents go after you upload them
Retention, training, and region terms can rule out an API before price does. The table summarizes the vendor terms reviewed; “not published” and “not stated” mean the relevant terms were not verified, not that no policy exists.
| API | Default retention | Training on your data | Private deployment |
| Amazon Textract (baseline) | Async results kept 7 days in a Textract-owned bucket unless you set your own output bucket | Inputs may be stored and used to improve AWS AI services, possibly in another region, unless you set an AI services opt-out policy | AWS PrivateLink and GovCloud; no on-premises option |
| Foxit PDF Services API | Delete endpoint available; retention period not published | Not used to train AI models unless you authorize it | Cloud only |
| Azure Document Intelligence | Inputs and results deleted 24 hours after analysis | Not published | Read and Layout containers (v4.0), including disconnected tiers; prebuilt model containers in v3.1 |
| Google Document AI | Online document data not persisted to disk; batch documents deleted after processing, 1-day failsafe TTL | Never | Google Cloud; VPC Service Controls and customer-managed keys, subject to processor-version support |
| Amazon Bedrock Data Automation | Async output goes to your S3; sync JSON can be inline or S3 | Not used to train Nova, Titan, or third-party models | AWS-managed with IAM and S3; cross-region inference is required |
| Mistral OCR | Zero data retention on /v1/ocr with approved paid access; batch files excluded | Free mode may train; free and pay-as-you-go users can opt out | Single-container self-hosting for enterprise |
| LlamaExtract | Files cached 48 hours unless do_not_cache is set | No, by default | Single-tenant, bring-your-own-cloud or self-hosted |
| Reducto | Default job results: about 12 hours; zero data retention from Growth purges API artifacts within 24 hours, except Studio jobs and persisted results | Never from Growth up; Standard not stated | Hybrid VPC or full VPC on Enterprise |
| Docling | Your infrastructure | Not applicable | Self-hosted, including air-gapped |
Textract’s opt-out. Use an AWS Organizations AI services opt-out policy if you need to prevent Textract content from being used or stored for service improvement. This does not prevent the processing or storage required to provide the service.
“Our documents cannot leave our cloud.” A requirement to process data in a particular region is different from a rule that documents must stay inside your own environment. Zero data retention and no training do not, by themselves, satisfy either requirement. Check where processing happens and who operates the infrastructure.
If documents must stay in your environment. Docling (MIT) runs fully self-hosted or air-gapped. Azure Document Intelligence v4.0 containers cover Read and Layout, including disconnected tiers; prebuilt model containers require v3.1.
Reducto’s full VPC keeps infrastructure in your environment, though the hybrid tier keeps storage local while processing runs on Reducto’s GPUs. LlamaExtract offers bring-your-own-cloud deployment (AWS, Azure, or GCP) and self-hosting for enterprise customers.
Mistral offers a single-container self-hosted option for enterprise customers. Amazon Bedrock Data Automation stays in your AWS account but requires cross-region inference profiles, which may move requests outside your primary region. Most private deployment options require enterprise contracts rather than self-serve plans.
For regulated documents, check retention, training, and deployment before accuracy, because those determine whether you can use the API at all. Price and accuracy comparisons are only relevant after that gate.
Which accuracy claims you can trust
Who ran the tests. Businessware Technologies, a software services firm, published an invoice accuracy test in January 2025 that covers Textract’s AnalyzeExpense, Azure’s invoice model and GPT-4o. LlamaIndex runs ParseBench (published April 2026), Reducto runs RD-TableBench (November 2024 results), and anyformat publishes its own Textract comparison, last updated 27 Jul 2026. In each vendor-run benchmark, the publisher wins, so vendor-run results are not independent validation. Businessware, LlamaIndex and Reducto don’t publish the Textract, Azure or Google model versions they tested, so a result may predate the current release.
How good is Amazon Textract? In Businessware’s January 2025 invoice test, AnalyzeExpense scored approximately 78% field accuracy and 82% on line items, behind Azure’s invoice model (93% field accuracy, 87% on line items) and GPT-4o with a separate OCR step (98% field accuracy).
AWS shipped a text-detection model update on 30 Jun 2025, after that test, and the Businessware page doesn’t state a sample size. Treat these dated results as context, not a definitive ranking: the report does not specify the sample size or tested model versions.
Is Google Document AI better than Amazon Textract for OCR? It depends on the job. Google reads more than 200 languages including handwriting against Textract’s 40-plus printed languages and English-only handwriting.
In Businessware’s January 2025 invoice test, Google scored 82% on fields but only 40% on line items, against Textract’s 78% and 82%. On LlamaIndex’s ParseBench, a LlamaIndex-run test from April 2026, Google’s Layout Parser scored 50.4 and Textract scored 47.9, with neither result a clear win across all document types.
Benchmark scores. On LlamaIndex’s ParseBench (April 2026, run by LlamaIndex), LlamaParse Agentic scored 84.9, Azure 59.6, Docling 50.6, Google Document AI Layout Parser 50.4 and Amazon Textract 47.9. On Reducto’s RD-TableBench (November 2024, run by Reducto), Azure scored 82.7%, Textract 80.9% and Google 64.6%.
Other vendor claims. On LlamaIndex’s ExtractBench (2 Sep 2026, run by LlamaIndex on 370 enterprise documents), LlamaExtract Agentic Plus scored 95.6% overall at 8.1 cents a page. anyformat’s 78.1% vs. 65.4% combined parse score against Textract comes from anyformat’s own 2026 benchmark.
The only reliable way to compare accuracy is to run 50-100 of your own documents through Textract and 2 shortlisted alternatives, then compare fields one by one against values you’ve checked by hand. Use your own mix (scans, multi-page tables, handwriting, your most common vendor invoice layouts) rather than published benchmarks alone.
How to choose an Amazon Textract alternative
Work through the decision in this order:
- Residency first. If documents can’t leave your environment, start with Docling, or with the private deployments from Azure (Read and Layout containers), Reducto, LlamaExtract and Mistral, which mostly need enterprise contracts.
- AWS or not. If you’re staying on AWS, check whether AnalyzeExpense covers what you now pay AnalyzeDocument for, then look at Amazon Bedrock Data Automation for schema-defined fields inside IAM and S3.
- Main reason for switching. Prebuilt invoice, receipt and ID models point to Azure Document Intelligence, non-English or handwritten documents to Google Document AI, per-page OCR cost at volume to Mistral OCR, field-level evidence to LlamaExtract, mixed packets to Reducto, and long PDFs billed per page to the Foxit PDF Services API.
- Price your document mix. Run your pages per document, scanned-to-digital ratio and required fields through each shortlisted pricing model, then test 50-100 of your own documents before cutting over.
Where Foxit fits
Our PDF Services API gives you 4 extraction routes. PDF Structural Extraction (Trial) returns typed JSON with 12 element types, bounding polygons and confidence scores, plus table cell grids. PDF to Excel converts the PDF, tables included, to an XLSX workbook. Export PDF Form Data reads interactive form field values from fillable PDFs and returns JSON keyed by field name. PDF to Markdown converts structured PDFs to Markdown for LLM pipelines.
Teams running contract extraction or invoice parsing alongside other document operations can use the same Foxit account and credit pool. The billing unit still depends on the service: PDF Services processing calls cost 1 credit each, while eSign uses 5 credits per envelope.
Per-request pricing favors long documents. A 50-page digital statement costs 1 credit, where Textract Tables bills all 50 pages. The same model works against short documents, so teams that mainly process 1-page invoices at volume get a better rate from a per-page API such as AnalyzeExpense. Where there’s no prebuilt model, our structured JSON tutorial shows how to map extracted elements to your own fields.
For prebuilt invoice or ID fields, Azure Document Intelligence and Google Document AI are the better fit. For an in-depth feature comparison with Google Document AI, see How Foxit compares to Google Document AI for document data extraction.
Our free Developer plan gives you 500 credits a year, enough for up to 500 extraction requests on digital PDFs, or 250 on scans. That’s room to price and test your own document mix, the step every section above comes back to, before you commit to a paid plan.
Create a free Foxit developer account and turn your first PDF into structured JSON with the PDF Structural Extraction API.
What else to know before you replace Amazon Textract
The answers below cover Rekognition, free and open-source options, and LLM-based extraction.
What are the key differences between Rekognition and Textract?
Amazon Rekognition‘s DetectText finds up to 100 words in an image or video frame, designed for signs, labels, and captions in scene images. Textract reads documents, including multi-page PDFs and TIFFs up to 3,000 pages asynchronously, and returns forms, tables, queries, layout, signatures, invoices, receipts, and IDs. For document data extraction, Rekognition addresses a different problem entirely.
Is there a free or open-source alternative to Amazon Textract?
Docling (MIT) and PaddleOCR (Apache-2.0, v3.7.0, with PaddleOCR-VL) run on your own hardware with no per-page software fee. MinerU and Marker are other open-source options; check model licenses before commercial use, because some open OCR models require a commercial license above certain revenue thresholds.
For hosted options with free allowances, LlamaExtract gives you 10,000 free credits a month on pay-as-you-go (about 1,250 Cost-effective pages). Azure Document Intelligence offers 500 pages/month on the F0 tier, with a 2-page-per-document limit. Google Document AI gives you the first 1,000 Enterprise Document OCR pages free. Reducto’s Standard plan includes $150 in free usage. Our Developer plan gives you 500 credits/year. Textract has a 3-month free tier for new AWS customers; eligibility depends on the current AWS Free Tier program.
Can an LLM replace Amazon Textract?
For field extraction, often yes, with trade-offs. In Businessware’s January 2025 invoice test, GPT-4o with a separate OCR step reached 98% field accuracy, ahead of AnalyzeExpense’s 78%, though the test doesn’t provide a reliable latency comparison. Amazon Bedrock Data Automation, LlamaExtract, Reducto, and Mistral’s annotations all package an OCR-plus-model pattern behind one API call. Per-field confidence and citation support vary by service. Mistral documents OCR confidence but not annotation confidence, LlamaExtract’s primary tiers return 0-1 confidence per field, and Reducto returns high or low labels plus numeric confidence. The main practical trade-off is that LLM-based approaches add latency and a schema-design step that Textract’s prebuilt models skip.
10 Best Document Parsing APIs for Developers in 2026

Document parsing APIs differ in what they return, how they bill, and where your files go. This guide compares 10 options, including Foxit, LlamaParse, Reducto, Azure, and Docling, on outputs, OCR, pricing, and deployment. Use it to shortlist the right document extraction API and test it on your hardest pages.
A parser that handles clean digital PDFs may struggle with a scanned lease, a 2-column report, or a table that spans several pages. Misread reading order and missing table cells can leave garbled RAG chunks, incorrect invoice totals, or missing contract parties.
“Document parsing” covers 3 distinct jobs that most roundups treat as one.
- Layout parsing returns document structure as Markdown or JSON, including headings, tables, reading order, and often bounding boxes.
- Field extraction returns named values against a schema or prebuilt model, the invoice_total or party_name your pipeline actually needs.
- OCR turns images of text into selectable text so the other 2 jobs can run. Most APIs are built around one of these jobs and bill each differently.
Pricing units alone make comparison hard. On Amazon Textract, the same page costs $1.50 per 1,000 pages for plain text detection and $70 per 1,000 pages when you add Forms, Tables, and Queries together.
LlamaParse bills credits per page by tier, Reducto bills per product per 1,000 pages, and the Foxit PDF Services API bills 1 credit per request regardless of page count.
In this article, we compare 10 document parsing APIs based on their features, pricing, usage limits, and deployment options.
Our top picks by use case
The best document parsing API depends on whether you need layout structure, named fields, or OCR, and where your documents can be processed. These picks match common developer workflows to the APIs that support them.
All prices and availability are current as of 16 Oct 2026.
Use case | Pick | Why it fits |
Structure-aware JSON inside a wider PDF workflow | Structural Extraction (Trial) returns 8 confirmed element types with bounding boxes and table cell grids at 1 credit per request, with PDF to Markdown and OCR on the same account | |
RAG ingestion with tiered cost and quality | LlamaParse | 4 parse tiers from 1 to 45 credits per page at $1.25 per 1,000 credits; 10,000 free credits a month |
Parse, extract and split behind one API, with VPC options | Reducto | r-1 parsing at $10 per 1,000 pages (preview), Extract at $20 including parsing, with hybrid and full VPC deployments |
Field extraction you can trace back to the page | DPT-3 models with line- or word-level grounding and a Ground API that costs no credits | |
High-volume OCR to Markdown at one flat page price | OCR 4.1 at $4 per 1,000 pages, or $0.40 with the Batch API, with blocks, bounding boxes and confidence included | |
Prebuilt models for invoices, IDs and tax forms | Layout and prebuilt models at $10 per 1,000 pages, with invoice, receipt, ID, bank statement, tax and mortgage models, plus containers | |
Layout-aware chunking on Google Cloud | Layout Parser at $10 per 1,000 pages including chunking, with Gemini-based versions in preview | |
Paying per feature inside AWS | Amazon Textract | Text at $1.50 per 1,000 pages, Tables $15, Forms $50, and natural-language Queries |
PDF extraction for teams already on Adobe PDF Services | Element tree with fonts and reading order, tables as CSV and XLSX, and 500 free Document Transactions a month | |
Self-hosted, open-source parsing | MIT-licensed, runs locally or air-gapped, with Docling Serve REST API. v2.140.0 released 16 Oct 2026 |
Each API appears once, under the use case it fits best. Several handle more than 1 job, and the feature table in each entry shows their coverage.
The Foxit Developer plan includes 500 credits a year, enough to run Structural Extraction on a sample of your hardest pages. Create a free developer account to start.
How we compared these document parsing APIs
We reviewed public documentation, pricing pages, official price feeds, model cards, and GitHub repositories as of October 16, 2026.
Each API uses the same 8 comparison rows: outputs, scanned pages and OCR, tables and layout, field extraction, pricing, free allowance, limits, and deployment and data. Prices identify the billing unit and relevant tier or mode. Security and compliance statements remain vendor claims.
The picks reflect use-case fit, not an overall ranking. Benchmark results appear separately, with their publisher, product version, and date.
The 10 document parsing APIs in detail
Foxit PDF Services API
Our PDF Services API covers cloud-based PDF extraction, conversion, OCR, redaction, and compression. The extraction endpoints covered here are PDF Structural Extraction (Trial) and PDF to Markdown.
Key features at a glance
Feature | Details |
Outputs | PDF Structural Extraction (Trial) returns a ZIP with StructureInfo.json (schema v1.0.7), extracted images, and table renditions. Also: PDF to Markdown (tables as Markdown pipes or HTML), PDF to Excel, PDF to HTML, PDF to text, and image, text, or page extraction on sibling endpoints |
Scanned pages and OCR | Our dedicated OCR endpoint makes scanned PDFs searchable and supports around 38 language codes, including Simplified and Traditional Chinese, Japanese, Korean, Thai, and 30+ European languages and variants. Our Structural Extraction documentation does not separately state an OCR language count |
Tables and layout | In v1.0.7, our MCP server’s extraction schema defines 8 element types: title, head, paragraph, table, image, form, hyperlink, and formula. The output includes reading order and bounding boxes. Tables return as cell grids with row and column relationships |
Field extraction | No schema-based extraction or prebuilt invoice models. Map elements to your fields in code, as the invoice parsing and contract metadata tutorials show |
Pricing | 1 credit per successful request, regardless of page count or file size within supported limits. Startup $1,750 a year (5,000 credits), Business $4,500 a year (15,000 credits). Credits reset yearly with no rollover |
Free allowance | 500 credits a year on the Developer plan |
Limits | 100 MB upload. Per application: 15 requests a minute in sandbox, 100 in production. Asynchronous workflow: submit, poll the task, then download the ZIP. Polling, uploads, and downloads use no credits. A page limit per request is not published as of 16 Oct 2026 |
Deployment and data | Cloud only, through one global API gateway. A delete endpoint removes uploaded and generated files. Our cloud-hosted PDF APIs are covered by SOC 2 Type II audits, and we support HIPAA BAAs. pdf_structural_analysis, pdf_extract, and pdf_ocr tools ship in the Foxit MCP Server |
Where Foxit PDF Services API stands out
Per-request billing charges the same 1 credit for a 200-page report as a 1-page receipt, within supported limits. The cost advantage depends on document length and how much of your annual credit pool you use.
These extraction endpoints share an account and credit pool with our other document services, including OCR, conversion, redaction, and eSign. If your workflow already uses those services, you can add extraction without a separate vendor integration.
Our MCP server exposes structural extraction tools, so AI agents can call the API through the same interface as other PDF operations.
What to consider
Our PDF Structural Extraction API is currently in trial and uses schema version v1.0.7. The API may change, so validate responses against the schema your application expects.
The API has no schema-based field extraction and no prebuilt invoice or contract models. You receive a typed element tree and map fields yourself, which the invoice parsing tutorial and contract metadata tutorial walk through. Teams that need named fields returned directly from the API should evaluate LandingAI, Reducto Extract, or Azure prebuilt models alongside this.
Paid credits expire at year-end without rollover. Forecast annual usage before choosing a plan.
Best for
Pipelines that already convert, OCR, redact, or sign PDFs and need structure-aware JSON or Markdown from the same account, particularly on long documents where per-request billing is favorable.
Getting started
Create a free Foxit developer account, set up a sandbox application, and send your first PDF to the Structural Extraction endpoint. The Developer plan includes 500 credits a year with no credit card required.

Our API plans and included credits.

Sandbox and production request limits for our APIs.
LlamaParse
LlamaParse is the document parsing service from LlamaIndex, the company that also publishes the ParseBench benchmark.
It accepts 130+ file types, returns Markdown or JSON, and offers 4 parse tiers that let you route documents by cost and quality.
Key features at a glance
Feature | Details |
Outputs | Markdown, plain text, per-page JSON, XLSX and HTML tables, and layout bounding boxes as an add-on (+3 credits a page), plus schema-based JSON with citations and confidence through LlamaExtract |
Scanned pages and OCR | OCR in 80+ languages (vendor claim) across 130+ file types, including images, Office files, HTML, spreadsheets, and audio |
Tables and layout | Layout-aware table extraction that preserves cell structure, plus charts and diagrams, and enriched forms output in beta (+10 credits per page with a form) |
Field extraction | LlamaExtract with JSON schemas: Cost-effective 8, Agentic 25, Agentic Plus 60 credits a page including parsing; Turbo 35 |
Pricing | $1.25 per 1,000 credits. Parse tiers: Fast 1, Cost-effective 3, Agentic 10, Agentic Plus 45 credits a page (approximately $1.25, $3.75, $12.50, and $56.25 per 1,000 pages). Starter $50 a month (40,000 credits), Pro $500 a month (400,000 credits) |
Free allowance | 10,000 credits a month |
Limits | Parse accepts 512 MB per file. Extract caps at 100 MB and 500 pages per job. Concurrent jobs: 5 on Free and Starter, 20 on Pro, 100 on Enterprise. Text beyond 64 KB per page is dropped |
Deployment and data | SaaS in the US (us-east-1) or EU (eu-central-1), with single-tenant, bring-your-own-cloud and self-hosted options for enterprise. Files cached 48 hours unless you opt out per request. No training on customer data by default. Claims SOC 2 Type II; HIPAA BAA for Enterprise |
Where LlamaParse stands out
Fast costs $1.25 per 1,000 pages, compared with $56.25 per 1,000 for Agentic Plus. Routing simple scanned pages to Fast and complex layouts to Agentic Plus can substantially cut costs in mixed-document pipelines.
Date-pinned tier versions keep the output format reproducible when you rerun the same job weeks later, supporting reliable regression testing on parser output.
LlamaExtract adds JSON schema-based field extraction on top of parsing, with citations and confidence scores, at no separate integration. The same credential covers both.
What to consider
Concurrency caps are a real constraint on lower plans. One practitioner in the r/RAG community thread (June 1, 2026) reported throttling at 5 to 10 concurrent jobs, which can stall batch pipelines during peak ingestion. The 500-page Extract cap is also worth checking against your largest documents before committing.
LlamaParse’s own API reference confirms the Fast tier skips OCR on images and skips table and heading reconstruction, so its output is closer to spatially-laid-out raw text than the fully reconstructed Markdown the Balanced and Premium tiers produce. The HIPAA BAA scope is Enterprise only, so teams with PHI must confirm the plan level before sending protected documents.
The 48-hour file cache means documents persist by default unless you explicitly opt out per request, which is worth reviewing against your data policy.
Best for
RAG ingestion where you want to trade cost against quality on a per-document basis.
Getting started
Create an account at llamaindex.ai and start with the 10,000 free monthly credits.

LlamaParse plans, pricing, and included credits.
Reducto
Reducto offers parsing, extraction, splitting, classification, and a document-editing endpoint behind one API. Its r-1 model is its newest parsing tier, currently in preview.
Pricing moved to a per-product structure on 1 Sep 2026, replacing the previous credit-based model.
Key features at a glance
Feature | Details |
Outputs | Blocks with bounding boxes, whole-document Markdown, embedding-ready table summaries. Extract returns JSON with citations. Split, Classify, and Edit endpoints also available |
Scanned pages and OCR | r-1 handles scans and handwriting (vendor claim), with 30+ file types and a multilingual guide covering 60+ languages |
Tables and layout | Merged cells and nested headers on r-1, with dynamic table output (Markdown for simple tables, HTML for complex ones) |
Field extraction | Extract $20 per 1,000 pages including parsing, Deep Extract $40. Extractions over 100 fields per page may incur a per-field surcharge |
Pricing | Per 1,000 pages: r-1 Parse $10 (preview, opt-in on the API), legacy Parse $15 standard and $30 complex (2x for agentic modes). Citations add $2, custom regions $5. Parse and Extract batch jobs 20% off, Deep Extract excluded. Contracted customers keep credit-based pricing until renewal |
Free allowance | $150 of usage on the Standard plan, equivalent to 15,000 credits at the standard $10-per-1,000-page r-1 Parse rate |
Limits | 100 MB direct upload (5 GB with presigned upload). No page limit on Standard. Synchronous calls time out near 15 minutes. 1,000 requests a second per key. 200 guaranteed concurrent pages on Standard |
Deployment and data | SaaS, hybrid VPC (your storage, Reducto compute), or full VPC on Enterprise. Results available approximately 12 hours. Growth and Enterprise API artifacts expire within 24 hours under ZDR policy, except Studio jobs and persist_results results. Claims SOC 2 Type II on every tier. Never trains from Growth up; Standard training policy not stated |
Where Reducto stands out
Teams can consolidate these document operations under one API and authentication credential rather than chaining vendors. The Edit endpoint also supports document filling.
Hybrid VPC deployments let you keep documents in your own storage while Reducto handles compute. That arrangement splits the data-custody question in a way that SaaS-only providers can’t match without a full VPC agreement.
r-1 returns Markdown for simple tables and HTML for complex merged-cell tables, so your downstream parser can handle each format appropriately.
What to consider
The r-1 tier is preview and opt-in via the API, meaning its behavior may change before general availability. Pricing changed 6 weeks before the check date, so re-verify rates before signing a volume commitment. The Standard plan’s training data policy is not explicitly stated, so teams with sensitive documents should ask before sending production data.
The Standard plan’s free allowance is $150 of usage, worth 15,000 credits at the standard $10-per-1,000-page r-1 Parse rate.
Best for
Teams that need parsing, extraction, and splitting in one place with a path to a private deployment.
Getting started
Sign up at reducto.ai and start with the Standard plan’s free usage.

Reducto’s Standard, Growth, and Enterprise plans.
LandingAI Agentic Document Extraction
LandingAI Agentic Document Extraction (ADE) made its v2 APIs generally available on 24 Jul 2026. Its DPT-3 model family returns extracted values linked to their exact location in the source document, which lets downstream processes verify or review what the model read.
Key features at a glance
Feature | Details |
Outputs | Reading-order Markdown and hierarchical JSON (pages, blocks, table cells) with block bounding boxes, line-level grounding on DPT-3 Pro, and word-level grounding and word confidence on DPT-3 Verity (preview) |
Scanned pages and OCR | DPT-3 Pro handles scans, handwriting, and non-Latin scripts. Verity is Latin-only and does not handle scans. 11 languages listed as strong |
Tables and layout | Tables, forms, checkboxes, and figure descriptions. Spreadsheet cells grounded by Excel address |
Field extraction | Extract API with JSON Schema and a schema builder. The Ground API links extracted fields to page bounding boxes and costs no credits, but is unavailable with zero data retention (ZDR) enabled |
Pricing | $0.01 per credit. DPT-3 Pro priority: 1 credit per page plus 0.5 credits per 1,000 output characters. Async standard tier costs half. LandingAI quotes a 1.5-credit median for a typical business document on standard. Team plans start at $250 a month |
Free allowance | 1,000 credits on Explore, expiring 90 days after sign-up |
Limits | Synchronous: 50 MiB, 100 pages a minute on Explore, 475-second timeout. Async jobs: PDFs up to 1 GiB and 6,000 pages on standard, with priority capped by rate limit. Both have a 6-hour timeout |
Deployment and data | US (us-east-2) and EU (eu-west-1), with VPC and on-premises for Enterprise and optional ZDR on Team and Enterprise. Claims SOC 2 Type II, GDPR, and HIPAA with a BAA |
Where LandingAI Agentic Document Extraction stands out
Grounding is the defining feature. DPT-3 Pro links every extracted value to the line that contains it, and DPT-3 Verity links to the word. The Ground API then lets you query those positions without spending additional credits, so your review UI or audit log can show exactly where in the document each field value came from.
Each table cell has a bounding box, so reviewers can highlight a tax line on a complex form rather than inspect a bare string. This helps regulated workflows where someone must sign off on what the model read.
What to consider
Per-page cost moves with output character count, so dense documents with a lot of extracted text cost more than the per-page headline rate suggests. LandingAI quotes a 1.5-credit median for typical business documents on standard, but your actual distribution will depend on document type.
Free credits expire after 90 days from sign-up, not at month end, so plan your evaluation window accordingly. DPT-3 Verity is still in preview and limited to Latin scripts without scan support, so don’t route scanned or non-Latin documents to it.
Enabling ZDR disables the Ground API, which means you must choose between the strongest data-residency guarantee and the traceability feature. That tradeoff is worth understanding before choosing a plan.
Best for
Regulated extraction where each field value must be traceable to its location in the source document.
Getting started
Sign up at landing.ai and start with the 1,000 Explore credits (90-day expiry).

LandingAI’s free Explore tier and credit-based pricing.
Mistral OCR
Mistral OCR is Mistral’s document-to-Markdown service, now at model version OCR 4.1 (released 16 Jul 2026).
It bills one flat price per page and cuts that price by 90% for batch jobs, with confidence scores and bounding boxes included in both modes.
Key features at a glance
Feature | Details |
Outputs | Per-page Markdown, image bounding boxes, and blocks in reading order with labels (text, title, table, equation, signature, others). Confidence at page, block, or word level. Tables inline or as separate Markdown or HTML |
Scanned pages and OCR | OCR on images and PDF, DOCX, PPTX, and more, with 42 languages officially supported for OCR |
Tables and layout | table_format options, with header and footer extraction |
Field extraction | Document AI annotations with your JSON schema. A separate per-annotated-page price is not published alongside the OCR rates as of 16 Oct 2026 |
Pricing | OCR 4.1 (released 16 Jul 2026): $4 per 1,000 pages synchronous, $0.40 per 1,000 pages with the Batch API |
Free allowance | Free-mode usage limits shown on the account’s Limits page. Mistral’s free mode may use inputs and outputs for training unless you opt out |
Limits | 50 MB and 1,000 pages per document. OCR 4 is not intended for real-time, latency-sensitive processing |
Deployment and data | Hosted API, plus Amazon SageMaker and Microsoft Foundry, and single-container self-hosting for enterprise customers. Zero data retention on /v1/ocr requires approved pay-as-you-go access, with Files API and batch files excluded. ISO 27001, ISO 27701, and SOC 2 Type II listed on the trust center |
Where Mistral OCR stands out
A single flat page price already includes blocks, bounding boxes, confidence scores, and reading-order labels. Most providers charge separately for bounding boxes or confidence, so the all-in-one pricing simplifies budget math for large batch jobs.
For pipelines that can wait for asynchronous results, the Batch API’s 90% discount brings the price to $0.40 per 1,000 pages, making it one of this list’s cheapest options for converting archives to Markdown.
What to consider
OCR 4 is not intended for low-latency, real-time processing. If your pipeline needs synchronous sub-second responses on individual documents, test latency at your volume before committing.
Model versions retire quickly. OCR 4.0 was retired on 30 Sep 2026, less than 3 months after release. Pin your API calls to a specific model version and monitor Mistral’s release notes so you’re not caught by an automatic cutover. Published scores in the OCR 4 announcement are Mistral’s own reproductions of competitor benchmarks, not independent measurements.
Mistral officially supports 42 languages for OCR. Test on your target languages before committing.
Best for
Large batch conversions of documents to Markdown for RAG at a flat per-page price.
Getting started
Sign up at mistral.ai and generate an API key.

Mistral’s general pricing page. OCR rates are listed separately in its API pricing documentation.
Azure Document Intelligence
Azure Document Intelligence (previously Form Recognizer, then Azure AI Document Intelligence) is Microsoft’s cloud extraction service, now available as Azure Document Intelligence in Foundry Tools (API v4.0, 2024-11-30).
It covers layout parsing, a broad catalog of prebuilt models, custom training, and container deployments for environments that cannot call a cloud API.
Key features at a glance
Feature | Details |
Outputs | JSON with paragraphs and roles, lines and words with confidence and polygons, selection marks, tables with row and column spans, figures and sections. Layout can return Markdown with HTML tables for merged cells |
Scanned pages and OCR | Read and Layout OCR printed text in a long language list, with handwriting on a shorter list. Add-ons for high resolution, formulas, fonts, barcodes, and searchable PDF output |
Tables and layout | Spans and header flags. For tables that run across pages, Microsoft advises splitting the PDF and stitching the results in post-processing |
Field extraction | Prebuilt invoice, receipt, ID, bank statement, check, pay stub, contract, US tax, and mortgage models, plus custom neural and template models and query fields as an add-on |
Pricing | East US pay-as-you-go, per 1,000 pages: Read $1.50 (then $0.60 above 1 million), Layout and prebuilt models $10, custom extraction $30, add-ons $6, query fields $10. Batch costs the same as standard. Commitment tiers start at $190 a month for 20,000 prebuilt pages |
Free allowance | 500 pages a month on the F0 tier, which analyzes only the first 2 pages of each document (4 MB cap) |
Limits | S0: 500 MB and 2,000 pages per analysis; 15 analyze requests a second by default (adjustable); asynchronous submit and poll |
Deployment and data | Azure regions plus Read and Layout containers, including disconnected tiers. Inputs and results deleted 24 hours after analysis completes. SDKs for .NET, Python, Java, and JavaScript |
Where Azure Document Intelligence stands out
Azure’s prebuilt model catalog is among the broadest on this list. Its dedicated models already map named fields, so you don’t have to write field-extraction logic for the standard document types listed above.
Container deployments let you run Read and Layout processing inside your own infrastructure without sending documents to Azure endpoints. Disconnected containers extend that to air-gapped environments, though availability varies by model and API version.
Volume commitment tiers reduce per-page costs substantially for high-volume workloads. The $190/month tier covers 20,000 prebuilt pages at $9.50 per 1,000 pages rather than the list price.
What to consider
The F0 free tier analyzes only the first 2 pages of each document, which means a 30-page invoice only returns extraction on pages 1 and 2. Testing during evaluation must account for this limit, or you’ll get misleading accuracy results.
For multi-page tables, budget development time to stitch the extracted sections together during post-processing.
Azure Content Understanding (GA with API version 2025-11-01) is a newer generative extraction layer on the same cloud that’s worth evaluating alongside Document Intelligence for use cases that benefit from generative models.
Best for
Invoices, receipts, IDs, and tax forms on Azure infrastructure, with an option for container or disconnected deployments.
Getting started
Sign up at portal.azure.com and create a Document Intelligence resource. The F0 tier gives 500 free pages a month.

Azure Document Intelligence pricing and its F0 free tier.
Google Document AI
Google Document AI is Google Cloud’s document processing platform, covering OCR, layout parsing with chunking, form parsing, and specialized prebuilt parsers. The Layout Parser’s built-in chunking feature makes it a direct fit for RAG pipelines on Google Cloud.
Key features at a glance
Feature | Details |
Outputs | Document objects with blocks, paragraphs, and tokens. Layout Parser builds a layout tree and context-aware chunks that carry their parent headings. Image and table annotations are GA (27 May 2026) |
Scanned pages and OCR | Enterprise Document OCR reads printed and handwritten text in more than 200 languages (Google claim), with checkbox and math OCR add-ons |
Tables and layout | Layout Parser detects tables, headings, page headers and footers. Google notes that PDF tables spanning pages “might be split in two tables” |
Field extraction | Form Parser (key-value pairs and checkboxes), Custom Extractor (generative or trained), and Invoice, Expense, Bank Statement, Pay Slip, and ID parsers |
Pricing | Per 1,000 pages: OCR $1.50 after the first 1,000, Layout Parser $10 including chunking, Form Parser and Custom Extractor $30 (then $20 above 1 million), Invoice and Expense parsers $0.10 per document up to 10 pages |
Free allowance | First 1,000 Enterprise Document OCR pages are free |
Limits | Online requests take up to 15 pages for most processors, or 30 in supported imageless mode. Batch jobs typically finish in 12 to 24 hours after starting, excluding queue time |
Deployment and data | US and EU multi-regions, with VPC Service Controls and customer-managed keys. Google states it never trains Document AI models on customer data. FedRAMP High and HIPAA listed |
Where Google Document AI stands out
Layout Parser includes context-aware chunks with parent-heading metadata at $10 per 1,000 pages, removing a separate chunking step from a standard RAG pipeline on Google Cloud.
Image and table annotations became generally available on 27 May 2026, so the Layout Parser now returns visual assets alongside text structure in one pass.
What to consider
As of 16 Oct 2026, every Gemini-based Layout Parser version is in preview; only v1.0 from 2024 is stable. Most processors cap standard online requests at 15 pages, or 30 in supported imageless mode. Documents above those limits require batch processing, which typically takes 12 to 24 hours, excluding queue time.
Multi-page tables may be split across 2 table objects, requiring post-processing stitching similar to Azure Document Intelligence. The per-document pricing on Invoice and Expense parsers ($0.10 per document up to 10 pages) is competitive for short invoices but doesn’t scale linearly beyond 10 pages.
Best for
RAG pipelines already running on Google Cloud that want layout-aware chunking included at the page price.
Getting started
Enable Document AI in your Google Cloud project at cloud.google.com/document-ai.

Per-page pricing for Google Document AI processors.
Amazon Textract
Amazon Textract charges per feature rather than per page tier, so you pay for Tables only if you call Tables, and Queries only if you call Queries.
That pay-per-feature structure makes it flexible for pipelines that need different capabilities from different document types.
Key features at a glance
Feature | Details |
Outputs | JSON blocks (words, lines, tables, key-value pairs, layout elements, signatures) with confidence scores and bounding boxes. Markdown output not stated on pages checked 16 Oct 2026 |
Scanned pages and OCR | Printed text in English, French, German, Italian, Portuguese, and Spanish, with handwriting in English only |
Tables and layout | Tables and Layout features. Table extraction works best with visually separated, upright tables |
Field extraction | Forms (key-value pairs), Queries in natural language (English only), Custom Queries with adapters, and prebuilt Expense, ID (US passports and driver’s licenses), and Lending APIs |
Pricing | US East, first 1 million pages a month: text $1.50 per 1,000 pages, Tables $15, Forms $50, Queries $15, Layout $6.50 (then $4 after 1 million pages), Forms plus Tables plus Queries $70. Expense $10. ID $25 for first 100,000 pages, then $10 |
Free allowance | 3 months for new AWS customers: 1,000 pages a month of text detection and 100 pages a month for Forms, Tables, and Layout |
Limits | Synchronous calls take 1-page PDFs up to 10 MB. Asynchronous jobs take up to 500 MB and 3,000 pages from S3. TPS quotas per API, adjustable |
Deployment and data | Most AWS regions including GovCloud, with PrivateLink. AWS may use inputs to improve its services unless you opt out with an AWS Organizations policy. HIPAA eligible, and covered by PCI, ISO, and SOC programs |
Where Amazon Textract stands out
Text-only pipelines pay $1.50 per 1,000 pages without bundling unused field or table extraction. For one-off or low-volume extraction, Queries retrieve specific values using questions such as “What is the total due?” without a full extraction schema.
GovCloud availability and PrivateLink support make Textract an option for US government workloads and VPC-isolated architectures that other providers on this list can’t reach.
What to consider
6 supported OCR languages with English-only handwriting and English-only Queries is a hard constraint. If your document set includes French invoices with handwritten annotations, Textract won’t serve that use case.
Synchronous API calls accept only single-page PDFs up to 10 MB, so multi-page documents must go asynchronous through S3.
The data-use opt-out requires an AWS Organizations policy, not an individual account setting. If your organization doesn’t have that policy in place, AWS may use your documents to improve its services by default.
For generative extraction, also evaluate Amazon Bedrock Data Automation, AWS’s newer document layer. It costs $0.01 per page standard and $0.04 per page for custom models.
Best for
English-language forms and tables already stored in S3, where you want to pay only for the specific features your pipeline calls.
Getting started
Enable Textract in your AWS account at aws.amazon.com/textract. The 3-month free tier includes 1,000 text pages a month.

Amazon Textract’s 3-month free tier allowances.

Amazon Textract pricing by feature and feature combination.
Adobe PDF Extract API
Adobe PDF Extract API is part of Adobe PDF Services. It returns a detailed element tree from native PDFs, including font data, reading order, and tables as CSV and XLSX, in a single ZIP output.
Key features at a glance
Feature | Details |
Outputs | A ZIP with structuredData.json containing an ISO-style element path (headings, paragraphs, lists, tables, figures, footnotes) with bounds, fonts, and reading order, plus tables as CSV, XLSX, and PNG, and a PDF to Markdown endpoint for LLMs. Page headers and footers are excluded |
Scanned pages and OCR | Native or scanned PDFs; quality drops below 200 DPI. Optimized for English, with other Latin-script languages expected to work |
Tables and layout | Cells spanning rows or columns are identified |
Field extraction | No key-value pairs, checkboxes, schemas, or prebuilt models |
Pricing | 1 Document Transaction per 5 pages. Paid plans by sales quote only |
Free allowance | 500 Document Transactions a month across Adobe PDF Services, covering up to 2,500 Extract pages. That figure assumes every transaction covers exactly 5 Extract pages and no other PDF Services operations |
Limits | 100 MB; up to 400 pages (150 if scanned, lower for table-heavy files); 25 requests a minute on the free tier, 100 on enterprise |
Deployment and data | Hosted only; SDKs for Java, .NET, Node.js, and Python. US and Europe processing regions, with uploaded and generated assets stored 24 hours by default and early deletion available. Compliance scope and training use not verified as of 16 Oct 2026 |
Where Adobe PDF Extract API stands out
Font metadata alongside structural elements is uncommon in this category. If your pipeline needs to distinguish between a heading that is bold because of its font weight and one styled that way by position alone, the element tree carries that information. Tables export as CSV and XLSX in the same ZIP as the JSON, which removes a conversion step for pipelines that feed spreadsheet data into downstream systems.
The PDF to Markdown endpoint gives LLM-oriented pipelines a direct path from native PDF to LLM-ready text without a separate conversion step.
What to consider
The 400-page limit (150 for scanned files) is a hard ceiling per request, and table-heavy documents may hit a lower effective limit.
Paid plan pricing is by sales quote only, so you can’t estimate costs from a public page before speaking with Adobe. Compliance scope and training use were not verified as of 16 Oct 2026, so confirm those terms directly with Adobe before sending sensitive documents.
If you need named fields returned directly, evaluate LandingAI, Reducto Extract, or Azure prebuilt models alongside Adobe.
Best for
Teams already licensing Adobe PDF Services who need font-aware structure and table exports from native digital PDFs.
Getting started
Sign up at developer.adobe.com and start with the 500 free Document Transactions a month.
Docling
Docling is an MIT-licensed open-source document parsing library from IBM Research. It runs locally or in air-gapped environments via Docling Serve, a REST API available in CPU and CUDA containers. v2.140.0 was released on 16 Oct 2026.
Key features at a glance
Feature | Details |
Outputs | Markdown, JSON, and a DoclingDocument object with layout elements, reading order, and table structure |
Scanned pages and OCR | Pluggable OCR backends (EasyOCR, Tesseract, RapidOCR, and others) |
Tables and layout | TableFormer model for table structure recognition, with row and column detection |
Field extraction | DocumentExtractor with a schema |
Pricing | None; your compute only |
Free allowance | Unlimited under the MIT license |
Limits | Determined by your hardware |
Deployment and data | Self-hosted; CPU and CUDA containers for Docling Serve. Data never leaves your infrastructure |
Where Docling stands out
The MIT license means there are no per-page costs, no API keys, and no data leaving your infrastructure. For teams processing sensitive documents in air-gapped environments, or for high-volume pipelines where per-page costs compound quickly, self-hosting eliminates the billing variable entirely.
Docling Serve exposes the library as a REST API in Docker containers, so you can drop it into an existing microservices architecture without rewriting your integration layer.
What to consider
Self-hosting puts you in charge of scaling, uptime, and model updates. OCR quality depends on which backend you configure, and none of the pluggable backends match the accuracy of cloud OCR services on difficult scans. The DocumentExtractor schema-based extraction is less mature than the field extraction offerings from LandingAI, Reducto, or Azure.
Datalab’s Marker and Chandra publish Apache 2.0 code, but the model weights require a commercial license for organizations above $5M in revenue or $2M in funding, so factor that into your evaluation if you’re above those thresholds.
Best for
Air-gapped deployments, high-volume pipelines where per-page costs are prohibitive, and teams that need full data custody.
Getting started
Install via pip (pip install docling) or pull the Docling Serve container from the IBM Research GitHub repository.
What to compare before choosing a document parsing API
Pricing units are the first thing that makes these 10 hard to compare side by side, so the breakdown below starts there.
Per page, per credit or per request
All prices are from vendor pricing pages, checked 16 Oct 2026.
API | Billing unit | Example list price | Free allowance |
Foxit PDF Services API | Request (1 credit), any page count within limits | Business: $4,500 a year for 15,000 credits; $0.30 per request only when all included credits are used | 500 credits a year |
LlamaParse | Credits per page by tier | Cost-effective: $3.75 per 1,000 pages | 10,000 credits a month |
Reducto | Pages, priced per product | r-1 Parse: $10 per 1,000 pages (preview) | $150 of usage |
LandingAI ADE | Credits per page plus output characters | DPT-3 Pro standard: 0.5 credits per page plus 0.25 credits per 1,000 output characters ($0.005 per page plus $0.0025 per 1,000 characters) | 1,000 credits for 90 days |
Mistral OCR | Pages | $4 per 1,000 pages, $0.40 with the Batch API | Free-mode limits shown in account |
Azure Document Intelligence | Pages, priced per model | Layout: $10 per 1,000 pages | 500 pages a month (2 pages per document) |
Google Document AI | Pages, priced per processor | Layout Parser: $10 per 1,000 pages | First 1,000 OCR pages |
Amazon Textract | Pages, priced per feature | Tables: $15 per 1,000 pages | 3-month free tier |
Adobe PDF Extract API | Transaction per 5 pages | Sales quote | 500 transactions a month |
Docling | None (self-hosted) | Your compute | Unlimited |
Worked example, long document. At full use of our Business plan’s 15,000 annual credits, Foxit allocates $0.30 per request. A 200-page document would cost $0.80 on Mistral OCR, $2.00 on Azure Layout or Reducto r-1, and $3.00 on Textract Tables. These are calculations from list prices, not equivalent-output benchmarks.
Worked example, short document. A 2-page invoice still costs $0.30 on Foxit at full credit utilization, versus $0.008 on Mistral OCR, $0.02 on Azure Layout or Reducto r-1, and $0.025 on LlamaParse Agentic.
Where the lines cross. At full credit utilization, the $0.30 request cost breaks even at 20 pages against Textract Tables, 24 against LlamaParse Agentic, 30 against the $10-per-1,000-page services, and 75 against Mistral OCR. These are calculations from list prices.
Commitment. Our paid plans use annual credit pools, while most per-page services bill pay-as-you-go. Unused credits raise the effective cost per request. Each successful PDF Services processing call costs 1 credit within supported limits, including each separate call in a batch.
Capabilities still differ. These are price comparisons, not like-for-like capability comparisons. Use the job-coverage table below to check whether you need layout parsing, field extraction, or OCR.
Estimate cost from your actual document lengths and annual volume before choosing a billing model.
Parsing, field extraction and OCR as distinct jobs
Document parsing turns a document into machine-readable structure, including text, headings, tables, reading order, and sometimes positions.
The table below shows which of the 3 jobs each API covers.
API | Layout parsing | Field extraction | OCR for scans |
Foxit PDF Services API | Structural Extraction (Trial), PDF to Markdown | Map elements in code | Dedicated OCR endpoint (about 38 language codes) |
LlamaParse | Yes | LlamaExtract | Yes |
Reducto | Yes | Extract, Deep Extract | Yes |
LandingAI ADE | Yes | Extract API with grounding | DPT-3 Pro |
Mistral OCR | Markdown and blocks | Schema annotations | Yes |
Azure Document Intelligence | Layout | Prebuilt and custom models | Read and Layout |
Google Document AI | Layout Parser | Form Parser, Custom Extractor, prebuilt parsers | Enterprise Document OCR |
Amazon Textract | Layout blocks (no Markdown stated) | Forms, Queries, prebuilt APIs | 6 languages |
Adobe PDF Extract API | Structure JSON, Markdown | No | Scanned PDFs |
Docling | Yes | DocumentExtractor with a schema | Pluggable OCR |
Choose layout parsing when you need document structure for chunking, search, or LLM input. Choose field extraction when you need named values for a database or business workflow.
Field extraction does not always cost more than layout parsing. Compare the specific product and mode rather than assuming a fixed premium.
What happens to your documents
Compare retention, training policies, and private deployment before sending sensitive documents.
The table uses vendor security and data-use documentation checked on October 16, 2026. “Not published” means the reviewed pages did not state a policy.
API | Default retention | Training on your data | Private deployment |
Foxit PDF Services API | Delete endpoint available. Retention period not published as of 16 Oct 2026 | Not published as of 16 Oct 2026 | Cloud only |
LlamaParse | 48-hour cache (opt out per request) | No, by default | BYOC or self-hosted (enterprise) |
Reducto | Results available approximately 12 hours. Growth and Enterprise API artifacts expire within 24 hours, except Studio and persist_results | Never from Growth up; Standard not stated | Hybrid or full VPC (enterprise) |
LandingAI ADE | Optional ZDR on Team and Enterprise, with results deleted after retrieval | Not used under zero retention | VPC or on-premises (enterprise) |
Mistral OCR | Optional ZDR with approved pay-as-you-go access, excluding Files API and batch files | Free mode may train unless you opt out | Single container (enterprise) |
Azure Document Intelligence | Deleted 24 hours after analysis completes | Check the data privacy page | Containers, including disconnected |
Google Document AI | Online document data not persisted. Batch data normally deleted after processing, with a 1-day failsafe TTL | Never (Google claim) | No on-premises option found |
Amazon Textract | May be stored to improve services | May be used, unless you opt out via AWS Organizations policy | PrivateLink; no container |
Adobe PDF Extract API | 24-hour default asset retention, with early deletion available | Not verified as of 16 Oct 2026 | Hosted only |
Docling | Your infrastructure | Not applicable | Self-hosted |
For regulated documents, confirm permitted regions, retention, training opt-outs, and deployment options before evaluating accuracy. A strong benchmark score cannot override a data-handling restriction.
Which accuracy claims you can trust
Who runs the benchmarks. The callout below names the organizations behind the main tests. LongArray-Extract is run by Extend, and Tensorlake ran its own test. Treat vendor-run results as evidence about those tests, not independent validation.
Versions go stale. OmniDocBench’s only Mistral entry uses the March 2025 model, which Mistral had retired by October 16, 2026. RD-TableBench was run in November 2024. Mistral’s OCR 4 announcement compares OCR 4 against competitor models, using Mistral’s own reproductions of competitor scores rather than results from the benchmark owners. Scores attached to retired model versions don’t tell you how the current API performs.
Benchmark scores. LlamaIndex’s ParseBench leaderboard reports Azure Layout at 59.6, Docling at 50.6, Google Layout Parser at 50.4, Textract at 47.9, and its own LlamaParse Agentic at 84.9.
Coverage gaps. As of October 16, 2026, we found no public benchmark covering our PDF Structural Extraction API or Adobe PDF Extract API.
Test 20 to 50 of your hardest pages, including scans, merged-cell tables, 2-column layouts, and handwritten annotations, through 2 or 3 shortlisted APIs. Compare the output with values you have checked by hand. This measures performance on your documents rather than a vendor-curated dataset.
Benchmark ownership. ParseBench is run by LlamaIndex, which publishes LlamaParse. RD-TableBench is run by Reducto. OmniDocBench is published by OpenDataLab, makers of a competing parser. olmOCR-Bench is published by the Allen Institute for AI, another parser creator. Each benchmark publisher’s product wins or places strongly in its own benchmark. Vendor-run benchmark measurements are not independent validation.
Where Foxit fits
Setting the pricing and job-coverage comparisons aside, here is what the Foxit PDF Services API itself covers for a team evaluating it directly.
Extraction routes on the PDF Services API
Our extraction endpoints cover typed JSON, Markdown for RAG pipelines, tables as spreadsheets, and OCR for scanned files. Structural Extraction remains in Trial; its schema and limits are covered in the Foxit entry above.
What else shares the same credit pool
From the same account, you can also convert Office files, redact sensitive values, compress or split PDFs, generate documents, and send them for signature.
Tutorials and comparisons
The structured JSON tutorial, invoice parsing tutorial, and contract metadata tutorial show how to map Structural Extraction output to your own field schema in code. Our Google Document AI comparison covers that API’s layout and extraction capabilities alongside ours.
The free Developer plan
Our Developer plan includes 500 credits a year to try these endpoints before committing to a paid plan.
Create a free Foxit developer account and turn your first PDF into structured JSON with the PDF Structural Extraction API.
What else to know before you pick a document parsing API
You may only need plain text, a free tier for a prototype, or a service you can run yourself.
Is there an API that can extract text from PDFs?
Yes. Our PDF to text endpoint extracts text from PDFs, and services such as Amazon Textract and Azure Document Intelligence offer text-detection or Read endpoints. An open-source library may be enough for digital PDFs. Scanned PDFs need OCR before their text can be extracted.
Is there a free document parsing API?
Yes. Our Developer plan includes 500 credits a year. LlamaParse offers 10,000 credits a month, Adobe 500 Document Transactions, and Azure 500 pages, though Azure processes only 2 pages per document on its free tier. Docling is free to self-host, but you still pay for compute.
Can you self-host a document parsing API?
Yes. Docling Serve exposes Docling as a self-hosted REST API. Some hosted vendors also offer private deployments, including Azure containers, Reducto VPC deployments, LlamaParse self-hosting, LandingAI on-premises, and Mistral’s single-container option. Availability depends on the vendor and plan, and self-hosting leaves you responsible for infrastructure, scaling, and updates.
10 Best HTML to PDF APIs for Developers in 2026

The best HTML to PDF API depends on two things: the engine that renders your HTML and what counts as one billable render. This guide compares 10 options, including Foxit PDF Services API, DocRaptor, PDFShift, and Gotenberg, on engines, JavaScript handling, layout controls, pricing, and free allowances. Use it to build your shortlist and test your hardest template before you pay.
Running Puppeteer for a few invoices is different from maintaining it under concurrent load. JavaScript timeouts, memory use, cold starts, and font differences between development and production can make self-hosted rendering harder to operate as demand grows.
Moving to a hosted API swaps those problems for two questions, which engine renders your HTML and what counts as one billable render.
Those two questions drive the decision more than the headline plan price, because the billing models across these APIs have almost nothing in common. PDFShift charges 1 credit per 5 MB of output, PDFCrowd 1 credit per 0.5 MB, PDF.co 9 credits per page, Browserless one unit per 30 seconds of browser time, and DocRaptor one document whatever its size or page count.
We compare our Foxit PDF Services API with 9 alternatives: DocRaptor, PDFShift, ConvertAPI, PDFCrowd, Api2Pdf, Browserless, PDF.co, Nutrient DWS Processor API, and Gotenberg.
The comparison covers rendering engines, JavaScript handling, layout controls, output options, pricing, free allowances, limits, SDKs, and hosting, using public documentation, API specifications, pricing pages, and GitHub repositories.
Top picks by use case
The best HTML to PDF API depends on where your layout logic lives and how your renders will be billed.
For products that render HTML and then process the resulting PDF, the Foxit PDF Services API covers both steps on one credit pool.
For print-styled documents with complex pagination, DocRaptor’s Prince engine applies CSS paged media directly. The table below maps each pick to the use case it fits best.
Use case | Pick | Why it fits |
HTML to PDF followed by other PDF steps or signing | Foxit PDF Services API | 1 credit per conversion regardless of page count, same credit pool as compress, merge, watermark, OCR, and eSign |
Print-grade layouts with CSS paged media | DocRaptor | Prince 15.1 engine; PDF/A, PDF/UA, and PDF/X profiles; Basic $15 a month for 125 documents |
High-volume Chromium rendering at a low price per credit | PDFShift | Chromium 142; 1 credit per 5 MB of output; Business $99 a month for 25,000 credits |
Page breaks controlled by CSS selector | ConvertAPI | AvoidBreakElements, BreakBeforeElements, and BreakAfterElements; UK, EU, and US endpoints; 250 free conversions at sign-up |
Archival output with multiple PDF/A variants | PDFCrowd | PDF/A-2, PDF/A-3, and PDF/A-4 variants, tagged PDF, SDKs in 7 languages; 1 credit per 0.5 MB of output |
Paying only for the compute a render uses | Api2Pdf | $1 a month plus $0.001 per MB and $0.00019551 per second of compute; Chrome, wkhtmltopdf, or LibreOffice per call |
Puppeteer-level control without running browsers | Browserless | /pdf REST API with waitForSelector and waitForFunction, with a free plan covering 1,000 units a month |
HTML to PDF inside a no-code-friendly PDF toolbox | PDF.co | HTML templates, parsing, forms, and barcodes on one credit balance, with Make and Zapier modules; 9 credits per page |
Static HTML that becomes fillable PDF forms | Nutrient DWS Processor API | HTML form fields turn into fillable PDF fields; HTML to PDF costs 0.5 credit |
Free, self-hosted conversion | Gotenberg | MIT-licensed Docker API with Chromium and LibreOffice, with v8.38.1 released 15 Oct 2026 |
These picks highlight different use cases, not exclusive capabilities. Check each API’s features and limits against your full workflow.
Create a free Foxit developer account and convert your first HTML file or URL to PDF with the PDF Services API.
How we compared these HTML to PDF APIs
Every fact in this article comes from public documentation, API specs, pricing pages, and GitHub, all checked on 16 Oct 2026. Recheck any price before making a purchasing decision, since billing details change.
Compare inputs and engines, JavaScript timing, layout controls, output options, pricing, free allowances, limits, SDKs, and hosting. Where a vendor does not publish a number or engine name, the table notes that gap as of 16 Oct 2026.
Three APIs in this list do not name their HTML rendering engine in their public documentation, namely Foxit PDF Services API, PDFCrowd, and PDF.co. ConvertAPI names Chrome headless. Nutrient’s overview names Chromium, but the generation guide does not and conflicts with the overview on JavaScript support.
We found no independent, reproducible fidelity or speed benchmark of hosted HTML-to-PDF APIs in the sources reviewed. The comparisons that rank for this query are vendor-written.
All prices are in USD unless otherwise noted. Billing period is named beside every price.
The 10 HTML to PDF APIs in detail
Start with the engine and the controls your template needs. Chromium-based APIs such as PDFShift, Browserless, Gotenberg, and Api2Pdf’s Chrome route use a browser print engine. DocRaptor uses Prince for CSS paged media. Check the engine comparison table for differences in JavaScript, headers, and footers.
Foxit PDF Services API
Our PDF Services API is a cloud REST API for automating PDF workflows.
After converting HTML to PDF, you can compress, merge, watermark, protect, or OCR the result, or send it for signature with our eSign API, using the same developer account and shared credit pool.
Feature | Details |
Inputs and engine | Upload an HTML file (embedded CSS, images, and web fonts supported, with external resources needing to be reachable) or pass a public URL. Word, Excel, PowerPoint, images, text, and Markdown convert on sibling endpoints. The API reference does not name the HTML rendering engine. |
JavaScript and waits | The URL route renders the page with JavaScript, with a 30-second JavaScript timeout and a 60-second maximum page load. No delay or wait-for-selector parameter is documented. For uploaded HTML, ship fully rendered markup. |
Layout controls | Page width and height in points (72 to 14,400, default 595 x 842, A4), rotation, single-page or multi-page mode, and scaling (none, scale, enlarge). No margin or header and footer parameters are documented. Set margins and page breaks with @page and print CSS inside the HTML. |
Output options | PDF. Separate endpoints compress, protect, linearize, watermark, flatten, merge, or auto-tag the file for accessibility, at 1 credit each. |
Pricing | 1 credit per successful conversion, regardless of page count or file size within supported limits. Startup $1,750 a year (5,000 credits); Business $4,500 a year (15,000 credits). Credits reset annually with no rollover. |
Free allowance | 500 credits a year on the Developer plan. |
Limits | 100 MB maximum input for uploaded HTML files; no size limit is published for the URL route. Asynchronous: submit, poll the task, then download. Polling and downloads consume no credits. |
SDKs and hosting | REST with OAuth client credentials, with code samples in Python, Node.js, and PHP in the developerapidemos repository. The pdf_from_html and pdf_from_url tools are available in the Foxit MCP server, and n8n and Power Automate walkthroughs are on the Foxit blog. Cloud only. |

Our pricing calculator and credit reference list Business at $4,500/year for 15,000 credits, while the pricing page’s plan cards show a custom Volume tier. Confirm the available plan with our team before purchasing.
Where Foxit PDF Services API stands out
A two-page invoice and a 150-page annual report each use 1 conversion credit within the supported limits. That keeps page count out of the conversion cost calculation, though follow-on operations consume additional credits.
The same credit pool covers the steps that typically follow a render. Compress the file for email delivery, merge it with a cover page or terms document, watermark it, protect it with a password, auto-tag it for accessibility, or send it for signature with eSign, all without touching a second vendor or a second billing system.
For agentic workflows, the Foxit MCP Server exposes pdf_from_html and pdf_from_url as tools that LLM agents can call directly, without custom REST client code.

The Foxit PDF Services page confirming MCP server access comes at no added cost beyond existing API credentials.
What to consider
The API reference does not document margin, header and footer, or wait-for-selector parameters. Layout control happens inside the HTML itself, using @page rules and print CSS. If your template relies on request-level margin or footer injection, you’ll need to build those into the markup before upload.
For uploaded HTML, conversion follows four steps: upload the file, submit the job, poll for completion, and download the PDF. Polling and downloads consume no credits. Build your error handling around task status rather than a single conversion response. Our htmlToPDF.py sample shows this flow in Python, with a Node.js equivalent alongside it.

The htmlToPDF.py sample on GitHub, showing the working Python implementation of the async flow described above.

The four-step async flow. Only the submit step consumes a credit; polling and downloading are free.
Credits are sold as an annual pool with no rollover. If your rendering volume is spiky or hard to predict, estimate conservatively and track consumption through the developer console.

The Foxit developer console’s dashboard, showing the Credits Used tile alongside the active plan’s included credit balance.
Best for
Products where the HTML render is the first step of a longer document workflow, such as generating an invoice and then compressing, watermarking, and sending it for signature on the same account.
Getting started
Create a free Foxit developer account and convert your first HTML file or URL to PDF with the PDF Services API.

The Foxit developer sign-up page, confirming no credit card is required to get started.
DocRaptor
DocRaptor is built on Prince, a CSS typesetting engine that treats HTML as print layout input rather than a browser page.
It’s the go-to for documents whose pagination must match a designed layout, including long reports, financial statements, and books.
Feature | Details |
Inputs and engine | An HTML string or a URL. Prince 15.1 is the default engine (pipeline 10.1), and older Prince versions can be pinned. Also outputs XLS and XLSX. |
JavaScript and waits | Off by default. javascript=true runs DocRaptor’s own JavaScript engine, not Chromium. Signal readiness with docraptorJavaScriptFinished(). JavaScript errors fail the document. |
Layout controls | Page size, margins, headers, footers, and page numbers set in CSS (Prince paged media). Print media is the default, and using screen media when you meant print is described in DocRaptor’s docs as the most common issue. |
Output options | PDF/A-1, 2, and 3 (a and b); PDF/UA-1; PDF/X-1a, 3, and 4; 40 or 128-bit encryption with print, copy, and edit permissions and font embedding controls. |
Pricing | Per document, any size or complexity. Basic $15 a month (125 documents); Professional $29 (325); Premium $75 (1,250); Max $149 (5,000); Bronze $399 (15,000); Silver $1,000 (40,000). Overage from 12 cents a document on Basic down to 2.5 cents on Silver. |
Free allowance | 5 documents a month, plus unlimited watermarked test documents on every plan. |
Limits | 60 seconds synchronous, 600 seconds asynchronous, 30 simultaneous requests. Callbacks fire only on success, so poll to catch failures. |
SDKs and hosting | PHP, Python, Node, Ruby, Java, and .NET; Zapier. Rendering runs in AWS us-east-1 only. Claims SOC 2 Type II and GDPR compliance; HIPAA on paid plans with a BAA. DocRaptor is part of Artifex Software. |

DocRaptor’s full tier ladder, from the free plan through Silver’s 40,000 documents a month.
Where DocRaptor stands out
Prince applies CSS paged media to page size, running headers and footers, margins, and page numbering. Pagination is designed in CSS rather than patched with browser workarounds, which makes complex multi-page layouts consistent and predictable.
DocRaptor’s per-document billing is indifferent to file size or page count. A 200-page regulatory report costs the same credit as a two-page invoice, so teams with large, complex documents get more predictable costs than they would with size-based billing.
PDF/A, PDF/UA, and PDF/X profiles are available at render time with no extra API call. If your compliance requirements include archival or accessibility profiles, they’re applied in the same request that generates the document.
What to consider
JavaScript is off by default. DocRaptor offers its own JavaScript engine and Prince’s separate engine, enabled through different parameters. Test client-rendered charts, dynamic tables, and single-page-app templates with the engine you choose; Chrome previews alone do not establish compatibility.
Rendering runs only in AWS us-east-1. If data sovereignty requires keeping rendering in the EU or Asia-Pacific region, DocRaptor has no regional routing option.
Async jobs send callbacks only on success. A failed async job produces no callback, so your polling logic must handle both successful and failed states.
Best for
Long, print-styled reports and documents whose pagination must match a designed print layout.
Getting started
Start with DocRaptor’s unlimited watermarked test documents on any plan to validate your template before buying a paid tier.

DocRaptor’s documentation on the test parameter, which produces unlimited watermarked documents that do not count against the plan limit.
PDFShift
PDFShift is a Chromium-based rendering API with plans for a range of volumes and version pinning that lets you choose when to change the Chromium version used for your templates.
Feature | Details |
Inputs and engine | A URL or raw HTML, an array of sources for parallel conversion, or stored HTML templates. Headless Chromium is the engine, and the X-Processor-Version header picks Chromium 116 or 142, with new accounts defaulting to the latest. |
JavaScript and waits | A delay of up to 10 seconds, a wait_for JavaScript function (fails after 30 seconds), network idle by default, plus options to disable JavaScript, inject JavaScript or CSS, and lazy-load images. |
Layout controls | Format presets or custom sizes, margins, orientation (portrait or horizontal), zoom, page ranges, and the print stylesheet. Header and footer HTML supports page, total, date, title, and URL variables, but does not inherit the body CSS. |
Output options | PDF, PNG, JPEG, and WEBP, with metadata, password protection and permissions, and text or image watermarks. PDF/A is not in the API schema. |
Pricing | 1 credit per 5 MB of output (a 14 MB PDF uses 3 credits). Starter $9 a month (500 credits); Boost $24 (2,500); Growth $39 (5,000); Business $99 (25,000), up to $999 (1,000,000). Annual billing costs 10 times the monthly price. Overage from $0.04 down to $0.001 a credit. |
Free allowance | 50 credits a month, billed at 1 credit per 5 MB of output, with a 15 MB maximum file size and a 30-second timeout. A watermarked sandbox allows 10 requests a minute. |
Limits | 250 documents a minute. Timeouts run up to 15 minutes on paid plans. Result URLs are kept for 2 days, and webhooks are available for asynchronous jobs. |
SDKs and hosting | Language guides for Node.js, Go, PHP, Python, and Ruby. Exports directly to S3, Google Cloud Storage, or R2. French company; GDPR and HIPAA BAA links in the footer. |

PDFShift’s pricing calculator, confirming the Business tier at 25,000 credits for $99 a month. The page picks a single recommended tier from a credit-count slider rather than listing all tiers at once.
Where PDFShift stands out
Version pinning lets you choose Chromium 116 or 142 with the X-Processor-Version header rather than follow PDFShift’s default engine. It reduces one source of rendering changes, but you still need to test templates when their fonts, assets, or application code change.
The tier ladder runs from $9 a month to $999, covering a wide volume range without requiring a sales conversation. Direct export to your own S3, Google Cloud Storage, or R2 bucket means rendered PDFs land in your storage without an extra download step.
Size-based billing rewards lean templates. PDFs that are mostly text and vector graphics use fewer credits than image-heavy designs, giving you an incentive to optimize output size.
What to consider
Header and footer templates do not inherit your page CSS. Styles applied in the body are invisible inside the header or footer, which is a standard Chromium limitation. You need to duplicate any relevant styles inside those templates.
Image-heavy PDFs consume credits faster than plain ones, because 1 credit covers 5 MB of output. A rendering pipeline for photo-rich marketing materials will cost more than one for text-heavy invoices.
PDF/A output is not in the API schema as of 16 Oct 2026. If you need archival profiles, this API won’t meet that requirement.
Best for
High-volume rendering of modern HTML and CSS where cost per render and predictable engine behavior are the priorities.
Getting started
Use PDFShift’s 50 free monthly credits to test your templates and measure per-file credit consumption before choosing a paid tier.
ConvertAPI
ConvertAPI is a Chromium-based conversion API with CSS-selector page break controls and regional endpoints in the UK, EU, and US.
Feature | Details |
Inputs and engine | An HTML file or a link to one, or a live URL. The OpenAPI description names Chrome headless. With RespectViewport set to false it behaves like Chrome’s print to PDF. |
JavaScript and waits | JavaScript on by default. ConversionDelay runs up to 30 seconds. WaitElement accepts a CSS selector. User JavaScript and CSS injection are supported, as are hiding or showing elements, lazy-loaded content, ad and cookie-banner blocking, and a timeout up to 1,200 seconds. |
Layout controls | Page size presets or custom millimeters, orientation, margins (10 mm default), and scale. Header and footer HTML with page number and total pages. Page breaks by selector with AvoidBreakElements, BreakBeforeElements, and BreakAfterElements. CssMediaType defaults to screen. |
Output options | PDF. PDF/A and PDF/UA are separate PDF tools, not HTML-to-PDF parameters. |
Pricing | Per conversion. Monthly billing: Developer $35 (1,000 conversions); Startup $95 (5,000); Growth $175 (15,000); Business $350 (50,000). Annual billing: $30, $85, $160, and $300 a month with annual pools of 12,000, 60,000, 180,000, and 600,000 conversions. Overage $0.05 a conversion on every plan, minimum 20 overage conversions per billing period. |
Free allowance | 250 conversions at sign-up. |
Limits | Maximum file 200 MB on Developer, up to 2 GB on Enterprise. Developer through Business plans allow 1 to 4 concurrent conversions. Enterprise offers unlimited concurrency. Stored results are kept up to 3 hours. |
SDKs and hosting | Official open-source SDKs; Zapier, Make, and n8n. Regional endpoints in London, Amsterdam, Frankfurt, US East, and US West. ISO 27001 and GDPR compliance cited consistently across its documentation. |

ConvertAPI’s annual-billing tier prices, which match the $30/$85/$160 figures cited in the feature table.

ConvertAPI’s HTML to PDF API reference page, naming Chrome headless as the engine, with a link to the OpenAPI schema beside it.
Where ConvertAPI stands out
The AvoidBreakElements, BreakBeforeElements, and BreakAfterElements parameters let you control page breaks by CSS selector in the API request. That’s a level of pagination control you’d normally need to patch into the HTML itself, and it’s available across all plans.
Regional endpoints in London, Amsterdam, Frankfurt, and two US regions let you choose where rendering runs. If you have EU data residency requirements, confirm the applicable storage, transfer, and contractual terms as well as the endpoint location.
A configurable timeout of up to 1,200 seconds gives slow pages more time to finish rendering. Check it against your application’s own request timeout and response-time requirements.
What to consider
The default media type is screen. If your stylesheet uses @media print rules, you need to set CssMediaType explicitly in each request. Missing this is easy and produces output that ignores your print styles entirely.
Each request can count as one or more conversions, and successful responses report ConversionCost. Failed requests are also billed. Review the ConversionCost field in your response to avoid surprises.
ConvertAPI’s compliance wording varies across its own pages. ISO 27001 and GDPR appear consistently; treat other compliance claims as requiring verification.
Best for
Invoices and reports that need explicit control over where pages break, processed in the UK, EU, or US.
Getting started
The 250 free conversions at sign-up are enough to validate page break behavior and media type handling on your template before purchasing a plan.
PDFCrowd
PDFCrowd offers the widest PDF/A coverage in this comparison, with variants from PDF/A-2a through PDF/A-4f, tagged PDF, and credit-based billing that scales with output size.
Feature | Details |
Inputs and engine | A URL, an HTML file, zipped HTML with assets (up to 300 MB), raw HTML, or Jinja-style data templates. The rendering engine is not named in public documentation. The API pins converter versions (24.04, 20.10, 18.10). |
JavaScript and waits | javascript_delay and wait_for_element, both capped by the plan’s maximum delay (1 to 15 seconds). Custom JavaScript is supported, and JavaScript can be disabled. |
Layout controls | Page size, orientation, and margins. Header and footer HTML with page number and page count classes. A mode that prefers CSS @page rules and viewport options are also available. |
Output options | PDF/A-2a, 2b, 2u, 3a, 3b, 3u, 4, 4e, and 4f. Tagged PDF and encryption with user and owner passwords are supported. PDF/A cannot be combined with encryption, forms, or watermarks. |
Pricing | 1 credit per 0.5 MB of output. Nano $1 a month billed annually (10 credits); Micro $11 (200); Small $23 (1,000); Medium $35 (5,000); Large $61 (10,000); Ultimate $106 (20,000); Enterprise tiers up to $2,630 (3,000,000). Unused credits do not roll over. |
Free allowance | 100 test API credits valid for one month. |
Limits | 60-second limit per conversion. Rates run from 15 to 480 conversions a minute and 1 to 16 concurrent by plan, with 429 and 430 responses when exceeded. No async or webhook option found as of 16 Oct 2026. |
SDKs and hosting | PHP, Java, .NET, Python, Node.js, Ruby, and Go, plus a command-line tool; Zapier, Make, Pipedream, and others. Operated by an EU company with GDPR processor terms. |

PDFCrowd’s credit-based tiers, priced at 1 credit per 0.5 MB of output.
Where PDFCrowd stands out
PDFCrowd supports PDF/A variants from PDF/A-2a through PDF/A-4f, including PDF/A-4e for engineering documents. Tagged PDF output is also available, but tagging alone does not establish accessibility compliance.
Occasional overage is not billed on PDFCrowd’s documented policy, and entry-tier pricing starts at $1 a month billed annually, which makes low-volume archival use affordable.
Zipped HTML upload with assets up to 300 MB handles complex templates with many local resources without requiring a public URL or a content delivery network.
What to consider
Entry plans cap JavaScript waits at 1 to 2 seconds and run one conversion at a time. Concurrency and wait limits scale with plan tier, so a low-cost entry plan may not handle templates that depend on slow client-side rendering.
At 0.5 MB per credit, image-heavy or font-rich PDFs consume more credits than smaller exports. Compare the cost for your actual output sizes, not credit counts alone, because vendors price credits differently.
Sustained overage beyond occasional instances can lead to account suspension according to PDFCrowd’s overage documentation. Monitor consumption carefully on smaller plans.
Best for
Archival or accessible PDFs from HTML at steady monthly volume, especially when choosing among PDF/A variants is a requirement.
Getting started
The 100-credit trial covers a month of testing, enough to measure real output sizes and credit consumption before choosing a tier.
Api2Pdf
Api2Pdf is a metered API that bills for actual compute time and bandwidth consumed, with per-call choice of engine, covering Headless Chrome, wkhtmltopdf, or LibreOffice.
Feature | Details |
Inputs and engine | Raw HTML or a URL rendered with Headless Chrome (PuppeteerSharp-based) or wkhtmltopdf; Markdown through Chrome; Office and 100+ other formats through LibreOffice. The same API merges, watermarks, password-protects, and generates barcodes. |
JavaScript and waits | Delay plus Puppeteer wait-for method and value on the Chrome route. |
Layout controls | Width, height, margins, orientation (portrait or horizontal), scale, page ranges, preferCSSPageSize, print CSS, print background, and Chrome header and footer templates. |
Output options | Tagged PDF and outlines on Chrome PDFs; passwords and watermarks through separate endpoints; screenshots. PDF/A is not in the v2 spec. |
Pricing | $1 a month plus $0.001 per MB of bandwidth and $0.00019551 per second of compute. The $1 monthly fee starts 30 days after sign-up. Api2Pdf’s own example: 10,000 PDFs of 0.1 MB at 2 seconds each cost about $5.91 a month. |
Free allowance | One month of free credit for new accounts. |
Limits | 2 GB of memory and 90 seconds per standard request (V2 XL gives 8 GB and 5 minutes at 10 times the price); no rate, page, or file-size limits stated; files deleted after 24 hours; no webhook field in the v2 spec. |
SDKs and hosting | Python, Node, .NET, PHP, Java, Ruby, and Go; Power Automate and Zapier; an MCP server. Runs on Google Cloud Run in us-central1; managed and self-hosted enterprise options. |

Api2Pdf’s pay-as-you-go pricing page, including its own cost estimator for bandwidth and compute time.
Where Api2Pdf stands out
Api2Pdf estimates about $5.91 for its example of 10,000 small PDFs a month. For an unpredictable workload, compare that metered model with a subscription using your own render times and output sizes.
Each call chooses its engine independently. A batch that mixes HTML invoices (Chrome), legacy HTML files (wkhtmltopdf), and Office documents (LibreOffice) runs through the same API key without switching services.
The $1 monthly base fee after the first month is low enough that Api2Pdf is viable even for low-volume production use, such as a small internal tool that generates a handful of PDFs a week.
What to consider
Cost follows render time and output size, so a slow page with heavy JavaScript costs more than a fast static template. Profile your templates during the free month to understand what they’ll actually cost.
The wkhtmltopdf route runs on an archived, unmaintained engine (see “What happened to wkhtmltopdf” below). For new projects, the Chrome route is the maintained option.
The 90-second per-request cap is a hard ceiling. Templates that require long JavaScript execution or large resource loads need to fit within that window. V2 XL lifts it to 5 minutes at 10 times the compute cost.
Best for
Spiky or cost-sensitive workloads where paying for actual compute beats a fixed monthly tier.
Getting started
The one-month free period is the right time to run your real templates and compute your expected monthly cost before committing.
Browserless
Browserless runs Chrome as a managed service, exposing the same Puppeteer and Playwright controls your existing render code already uses, without you operating the browsers.
Feature | Details |
Inputs and engine | A URL or HTML. The /pdf REST API uses Chrome’s print engine through Puppeteer; full sessions also support Playwright with Chrome, WebKit, and Firefox. |
JavaScript and waits | waitForSelector, waitForFunction, waitForEvent, and waitForTimeout; navigation options; script and style injection; resource blocking; a bestAttempt mode. |
Layout controls | Puppeteer PDF options: format, size, margins, header and footer templates (page number, total pages, date, title, URL), print background, and page ranges. The /pdf endpoint cannot produce a single long-page PDF. |
Output options | A tagged-PDF flag (Browserless notes Chrome’s tagged output is not certified PDF/UA); screenshots. |
Pricing | Billed in units of up to 30 seconds of browser time. Prototyping $25 a month billed annually (20,000 units, then $0.0020 a unit); Starter $140 (180,000; $0.0017); Scale $350 (500,000; $0.0015). Monthly pricing available; annual billing saves approximately 30% per Browserless’s FAQ. |
Free allowance | 1,000 units a month, 2 concurrent browsers, and 2-minute sessions. |
Limits | 2 concurrent browsers on Free, up to 100 on Scale; session length 2 to 60 minutes by plan; PDFs that fail in one request can be split with page ranges and merged. |
SDKs and hosting | REST plus Puppeteer and Playwright connections; endpoints in San Francisco, London, and Amsterdam, with stored data in US infrastructure on the shared fleet. Claims SOC 2 Type II and GDPR compliance; HIPAA BAA and licensed self-hosting on Enterprise. |

Browserless’s unit-based tiers, where one unit covers up to 30 seconds of browser time.
Where Browserless stands out
Existing Puppeteer render code moves over with minimal changes. The /pdf REST API accepts the same options as Puppeteer’s page.pdf(), so teams moving off self-hosted Chrome don’t need to rewrite their rendering logic.
The full session API supports Playwright with Chrome, WebKit, and Firefox for browser automation. Check PDF-export support separately rather than assuming that every supported browser can generate PDFs.
Three geographic regions (San Francisco, London, Amsterdam) give you control over where browser sessions run, reducing latency for geographically distributed workloads.
What to consider
Browserless charges browser time in blocks of up to 30 seconds per connection. Longer waits can increase usage when they cross a block boundary, so measure the full connection duration rather than assuming cost rises in direct proportion to render time.
PDFs that fail to render in a single request may need chunking by page range and merging, which adds request complexity. The /pdf endpoint cannot produce a single continuous long-page PDF.
Chrome’s tagged PDF output is available but Browserless explicitly notes it is not certified PDF/UA. If formal accessibility compliance is a requirement, verify this limitation before building on it.
Best for
Teams with existing Puppeteer or Playwright render code who want to stop operating the browsers themselves.
Getting started
The 1,000 free units a month (2 concurrent browsers) cover lightweight testing. Run your actual templates against the free tier to measure unit consumption before selecting a paid plan.
PDF.co
PDF.co is owned by Artifex Software (the same parent as DocRaptor) and places HTML to PDF alongside parsing, forms, barcode, and extraction endpoints on one shared credit balance, with Make and Zapier modules for no-code integration.
Feature | Details |
Inputs and engine | Raw HTML, a URL, or stored HTML templates. The rendering engine is not named as of 16 Oct 2026. |
JavaScript and waits | Runs the page’s JavaScript on load with no option to disable it; DoNotWaitFullLoad changes how long it waits. |
Layout controls | Margins, paper size (A4 default), orientation, print background, media type (print default), and header and footer HTML with page number and total pages. |
Output options | Encryption profiles; passwords, merge, split, compress, forms, and parsing on other endpoints. |
Pricing | 9 credits per rendered page; job status checks cost 2 credits per call. Billed annually as displayed: Basic $8.99 a month (16,500 credits); Personal $22.49 (37,000); Business 1 $44.99 (80,500); Business 2 $89.99 (159,850); Business 3 $270 (483,000). Basic’s 16,500 credits works out to about 1,833 rendered pages a month, a computed ceiling rather than a vendor-stated page limit. |
Free allowance | 10,000 credits or 30 days, whichever comes first. |
Limits | 30 seconds synchronous; up to 3 minutes asynchronous with a webhook callback; 4 MB request payload; 100 MB per URL input file; output links expire after 60 minutes by default. |
SDKs and hosting | Make and Zapier modules and Postman collections. PDF.co is owned by Artifex Software. |

PDF.co’s annual-billing tiers, matching the 16,500/37,000/80,500 credit figures cited above.
Where PDF.co stands out
HTML to PDF shares a credit balance with parsing, form filling, barcode generation, compression, and splitting. An automation builder in Make or Zapier can chain all of these in one workflow without switching services or managing multiple API keys.
Per-page credits (9 per page) make PDF.co’s cost predictable for fixed-length documents. An invoice that’s always two pages always costs 18 credits, regardless of file size.
The 10,000-credit free trial gives you room to run a realistic volume of test documents and understand exactly what your credit consumption looks like before choosing a plan.
What to consider
At 9 credits per page, a 50-page report uses 450 credits and a two-page invoice uses 18. Personal’s 37,000 monthly credits would cover at most 82 reports or 2,055 two-page invoices if used only for rendering. Polling and other operations reduce those totals.
JavaScript always runs on load and cannot be disabled. If you’re rendering static HTML, there’s no way to skip the JavaScript execution time.
Synchronous calls stop at 30 seconds. Templates with heavy JavaScript or many external resources need the async route with webhook handling.
Best for
Automation builders on Make or Zapier who need HTML to PDF alongside other PDF jobs on one credit balance.
Getting started
The free 10,000-credit trial covers about 1,111 rendered pages, enough for realistic testing of your document types.
Nutrient DWS Processor API
Nutrient DWS Processor API converts HTML to PDF at 0.5 credits per conversion and turns HTML form fields into interactive, fillable PDF form fields, with the option to chain multiple operations in a single /build call.
Feature | Details |
Inputs and engine | An HTML file uploaded with its CSS, fonts, and images, or a URL. The overview names Chromium; the generation guide does not name the engine. |
JavaScript and waits | The generation guide states JavaScript assets are not supported, while the overview claims JavaScript support. Use pre-rendered HTML until this conflict is resolved. |
Layout controls | A layout object with orientation, size, and margins in millimeters; repeating headers and footers through #pspdfkit-header and #pspdfkit-footer elements with page number and page count tokens. HTML form fields become fillable PDF fields. |
Output options | PDF. PDF/A and PDF/UA are separate operations, chainable in one /build request. |
Pricing | HTML to PDF costs 0.5 credit. Starter $75 a month (1,000 credits); Growth $275 (5,000); Pro $445 (10,000). About 10% less billed annually. |
Free allowance | 50 credits a month (watermarked unless pay-as-you-go is enabled with a $25 wallet load). |
Limits | 100 requests per minute per API key on every plan. |
SDKs and hosting | Code examples in JavaScript, Python, Java, C#, and PHP; Zapier; an MCP server. Cloud API; self-hosting is a separate product (Document Engine). Claims SOC 2 Type 2 audited controls and GDPR compliance. |

Nutrient’s Processor API pricing, shown at the annual-billing rate (about 10% below the monthly prices cited in the feature table).

The Processor API overview page’s FAQ, naming Chromium as the engine and listing JavaScript among the web standards it supports, the first half of the conflict described below.

The PDF generation guide’s own callout, stating plainly that JavaScript assets are not supported, the second half of the conflict.
Where Nutrient DWS Processor API stands out
HTML form fields in your source markup turn into fillable PDF form fields in the output, with no post-processing required. If you’re generating application forms, order forms, or any document the recipient needs to complete, this capability is available directly in the conversion step.
Chaining operations in a single /build request reduces round trips. Convert HTML to PDF and apply PDF/A or PDF/UA in one call, rather than two separate API requests.
At 0.5 credit per HTML conversion, 1,000 credits cover 2,000 conversions if used only for that operation. Include any additional operations when estimating the cost of the full workflow.
What to consider
The overview and the generation guide conflict on JavaScript support. The generation guide states JavaScript assets are not supported; the overview says they are. Ship pre-rendered HTML until Nutrient clarifies this at the route level.
Free-plan output is watermarked unless you enable pay-as-you-go with a $25 minimum wallet load. Budget for that activation cost if you’re testing without a paid plan.
Best for
Static HTML templates such as applications or order forms that must become fillable PDFs.
Getting started
Review Nutrient’s HTML-to-PDF guide, then test your form-field conversion on the free tier (50 credits a month, watermarked) before selecting a plan.
Gotenberg
Gotenberg is an MIT-licensed Docker API wrapping Chromium and LibreOffice, with PDF/A, PDF/UA, and e-invoice output built in.
Version 8.38.1 was released on 15 Oct 2026. There are no per-render license fees or vendor quotas, but you pay for hosting and take responsibility for operation and maintenance.
Feature | Details |
Inputs and engine | HTML files (with header.html and footer.html), URLs via Chromium, and Office documents via LibreOffice. Chromium is the named engine. |
JavaScript and waits | Delay, expression, and selector waits. header.html and footer.html cannot load external resources or JavaScript. |
Layout controls | Page size, margins, orientation, print background, and page ranges. Headers and footers via separate HTML files. |
Output options | PDF/A-1b, 2b, 3b; PDF/UA-1; e-invoice (ZUGFeRD/Factur-X); merge, split, encrypt, flatten. |
Pricing | None (self-hosted). MIT license. |
Free allowance | No vendor quota; your hosting costs apply. |
Limits | 30-second default timeout (configurable). Concurrency controlled by container scaling. |
SDKs and hosting | REST API; community client libraries. Docker image; self-hosted on any infrastructure. |

Gotenberg’s GitHub repository, confirming the MIT license and its Chromium/LibreOffice/wkhtmltopdf topic tags.

Gotenberg’s Releases page, confirming v8.38.1 as the current release.
Where Gotenberg stands out
Self-hosting Gotenberg lets you process HTML and PDFs on your own infrastructure. For data residency or air-gapped deployments, also control outbound requests, external assets, and webhook destinations; self-hosting alone does not prevent data from leaving the environment.
PDF/A, PDF/UA, merge, split, encrypt, and e-invoice formatting are all available in the same container, with no per-operation billing. Volume is limited only by the compute you allocate.
What to consider
You own the operational burden, including container updates, Chromium upgrades, concurrency tuning, and uptime. The 30-second default timeout is configurable, but scaling to high concurrency requires running multiple container instances and a load balancer in front of them.
header.html and footer.html cannot load external resources or run JavaScript, which is the same architectural constraint as other Chromium-based APIs.
Best for
Teams with data residency requirements, air-gapped environments, or high enough volume that self-hosting costs less than per-render fees.
Getting started
Pull the official Docker image, run it, and POST your HTML to the Chromium route. The MIT license means no activation step. Grab a ready-to-use sample index.html here and save it in the same directory you run the curl command from, so the –form ‘[email protected]’ line below has something real to upload.
Run this command from your terminal:
docker pull gotenberg/gotenberg:8 The expected output should look like the following:
8: Pulling from gotenberg/gotenberg
4f4fb700ef54: Pull complete
50413e22b8b3: Pull complete
b95dd55d398d: Pull complete
031c4b37fda9: Pull complete
05f2a8effccb: Pull complete
ae7490fdba0d: Pull complete
125be13350c7: Pull complete
Digest: sha256:aa552cc115db488e0f0bcb07446aac13071ad51505b642c84bb894500907b42b
Status: Downloaded newer image for gotenberg/gotenberg:8
docker.io/gotenberg/gotenberg:8
Start the container, then convert an HTML file by posting it to the Chromium route:
docker run --rm -d --name gotenberg -p 3000:3000 gotenberg/gotenberg:8
curl --silent --request POST 'http://localhost:3000/forms/chromium/convert/html' \
--form '[email protected]' \
--output output.pdf \
--write-out 'HTTP status: %{http_code}\n'
file output.pdf The expected output should look like the following:
HTTP status: 200
output.pdf: PDF document, version 1.4, 1 pages The first line starts Gotenberg in the background, exposing it on port 3000. The curl call then POSTs index.html as a multipart file to Gotenberg’s Chromium conversion route, writes the resulting PDF to output.pdf with –output, and prints the HTTP status code with –write-out once the request completes, with –silent suppressing curl’s own progress output so only that final status line shows.
What counts as one billable render
Check the billing unit before comparing plan prices: it determines how your document size, length, and render time affect usage.
API | Billable unit | Entry paid plan | Free allowance | Published limits |
Foxit PDF Services API | 1 credit per conversion, any page count (shared pool) | Startup $1,750 a year, 5,000 credits | 500 credits a year | No published rate limit |
DocRaptor | Document, any size | Basic $15 a month, 125 documents | 5 a month plus unlimited watermarked tests | 60 s sync, 600 s async, 30 simultaneous |
PDFShift | Credit per 5 MB of output | Starter $9 a month, 500 credits | 50 credits a month | 250 documents/min |
ConvertAPI | Conversion | Developer $35 a month (1,000 conversions), or $30 a month billed annually (12,000 a year) | 250 at sign-up | 1 concurrent on Developer |
PDFCrowd | Credit per 0.5 MB of output | Nano $1 a month billed annually, 10 credits | 100 test credits for one month | 60 s per conversion |
Api2Pdf | MB of bandwidth plus seconds of compute | $1 a month plus usage | One month of credit | 90 s and 2 GB per request |
Browserless | Unit of up to 30 s of browser time | Prototyping $25 a month billed annually, 20,000 units | 1,000 units a month | 2 concurrent browsers on Free |
PDF.co | 9 credits per page | Basic $8.99 a month billed annually, 16,500 credits | 10,000 credits or 30 days, whichever comes first | 30 s sync, 3 min async |
Nutrient DWS Processor API | 0.5 credit per HTML conversion | Starter $75 a month, 1,000 credits | 50 credits a month, watermarked | 100 requests/min per API key, all plans |
Gotenberg | None (self-hosted) | No license fee; hosting extra | No vendor quota | 30 s default timeout |
Size-based units (PDFShift and PDFCrowd) mean image-heavy or font-heavy PDFs cost more than plain text renders. A 14 MB image-rich invoice uses 3 PDFShift credits where a 1 MB plain invoice uses one.
Page-based units (PDF.co at 9 credits per page) mean long reports cost proportionally more than short invoices. A 50-page report costs 450 credits; a 2-page invoice costs 18.
Time-based billing needs a closer look. Browserless charges in blocks of up to 30 seconds per browser connection, so separate 2-second and 10-second connections each use one browser-time unit. Api2Pdf meters compute by the second, but bandwidth and the base fee also contribute to the total bill. A fivefold increase in render time does not necessarily mean a fivefold increase in cost.
Flat units (DocRaptor and Foxit per document or conversion) are indifferent to output size and page count within the documented limits. ConvertAPI charges per conversion, but each request can count as more than one conversion, and the successful response reports ConversionCost.
Estimate cost from your real output size, page count, and render time, not from the headline plan price. Benchmark your actual templates on the free tier before committing to a billing model.
For template-plus-data pricing (Word templates, hosted template editors, and document generation), see the “best PDF generator APIs” comparison, which owns that topic.
Which engine renders your HTML
The engine determines almost everything about rendering behavior. Checked 16 Oct 2026.
API | Engine | JavaScript | Headers and footers |
Foxit PDF Services API | Not named in the API reference | URL route runs JavaScript (30 s limit) | No header/footer template parameter documented |
DocRaptor | Prince 15.1 | Off by default; own engine | CSS paged media |
PDFShift | Chromium 116 or 142 | On; delay, wait_for, network idle | Separate HTML template, no body CSS |
ConvertAPI | Chrome headless | On; delay and wait element | Header and footer HTML |
PDFCrowd | Not named as of 16 Oct 2026 | Delay and wait for element, capped by plan | Header and footer HTML |
Api2Pdf | Headless Chrome or wkhtmltopdf | Delay and wait-for (Chrome route) | Chrome templates |
Browserless | Chrome print engine via Puppeteer | Full Puppeteer wait controls | Puppeteer templates |
PDF.co | Not named as of 16 Oct 2026 | Always on | Header and footer HTML |
Nutrient DWS Processor API | Chromium (overview); unnamed in generation guide | Docs conflict; use pre-rendered HTML | Header and footer elements in HTML |
Gotenberg | Chromium | Delay, expression, and selector waits | header.html and footer.html, no JavaScript |
Chromium is the engine behind PDFShift, ConvertAPI, Api2Pdf (Chrome route), Browserless, Gotenberg, and Nutrient (per overview). Chromium-based APIs print the page the way Chrome’s print-to-PDF does, so templates built and previewed in Chrome usually carry over. A Chromium-level constraint applies to headers and footers, where scripts in Puppeteer header and footer templates do not run and the page’s own styles are invisible inside them. PDFShift’s header and footer templates have the same constraint. Gotenberg’s header.html and footer.html cannot load external resources or JavaScript.
Prince (DocRaptor) moves pagination into CSS. Page size, margins, running headers and footers, and page numbers are all defined in the stylesheet through CSS paged media properties, not through request parameters. That approach suits print-designed documents whose layout is controlled by a designer, but client-rendered charts or React-based templates need careful adaptation.
Unnamed engines (Foxit PDF Services API, PDFCrowd, and PDF.co) are not identified in public documentation as of 16 Oct 2026. Base your decisions on what you observe from test renders rather than assumptions drawn from similar APIs.
If your layout logic lives in JavaScript and the browser, a Chromium-based API is the natural fit. If it lives in print CSS and typographic control, Prince via DocRaptor is the right match.
What you can do with the PDF after it renders
Rendering may be only the first step. Your workflow might also need compression for email, a merged cover page, password protection, PDF/A conversion, accessibility tagging, or a signature.
Here’s what’s available per API.
The Foxit PDF Services API covers compress, merge, watermark, protect, linearize, flatten, accessibility auto-tagging, and eSign on the same credit pool, with each PDF Services step costing 1 credit.
Api2Pdf supports merge, watermark, and password protection.
PDF.co covers merge, split, compress, and form operations.
Nutrient DWS Processor API can chain PDF/A, PDF/UA, and other operations in a single /build call.
ConvertAPI offers separate PDF tools including PDF/A conversion.
Gotenberg handles PDF/A, PDF/UA, merge, split, encrypt, flatten, and e-invoice formatting in the same container.
DocRaptor and PDFCrowd apply PDF/A and encryption at render time, so no extra call is needed. PDFShift adds watermarks and protection at render time.
Browserless has no built-in post-render operations.
Count the charges for the full workflow, not just HTTP requests. Nutrient can chain operations in one /build call, but that does not establish a one-unit charge for the whole request. For Foxit, include conversion and follow-on processing credits, and account for eSign’s per-envelope charge separately. Check the applicable billing rules for Api2Pdf, PDF.co, and any render-time options you use.
If the rendered PDF isn’t your final artifact, count the follow-on calls in your cost estimate and your vendor selection criteria.
Will the PDF look the same as your browser preview?
Use your own templates to compare output. Fonts, media type, header and footer styling, and JavaScript timing are useful starting points when a PDF differs from its browser preview.
Fonts are a common source of rendering differences. The same font-family can produce different output on macOS and Linux because the available system fonts differ.
Embedding fonts with @font-face or base64 data URIs keeps output consistent across platforms and across vendors. Puppeteer waits for document.fonts.ready by default before generating the PDF, which is worth replicating in any server-side render flow.
Print vs. screen CSS is the most common rendering surprise, per DocRaptor’s documentation. DocRaptor, PDF.co, Gotenberg, and Playwright default to print media. ConvertAPI defaults to screen. A template styled for screen output will ignore @media print rules, and a template styled for print may render incorrectly in screen mode. Check the default before testing and set it explicitly in your request.
Headers and footers hit a consistent wall across Chromium-based APIs. Puppeteer and Playwright header and footer templates do not run scripts and cannot see page styles. PDFShift’s header and footer templates don’t inherit body CSS. Gotenberg’s can’t load external resources. These are architectural constraints of how Chrome’s print engine handles header and footer injection. Duplicate any necessary styles directly into the template strings.
JavaScript timing can cause blank or partial renders. A page may reach network idle before asynchronous code finishes updating the DOM. Where supported, use an explicit readiness hook such as docraptorJavaScriptFinished() on DocRaptor, wait_for on PDFShift, waitForFunction on Browserless, or waitForExpression on Gotenberg. Otherwise, render the data server-side and send fully populated HTML.
Rendering fidelity
Font differences between macOS and Linux, print vs. screen media type mismatches, header and footer CSS isolation, and JavaScript timing are common causes of output that differs from your browser preview. Each has a documented fix, but the fix depends on the API and the engine. Vendor speed and fidelity claims are claims until you run your own hardest template. Test your most complex document (long tables, manual page breaks, custom web fonts, one chart) on each shortlisted free tier before committing.
Choosing an HTML to PDF API for your pipeline
Two questions decide which API fits your pipeline, which engine renders your HTML and what counts as one billable render.
A Chromium-based API matches templates built and previewed in Chrome. Prince, via DocRaptor, suits documents whose pagination is designed in CSS paged media.
A flat per-document or per-conversion charge removes the size and page-count variability that a size-based or page-based unit introduces, which matters most when document length varies widely from one render to the next.
If HTML rendering starts a longer document workflow, our PDF Services API lets you convert, compress, merge, watermark, protect, and auto-tag PDFs through one account. Our eSign API uses the same shared credit pool, with its own per-envelope charge. Choose the plan based on the full sequence of operations, not conversion volume alone.
Our free Developer plan includes 500 shared credits a year, plus eSign trial access. Use it to test your HTML templates and follow-on PDF operations before choosing a paid plan.
What else to know before you pick an HTML to PDF API
A few questions come up repeatedly when developers evaluate these APIs, so here are direct answers.
Can I convert HTML to PDF for free?
Yes. Our Foxit PDF Services API supports HTML-to-PDF conversion on the free Developer plan, which includes 500 shared credits per year. Each conversion uses one credit, and no credit card is required to sign up.
How do I bulk convert HTML to PDF?
Submit conversions within both the rate and concurrency limits. Use webhooks where available, or poll task IDs in your worker pool, as with our PDF Services API. PDFShift accepts arrays of sources for asynchronous conversion when parallel conversions are enabled on the account. DocRaptor supports async mode with callbacks. In Gotenberg, the concurrency setting controls simultaneous conversions within a browser, not the number of Chromium instances; scale container instances for heavier loads.
Per-minute and concurrency limits are the real ceiling on batch throughput. Check the limits row in each feature table and design your batch queue around those ceilings.
What's the best npm package to convert HTML to PDF?
Puppeteer and Playwright are the standard choices. Both drive headless Chromium, give you full control over the render, and keep documents on your server. Puppeteer is the more established package with a larger ecosystem, while Playwright adds cross-browser support (WebKit, Firefox) and has a clean async API.
At low volume with full control requirements or strict data locality, a self-managed Puppeteer or Playwright setup is hard to beat. The operational problems emerge at scale, where concurrency requires multiple browser instances with real memory footprints, cold starts on serverless functions add latency, font configuration differences between development and production machines cause output inconsistencies, and Chromium upgrades can change rendering. Those are the conditions where a hosted API earns its cost.
What happened to wkhtmltopdf?
The wkhtmltopdf GitHub repository was archived by its owner on 2 Jan 2023, with the last commit in November 2022. Api2Pdf still offers a wkhtmltopdf route for legacy compatibility.
For new projects, choose a maintained engine. Chromium-based APIs (PDFShift, ConvertAPI, Browserless, Gotenberg, Api2Pdf’s Chrome route) and Prince (DocRaptor) are both actively developed. Building on an archived engine means carrying its unresolved bugs and security findings with no fixes coming.
10 Best PDF MCP Servers for AI Agents in 2026

Not every PDF MCP server can do what your agent needs. This guide compares 10 options, from free local readers to cloud APIs that convert, edit, and secure files, so you can match the server to the job. See where each one sends your documents, what a full workflow costs, and which security gaps to close before you connect.
When an AI agent struggles with a scanned invoice or loses a table’s structure, it may need a tool built for that task.
A PDF MCP server gives it access to document tools, from text extraction and OCR to merging files or requesting a signature, depending on the server.
The choice comes down to what your agent needs to do and where the document can be processed.
Some servers process files on your machine; others send them to a cloud API. This guide compares 10 PDF MCP servers by their capabilities, setup, cost, and data-handling requirements.
Before connecting a server, consider what your agent can access and where document content goes, and treat incoming PDFs as untrusted input, especially when the agent can modify files.
Top picks by job
Start with the output your agent needs. For reading and extraction, compare the open-source options.
For editing, conversion, or other jobs that produce a new file, compare cloud API servers, Stirling PDF, and local toolkits.
Check current versions and documentation before integrating, since tool counts and pricing tiers shift as vendors ship updates.
| Job | Pick | Why it fits |
|---|---|---|
| Converting and editing PDFs through one cloud API | Foxit PDF API MCP Server | 40 tools in v1.1.2 for conversion both ways, merge, split, compress, OCR, redaction, watermark, and forms |
| Certificate-based signing inside agent flows | Nutrient DWS MCP Server | A PAdES digital signing tool, plus OCR and AI redaction, on Nutrient’s cloud |
| Zero-install PDF editing in claude.ai or ChatGPT | CloudConvert MCP Server | Hosted Streamable HTTP endpoint with OAuth; 24 tools |
| Invoice parsing and table extraction in the cloud | PDF.co MCP Server | 38 tools including fillable forms, table finding, and an AI invoice parser |
| Open-source, layout-aware conversion for RAG | Docling MCP | MIT, OCR and table-structure options, v3.3.0 released 6 Oct 2026 |
| Managed parsing and schema extraction | LlamaParse MCP | 26 tools on the unified OAuth endpoint, including indexing and project-key creation; 10K free credits/month |
| Searching long PDFs and whole folders locally | pdf-mcp (jztan) | 13 tools with hybrid keyword and semantic search that flags hidden text as untrusted |
| Lightweight local reading across many formats | anymd | Rust binary, 4 tools, no API key, 6,144 weekly npm downloads for @sylphx/anymd as of mid-October 2026 |
| A self-hosted PDF toolbox behind your firewall | Stirling PDF MCP Server | Built into Stirling PDF with OAuth2 or API key, off by default |
| Offline editing with no account | PDF Toolkit MCP | 22 local tools for merge, split, encrypt, forms, and creation |
These picks highlight different uses, not exclusive capabilities. Check each entry’s feature table against your full workflow.
How we compared these servers
For each server, we compare 6 fields: capabilities, data routing, setup, pricing, maintenance, and supported clients.
Tool lists and versions come from project READMEs and release notes, package metadata from npm or PyPI, and hosted-service details and costs from vendor documentation and pricing pages.
GitHub stars and directory visitor counts, including PulseMCP’s estimates, indicate popularity. Vendor-provided speed or accuracy figures, including anymd’s comparison with Docling and MarkItDown, are not independent test results.
For a deeper look at how MCP agents use PDF APIs together, see Building Agentic Document Workflows and the Foxit MCP Server setup guide.
The 10 PDF MCP servers in detail
Some servers run locally but send documents to a cloud API when a tool runs.
Before connecting confidential files, check the “Where files go” row in each table, along with the operations, setup requirements, and cost.
MarkItDown MCP deserves a brief mention as a conversion reference.
It exposes a single tool, has no built-in auth, and carries an alpha-suffixed release with conflicting Beta metadata, so its design assumes local-trusted use.
It’s excluded from the main list on scope grounds, but it’s a useful data point for single-format conversion comparisons.

Foxit PDF API MCP Server
Foxit maintains the Foxit PDF API MCP Server under the MIT license, packaging the Foxit PDF Services API operations as MCP tools and giving any MCP-compatible host direct access to Foxit’s cloud PDF engine.
The npm package @foxitsoftware/foxit-pdf-api-mcp-server registers 40 tools in v1.1.2 (13 Jul 2026), though the README for that version lists 36; the 4 additional registered tools in the package code are pdf_extract, pdf_ocr, pdf_redact, and pdf_structural_analysis.

Foxit’s npm package at v1.1.2, under the MIT license. The README preview groups operations by category; the 40-tool count comes from the shipped code.
| Feature | Details |
|---|---|
| Covers | Convert to/from PDF (Office, HTML, URL, text, images), merge, split, extract, compress, flatten, rotate, reorder, watermark, linearize, compare, OCR, redact, structural analysis, password protect/remove, form data import/export, properties. 40 tools in v1.1.2 (README lists 36). |
| Where files go | The server runs locally and calls Foxit’s cloud. Upload local files once and reuse document IDs for subsequent operations. URL and text creation can send inputs directly without a separate upload step. |
| Setup | stdio or –transport httpStream. Credentials (FOXIT_CLIENT_ID/SECRET) go in environment variables; v1.1.2 sends them as headers, unlike the current REST OAuth docs. HTTP mode defaults to 0.0.0.0 with no inbound auth, so keep it local or add access controls. |
| Pricing | 1 credit per successful (2xx) billable PDF processing request. Uploads, polling, downloads, and error responses (4xx/5xx) do not consume credits. Free Developer plan: 500 credits/year. See Credits Explained and the pricing page. |
| Maintenance | MIT. npm v1.1.2 (13 Jul 2026). The official MCP Registry still links to npm v0.2.3. Install from npm directly to get the current version. |
| Works with | Claude Desktop, VS Code, and Cursor, plus any MCP host via stdio or HTTP stream. |

Foxit charges 1 credit for each successful billable PDF processing request. Uploads, polling, downloads, and failed requests do not use credits.

The free Foxit Developer plan includes 500 credits per year.

The MCP Registry entry shown here points to npm v0.2.3, not the v1.1.2 package on npm. Install from npm directly for the version covered in this guide.
Where Foxit PDF API MCP Server stands out
Document IDs let agents chain uploaded files and processing results across steps without re-uploading, and MCP access ships with your API credentials at no extra cost, with the free Developer plan giving 500 credits per year and no credit card required.

Foxit makes its PDF Services operations available to agents through the MCP server.
What to consider
eSign and Document Generation are separate Foxit APIs with their own tools but the same shared credit pool, wrapped as custom tools when your agent needs them, per the Foxit MCP Server post.
Most operations follow an async pattern (call the operation, then get_task_result), except pdf_protect, which polls internally, so factor that into your tool-call count.
The HTTP transport also defaults to binding 0.0.0.0 with no inbound authentication, so add access controls before exposing it externally; get_task_result may also share results via a public link, so treat it as a data-sharing event, not a status check.
Best for
Agents that convert, assemble, and secure documents as part of a product workflow.
Getting started
Create a free Foxit developer account and follow the pinned @foxitsoftware/foxit-pdf-api-mcp-server package setup. Confirm the authentication path against the current API reference before deploying.
Nutrient DWS MCP Server
The Nutrient DWS MCP Server, maintained by Nutrient (formerly PSPDFKit), wraps the Nutrient Document Web Services API as MCP tools, covering a broad range of document operations with PAdES certificate-based digital signing as a standout capability not commonly found elsewhere on this list.
| Feature | Details |
|---|---|
| Covers | Merge, convert between PDF, Office, images, HTML, Markdown, and PDF/A, OCR, watermark, rotate, flatten, compress and linearize, redact, passwords and permissions, data and field extraction, and digital signing (PAdES). |
| Where files go | The server runs locally and sends processing files to Nutrient’s cloud. Sandbox restrictions apply only when configured. |
| Setup | stdio via npx or the Claude extension. OAuth covers both APIs; headless/API-key use needs separate Processor and Data Extraction credentials. |
| Pricing | Separate billing for Processor (50 free credits/month; paid Starter beyond that) and Data Extraction (per-page parsing, field extraction extra). Free plan applies a watermark, removed on paid PAYG. See pricing. |
| Maintenance | MIT. v0.1.3 (28 Aug 2026). |
| Works with | Claude Desktop, Cursor, Windsurf, VS Code, and Codex. |

Nutrient’s MIT-licensed MCP server, shown here at v0.1.3.

Nutrient includes 50 free Processor credits per month, but removing the output watermark requires paid or pay-as-you-go access.
Where Nutrient DWS MCP Server stands out
PAdES certificate-based digital signing, required for legally binding signatures in many European and enterprise contexts, is the key differentiator.
Paired with OCR and AI-assisted redaction, an agent can scan a document, redact sensitive fields, and apply a certificate-based signature in one workflow.
The server also supports PDF/A conversion for archival or regulatory use.
What to consider
The free-plan watermark is removed only on a paid PAYG tier, so confirm that tier is active before deploying anywhere watermarked output is a problem.
The server is still pre-1.0 at v0.1.3, so the tool surface and auth model may change, and headless use needs separate Processor and Data Extraction credentials.
Best for
Agents that must apply a certificate-based digital signature before a document leaves the workflow.
Getting started
See the Nutrient DWS MCP Server on GitHub and the Nutrient PDF MCP server page for setup and current credential requirements.
CloudConvert MCP Server
The CloudConvert MCP Server is a fully hosted server maintained by CloudConvert, the file conversion service, running as a Streamable HTTP endpoint authenticated with OAuth 2.0, nothing to install.
| Feature | Details |
|---|---|
| Covers | Convert, compress, watermark, capture URLs to PDF, merge, OCR, PDF/A, encrypt and decrypt, split and extract pages, rotate. 24 tools. |
| Where files go | CloudConvert’s cloud. Input files can be supplied as downloadable URLs. Output links expire after 24 hours. ChatGPT automatically bridges attachments into temporary input URLs. |
| Setup | Hosted Streamable HTTP endpoint with OAuth 2.0. Nothing to install. |
| Pricing | 10 free conversion credits per day, with additional credits via packages or subscriptions. See CloudConvert pricing. |
| Maintenance | Hosted service with no package version to track. |
| Works with | ChatGPT and Claude connectors, per CloudConvert’s docs. |

CloudConvert includes 10 free conversion credits per day.
Where CloudConvert MCP Server stands out
The hosted endpoint works directly in ChatGPT and claude.ai with no local setup, and ChatGPT attachments become temporary downloadable URLs automatically, so an agent can process uploaded PDFs without the user managing file transfers.
What to consider
The 24-hour link expiry on outputs means downstream steps need to download or store results promptly, and clients other than ChatGPT or claude.ai must supply files as downloadable URLs, so confirm your client can do that and supports the required transport before committing.
Best for
Hosted chat workflows where files arrive as attachments or downloadable URLs (ChatGPT or Claude connectors).
Getting started
See the CloudConvert MCP Server docs for connector setup and OAuth configuration.
PDF.co MCP Server
The PDF.co MCP Server, maintained by the PDF.co team, wraps the PDF.co cloud API as MCP tools.
Its 38 tools cover typical extraction and conversion jobs, including an AI invoice parser and table-finding tools for document data extraction workflows.
| Feature | Details |
|---|---|
| Covers | PDF to JSON, CSV, text, Excel, XML, HTML, and images; Office, HTML, and images to PDF; merge, split; read, fill, and create forms; OCR; passwords; table finding; AI invoice parsing. No compression tool. |
| Where files go | PDF.co’s cloud. |
| Setup | stdio via uvx. API key required. |
| Pricing | Credit-based, starting from a monthly plan billed annually. HTML to PDF costs 9 credits per page as a reference point. See PDF.co pricing for current rates. |
| Maintenance | MIT. v0.0.9 (28 Jul 2026). |
| Works with | Cursor and Claude Desktop. |

PDF.co sells monthly plans with a set credit allowance.

PDF.co’s MIT-licensed MCP server, shown here at v0.0.9.
Where PDF.co MCP Server stands out
The AI invoice parser and table-finding tools cut the work an agent would otherwise do in its own context window when pulling line items, totals, and vendor fields from financial documents.
The fill_forms tool (named fill_pdf_forms in the README but registered as fill_forms in the package) and the form-creation tools round out coverage for fillable documents.
What to consider
PDF.co has no compression tool. If your workflow also needs smaller files, you’ll need a separate compression step.
Best for
Agents that pull table data and invoice fields out of PDFs at scale.
Getting started
See the PDF.co MCP Server on GitHub for installation and API key setup.
Docling MCP
Docling MCP, maintained by the LF AI and Data project that started at IBM Research, wraps the Docling document processing library as MCP tools, converting documents to structured formats for RAG ingestion pipelines that need clean structure from complex layouts.
| Feature | Details |
|---|---|
| Covers | Convert PDFs and other documents to Docling JSON or Markdown, with OCR and table-structure options, build new documents, and optional RAG tool groups. No PDF binary editing. |
| Where files go | Local conversion or your own Docling Serve instance. Remote is the default; local processing requires the local extras install. Optional RAG and model service routing may send data to configured external endpoints. |
| Setup | stdio, SSE, or streamable HTTP. The remote Docling Serve API key is separate from MCP endpoint authentication; configure both independently. |
| Pricing | Free and open source; you pay for compute. |
| Maintenance | MIT. v3.3.0 (6 Oct 2026). Version 3.x requires MCP SDK v2; verify your integration’s SDK version before upgrading. |
| Works with | Claude Desktop, LM Studio, and Llama Stack. |

Docling MCP’s v3.3.0 release on GitHub.
Where Docling MCP stands out
Layout-aware conversion preserves table structure, column ordering, and document hierarchy, cutting the cleanup work an agent would otherwise do when indexing research papers, technical specs, or multi-column reports.
Optional RAG tool groups let agents build and query vector indexes from the same server, simplifying pipelines for teams that want ingestion and retrieval in one place.
What to consider
Docling MCP converts documents and does not write PDF binaries, so it cannot merge, compress, or encrypt a file; pair it with an editing server for pipelines that need both.
The v3.x requirement for MCP SDK v2 is a real constraint to check before upgrading from v2.x.
Best for
RAG and ingestion pipelines that need clean, layout-aware structure from complex document layouts.
Getting started
See Docling MCP on GitHub for installation options and Docling Serve configuration.
LlamaParse MCP
LlamaParse MCP is the hosted MCP server for LlamaIndex’s LlamaParse document parsing service, running entirely on LlamaIndex’s infrastructure with nothing to install, covering structured extraction, schema-based parsing, and index management through 26 tools on a unified OAuth endpoint.
| Feature | Details |
|---|---|
| Covers | Parse to Markdown or text with OCR, classify, split into sections, schema-based extraction and indexing. No PDF binary editing. LiteParse is available for jobs that do not require Parse credits. |
| Where files go | LlamaIndex’s cloud, with North America and EU endpoints available. |
| Setup | Hosted Streamable HTTP. Interactive clients use OAuth; API-key callers pass files by URL (not direct upload). |
| Pricing | 10K free credits/month; Starter tier includes 40K credits/month. Additional usage billed per 1,000 credits. See LlamaIndex pricing for current rates. |
| Maintenance | Hosted service. The older run-llama/mcp-server-llamacloud repo is archived; use the current hosted endpoint. |
| Works with | Cursor, VS Code, Claude Code, Claude connectors, and Codex. |

LlamaParse includes 10K credits per month on Free and 40K on Starter.
Where LlamaParse MCP stands out
The unified endpoint means no server to run, model to download, or Docling Serve to maintain, cutting operational overhead for teams that want managed parsing and schema extraction with North America/EU data routing.
Schema-based extraction suits varied document types, since you define the schema and let LlamaParse handle extraction, which tends to produce more consistent results than prompting an LLM to locate fields.
What to consider
LlamaParse MCP reads and parses documents without modifying PDFs; account and index writes consume credits separately from parsing.
LiteParse skips Parse credits for jobs that don’t need high-fidelity parsing, but API-key callers can’t upload files directly and must supply a URL to an accessible file, adding a step for locally stored documents.
Best for
Teams extracting structured fields from varied documents without running their own parser.
Getting started
See the LlamaParse MCP docs for endpoint details and OAuth setup.
pdf-mcp (jztan)
The pdf-mcp server by jztan is an open-source, locally-running MCP server focused on reading and searching PDFs.
Its 13 tools include hybrid keyword and semantic search, page-level reading, table extraction, and vector-chart data reading, and it flags hidden or injected text as untrusted rather than passing it silently along.
| Feature | Details |
|---|---|
| Covers | Hybrid and folder search, page reads, tables, vector-chart data, Tesseract OCR, and page rendering. Note that local embedding, model, and OCR dependencies must be installed separately. No PDF editing. |
| Where files go | Local by default. HTTP deployments use the configured server. Optional remote embeddings send text to the configured endpoint. |
| Setup | stdio or bearer-token-protected HTTP. Claude Desktop extension available. VS Code, Cursor, Codex CLI, and Kiro setups are documented. |
| Pricing | Free. |
| Maintenance | MIT. v3.5.0 (3 Oct 2026). |
| Works with | Claude Desktop and Claude Code; documented setups for VS Code, Cursor, Codex CLI, and Kiro. |

The v3.5.0 release of jztan’s pdf-mcp server.

pdf-mcp combines keyword and semantic search. Its README says hidden or injected text is flagged as untrusted rather than silently passed to the agent.
Where pdf-mcp (jztan) stands out
The server reads only the pages an agent requests rather than dumping an entire PDF into context, cutting token use for long contracts, filings, and manuals at scale.
It also explicitly flags hidden or injected text as untrusted, a warning most reading tools never surface.
What to consider
This server reads and searches PDFs only; it cannot merge, split, rotate, compress, or otherwise modify a document.
PulseMCP’s directory lists editing capabilities the README doesn’t document, so rely on the README, and budget setup time for external dependencies (Tesseract for OCR, a local embedding model for semantic search).
Best for
Research and review agents working through long contracts, filings, or technical manuals where selective reading reduces cost.
Getting started
See pdf-mcp on GitHub for dependency setup and client configuration.
anymd
anymd (formerly pdf-reader-mcp) is a Rust binary distributed via npm. It converts PDFs and other document formats to Markdown, with 4 tools, no API key, and no network upload for local files.
| Feature | Details |
|---|---|
| Covers | Four tools for mixed-format reading and Markdown output. OCR requires opt-in local models or an installed Tesseract binary. No PDF editing. |
| Where files go | Your machine. No files are uploaded. |
| Setup | stdio Rust binary installed via npm (npx -y @sylphx/anymd). No API key required. |
| Pricing | Free MIT core. An optional $29 one-time Pro add-on enables video timelines and citation checks. |
| Maintenance | MIT core. Release 8.5.3 (11 Oct 2026). |
| Works with | Claude Code, Codex, Cursor, VS Code, Claude Desktop, Windsurf, and Gemini CLI. |

Use SylphxAI’s anymd project and the @sylphx/anymd npm package. The unscoped anymd package belongs to an unrelated macOS-only tool, 1qh/anymd.

The @sylphx/anymd package at v8.5.3, showing 6,144 weekly downloads in mid-October 2026. Those downloads belong to this scoped package, not the unrelated anymd package.
Where anymd stands out
Its zero-dependency, zero-upload design supports mixed-format reading in a local agent, since pointing it at a folder of PDFs, Word docs, and Markdown files lets it read all of them through one server with no account setup and a small runtime footprint.
The @sylphx/anymd package shows 6,144 weekly downloads as of mid-October 2026, suggesting active use, though download counts don’t map directly to unique users and the figure moves week to week.
What to consider
anymd is read-only, converting documents to Markdown without producing modified PDFs, and OCR needs either a local Tesseract install or opting into local model support.
The author’s benchmark against Docling MCP and MarkItDown MCP is self-run and not independently validated, so treat it as a directional vendor claim.
Best for
Coding agents that need to read mixed-format document folders quickly, without network calls or API keys.
Getting started
See anymd on GitHub for installation and format support details.
Stirling PDF MCP Server
The Stirling PDF MCP Server is the MCP interface built into Stirling PDF, a self-hosted PDF toolbox, exposing PDF editing and conversion operations over a Streamable HTTP endpoint behind OAuth2 or per-user API keys, off by default.
| Feature | Details |
|---|---|
| Covers | Page operations (merge, split, rotate, reorder), conversion to and from PDF, compression, flattening and repair, encryption and permissions, upload and download, and AI features. |
| Where files go | Your server for standard PDF operations. AI features use configured model and embedding providers, which may be hosted externally depending on your configuration. |
| Setup | Streamable HTTP at POST /mcp, disabled by default. OAuth2 or per-user API key. Read and write scopes apply only in OAuth mode. Enable the server in Stirling PDF’s config and configure auth before exposing it. |
| Pricing | Stirling PDF has Free, Team, and Enterprise tiers; see the Stirling pricing page. MCP usage and credit consumption are not described on the MCP documentation page; do not treat platform pricing as per-tool call charges without confirming separately. |
| Maintenance | Open-core; MCP implementation is proprietary. Stirling PDF v3.1.0. Verify the applicable User License for your deployment context before production use. |
| Works with | MCP Inspector; Claude Desktop via mcp-remote. |

Stirling PDF offers Free, Team, and Enterprise plans. These are platform tiers, not a confirmed per-tool MCP rate card.

Stirling PDF’s MCP endpoint is disabled by default. Enable /mcp and configure API key or OAuth 2.1 authentication before connecting a client.

Stirling PDF v3.1.0 on GitHub.
Where Stirling PDF MCP Server stands out
The full editing toolbox runs behind your own firewall and stays accessible to agents with scoped permissions, letting teams in regulated industries or with data-residency requirements process PDFs on their own infrastructure.
The read/write scope separation in OAuth mode lets you start an agent with read-only access and expand permissions once you trust its behavior.
What to consider
You’re responsible for running, securing, and maintaining Stirling PDF. Default inline response payloads cap at 10 MB (less after base64 encoding), with large outputs using a fileId reference instead.
For AI features, confirm your model and embedding providers match your data-handling requirements, since the default example config uses hosted providers, and check the User License before production use.
Best for
Teams seeking self-hosted PDF editing exposed to agents, with control over data routing and scoped permissions.
Getting started
See the Stirling PDF MCP Server docs and the Stirling PDF GitHub repo for configuration and licensing details.
PDF Toolkit MCP
PDF Toolkit MCP, maintained by AryanBV, is an open-source, fully offline MCP server with 22 tools for reading, editing, and creating PDFs, requiring no account, no API key, and making no network calls.
| Feature | Details |
|---|---|
| Covers | Extract text and metadata, search, compare, and convert to Markdown; merge, split, rotate, reorder, flatten, AES-256 encryption; page numbers and QR codes; create PDFs from text, Markdown, or templates; fill forms; watermark; render pages to images. No compression or built-in OCR. |
| Where files go | Your machine. Fully offline. |
| Setup | stdio via npx. No auth required. |
| Pricing | Free. |
| Maintenance | MIT. v0.3.1 (30 May 2026). |
| Works with | Claude Desktop, Claude Code, Cursor, VS Code, and Windsurf. |

PDF Toolkit MCP v0.3.1 includes 22 tools for local PDF work.
Where PDF Toolkit MCP stands out
The server combines reading, editing, and creating PDFs with no external dependencies. AES-256 encryption, page creation from Markdown, and form-filling without uploading to any service support workflows where the data cannot leave your machine.
The rendering tool sends page images to the client’s vision model for analysis, extending OCR-like capability without bundling an OCR engine.
What to consider
There is no compression tool and no built-in OCR, so extracting text from rendered page images needs a vision-capable client, with accuracy depending on that model.
Built-in fonts cover Latin characters only, so non-Latin create or fill operations need a supplied fontPath pointing to an appropriate font file.
Best for
Local agents that edit documents containing data you cannot upload to a cloud service.
Getting started
See PDF Toolkit MCP on GitHub for the full tool list and font configuration notes.
What PDF MCP servers can and cannot do for an agent
A tool list is only part of the decision. Compare what each server can produce, where it processes files, and how a complete workflow is billed.
Capability coverage across all 10 servers
The table below marks a cell only where the README or vendor docs explicitly list the capability as of 7 October 2026.
| Server | Read and extract | OCR | Convert to or from PDF | Merge or split | Compress | Protect or redact | Runs on |
|---|---|---|---|---|---|---|---|
| Foxit PDF API MCP Server | Yes | Yes | Yes (both ways) | Yes | Yes | Password and redaction | Foxit cloud |
| Nutrient DWS MCP Server | Yes | Yes | Yes (both ways) | Merge | Yes | Password and redaction | Nutrient cloud |
| CloudConvert MCP Server | Via conversion | Yes | Yes (both ways) | Yes | Yes | Encrypt | CloudConvert cloud |
| PDF.co MCP Server | Yes | Yes | Yes (both ways) | Yes | No | Password | PDF.co cloud |
| Docling MCP | Yes | Yes | To Markdown or JSON | No | No | No | Local or Docling Serve |
| LlamaParse MCP | Yes | Yes | Markdown/text parsing; JSON extraction | Logical section splitting | No | No | LlamaIndex cloud |
| pdf-mcp (jztan) | Yes | Yes (Tesseract) | No | No | No | No | Local |
| anymd | Yes | Opt-in (Tesseract or local model) | To Markdown | No | No | No | Local |
| Stirling PDF MCP Server | Yes (OCR via enabled ocr-pdf using OCRmyPDF/Tesseract); AI Q&A needs AI engine | Yes | Yes (both ways) | Yes | Yes | Encrypt and permissions | Your server |
| PDF Toolkit MCP | Yes | Via rendered page images to client vision | To Markdown; from text, Markdown, or templates | Yes | No | AES-256 encrypt | Local |
Reading is well covered by open source, with five servers offering local-only processing at no cost.
Editing (merge, convert, compress, protect) needs a cloud API server, Stirling PDF, or PDF Toolkit MCP, and no single server covers every capability, so the right choice depends on which operations your workflow needs.
Where your document goes when the agent calls a tool
A locally running server doesn’t necessarily keep document content on your machine. pdf-mcp, anymd, and PDF Toolkit MCP process PDFs locally, but content returned to the agent may still reach its model provider, and pdf-mcp can also use remote embeddings.
Docling MCP defaults to a remote Docling Serve instance unless you install the
local extras, and Stirling PDF processes PDFs on your own server but routes AI features through hosted model and embedding providers.
Foxit, Nutrient, CloudConvert, PDF.co, and LlamaParse all process files in the cloud, so check each vendor’s retention policy and the entries above for file-handoff and regional options.
What a tool call costs
Pricing captured from vendor pricing pages, 7 October 2026. Verify current rates before budgeting a workflow.
| Server | Pricing model | Free allowance |
|---|---|---|
| Foxit PDF API MCP Server | 1 credit per successful (2xx) billable PDF processing request; shared credit pool. See pricing. | 500 credits/year |
| Nutrient DWS MCP Server | Credits per operation (e.g., HTML to PDF: 0.5 credits; OCR: 2 credits); separate Processor and Data Extraction billing. See pricing. | 50 Processor credits/month; default watermark removed with paid PAYG |
| CloudConvert MCP Server | Conversion credits per operation; packages or subscriptions. See pricing. | 10 credits/day |
| PDF.co MCP Server | Credits per page and per call. See pricing. | Trial credits on signup |
| LlamaParse MCP | Per-credit usage above free tier; Starter tier includes 40K credits/month. See pricing. | 10K credits/month |
| Stirling PDF MCP Server | Platform-level tiers (Free, Team, Enterprise); 1 cent per credit on paid tiers. See pricing. | 1,000 credits/month on free tier |
| Docling MCP | Free open-source core; you pay for compute and any remote services you configure. | No per-call meter |
| pdf-mcp (jztan) | Free. | No per-call meter |
| anymd | Free MIT core; optional $29 one-time Pro. | No per-call meter |
| PDF Toolkit MCP | Free. | No per-call meter |
Estimate costs for the whole workflow, not a single tool call. An editing workflow can take several calls (upload, operation, a get_task_result poll, download, sometimes a retry), but distinguish tool calls from billable requests, since with Foxit, uploads, polling, downloads, and failed requests don’t consume credits.
A read-only server that retrieves only the relevant pages can also cut model input cost versus loading an entire PDF into context, given Anthropic estimates 1,500 to 3,000 text tokens per page for Claude’s native PDF processing.
Security considerations for agents running PDF tools
Treat external PDFs as untrusted input, since their text can contain instructions designed to manipulate an agent (prompt injection, OWASP LLM01). pdf-mcp flags hidden or injected text, but application-level safeguards are still needed.
MCP servers pose a separate risk too, since Invariant Labs demonstrated tool poisoning in April 2025, where malicious tool descriptions manipulate client behavior, and the MCP specification on tools calls for human oversight with the ability to deny tool invocations.
Require host-side approval for write operations until you trust the agent’s behavior, restrict accessible directories, document IDs, and tool permissions (Stirling PDF separates read and write scopes in OAuth mode), and test with unusual text, embedded objects, and long unstructured content before production.
The unauthenticated HTTP default and the public-link behavior of get_task_result noted in the Foxit entry above are exactly this kind of gap, the sort worth checking for on any server before connecting it to a pipeline that handles confidential documents.
Choosing a PDF MCP server
Match the server to the job, not the other way around. Reading and extraction are covered well by free, local, open-source options, so an agent that only answers questions about a PDF rarely needs a cloud account.
Editing, converting, and assembling documents narrows the field to a cloud API server, Stirling PDF, or a local toolkit like PDF Toolkit MCP; the choice then comes down to where content is allowed to go and whether certificate-based signing or a specific format matters.
Weigh data routing against convenience, since a hosted cloud endpoint needs nothing to install but sends file content off your infrastructure on every call, while a local or self-hosted server keeps data in place but puts you on the hook for running and securing it.
Check pricing against expected call volume too, since several calls per document (upload, operation, poll, download) can burn through a free allowance faster than a single-call estimate suggests.
For an agent that converts, assembles, and secures documents as part of a product workflow, cloud API coverage in one install is the deciding factor, and that’s where the Foxit PDF API MCP Server fits, with eSign and Document Generation available as separate integrations wrapped as custom tools when needed.
Plan for request limits as well as credits, since the sandbox allows 15 requests/minute and production allows 100/minute, including status checks and file requests.
Create a free Foxit developer account and follow the pinned @foxitsoftware/foxit-pdf-api-mcp-server package setup, confirming its authentication path against the current API reference.
PDF MCP server FAQs
Can Claude read PDFs without an MCP server?
Yes. Claude’s API accepts PDFs directly, up to 32 MB per request and 600 pages (100 when the context window is under 1M tokens), so a single-document question-answer task needs no server. Consider a server for larger files, folder search, encrypted documents the model can’t open, or workflows that produce a modified PDF.
Do PDF MCP servers work in ChatGPT and claude.ai?
Compatibility depends on the server, supported transport, and client plan or workspace restrictions; hosted Streamable HTTP with OAuth alone doesn’t guarantee support. CloudConvert’s docs cover ChatGPT and Claude connectors, and LlamaParse documents Claude connectors, but check the client’s requirements and test your setup. Local stdio servers need a locally running process and aren’t directly compatible with hosted chat interfaces.
Is there a free PDF MCP server?
Yes. pdf-mcp, anymd, Docling MCP, and PDF Toolkit MCP are free and open source with no per-call charges. Several cloud services, including Foxit’s, also offer free allowances; see the pricing table for limits and conditions.
Should you call the PDF API directly instead of through MCP?
Direct REST calls are often simpler for fixed pipelines, since they’re predictable, easy to test, and straightforward to monitor. Use MCP when the agent chooses operations, documents, or the next step at runtime based on intermediate results.
For more on these tradeoffs, see Building Auditable, AI-Driven Document Workflows with Foxit APIs.
How to Extract Parties, Dates, and Key Terms from Contracts Using the Foxit API

Renewal dates slip past when contract terms live in PDFs and spreadsheets. This tutorial shows you how to pull parties, dates, notice periods, and liability caps from a signed contract with the Foxit PDF Services API, then add the signing audit trail from Foxit eSign. You end up with one JSON record per contract, ready for a CLM, CRM, or renewal-alert script.
Most teams still handle contract metadata the same way they did a decade ago. Someone opens the signed PDF, copies the effective date and renewal terms into a spreadsheet, and hopes nobody forgets to check back before the notice period closes. When the process breaks down, it usually breaks down quietly. A regex script built for one contract template chokes on the next one, and a renewal date slips past unnoticed.
This tutorial builds a two-stage pipeline that gets the same information out of a contract programmatically. The first stage uses Foxit’s PDF Services API to extract structured content metadata (party names, dates, notice periods, liability terms) from a signed PDF. The second stage calls the Foxit eSign API’s activity history endpoint to pull the signing audit trail, so the final record captures both what the contract says and how it got signed. By the end, you’ll have one JSON object per contract that’s ready to feed into a CLM tool, a CRM, or a renewal-alert script, built from a real API response rather than a screen-scrape.
What contract metadata looks like in practice
Before writing any code, it helps to know what you’re building toward. The two API calls this tutorial makes run independently against the same signed PDF and merge into one record, as shown below.
The goal isn’t a wall of extracted text. It’s a small, typed record with the fields that actually drive downstream decisions:
{
"party_a": "Northwind Robotics",
"party_b": "Blue Harbor Analytics LLC",
"effective_date": "March 3, 2026",
"renewal_date": "March 3, 2028",
"termination_notice_days": 30,
"liability_cap": "$50,000"
} That’s the schema this tutorial targets. Everything downstream, a renewal-alert cron job, a query against a CLM database, a BI dashboard, consumes a record shaped like this. The contract’s prose is the source of truth, but the schema is what actually gets used. A structural extraction API gets you from one to the other without hand-writing a parser for every contract template your organization uses.
Prerequisites
You’ll need the following before starting:
- Python 3.8 or later, with pip for installing packages.
- A virtual environment tool such as venv (included with Python) to isolate this project’s dependencies.
- The requests library for making HTTP calls.
- A code editor. VS Code with the Python extension works well for this walkthrough.
- A free Foxit developer account. Sign up here. No credit card is required.
Set up your workspace:
mkdir contract-extraction && cd contract-extraction
python3 -m venv .venv
source .venv/bin/activate
pip install requests Those four commands create the project folder, create and activate an isolated virtual environment inside it, and install the one library this tutorial’s code depends on.
Authenticating with the Foxit PDF Services API
Once you’ve signed up for a free developer account, the sign-up flow provisions API credentials immediately. There’s no separate approval step.
When you sign in, your dashboard has a client_id and client_secret. The PDF Services API and DocGen API authenticate with these two values sent as request headers, with no OAuth token exchange required.
export FOXIT_CLIENT_ID="your_client_id"
export FOXIT_CLIENT_SECRET="your_client_secret" Foxit eSign, which this tutorial’s second stage uses to pull signing metadata, runs on a separate host with its own token-based authentication, and needs a one-time activation step from your dashboard (look for “Get started with eSign”) before its endpoints will accept calls. Activate it now so it’s ready by the time you reach that section; the eSign section below covers the token exchange itself.
For the full authentication reference, see the Foxit API docs, or try a call directly against the interactive API reference before writing any code.
Uploading a contract and calling the extraction endpoint
The extraction flow uses two calls, uploading the PDF to get a document ID, then posting that document ID to the structural extraction endpoint.
This tutorial uses a short sample NDA between two fictional companies, with a purpose clause, a term-and-renewal clause, a termination clause, a liability cap, and a key-dates summary table. It’s built to mirror the clause structure of a real commercial NDA.
Step 1: Upload the document
import os
import requests
BASE_URL = "https://na1.fusion.foxit.com"
HEADERS = {
"client_id": os.environ["FOXIT_CLIENT_ID"],
"client_secret": os.environ["FOXIT_CLIENT_SECRET"],
}
with open("nda_sample.pdf", "rb") as f:
upload_response = requests.post(
f"{BASE_URL}/pdf-services/api/documents/upload",
headers=HEADERS,
files={"file": ("nda_sample.pdf", f, "application/pdf")},
)
upload_response.raise_for_status()
document_id = upload_response.json()["documentId"]
print(document_id) In this code, you open the local PDF, POST it as multipart form data to the upload endpoint, and read back a documentId. That ID is a handle to the file inside Foxit’s system; every subsequent call in this pipeline references the document by this ID rather than re-uploading the file.
Run this command from your terminal:
python3 step1_upload.py The expected output should look like the following:
6ab519b2c7ca700694bf3174 Step 2: Call the structural extraction endpoint
The extraction call returns immediately with a taskId, and the client polls the task endpoint every two seconds until the status flips to COMPLETED, as shown below.
import time
extract_response = requests.post(
f"{BASE_URL}/pdf-services/api/documents/pdf-structural-extract",
headers={**HEADERS, "Content-Type": "application/json"},
json={"documentId": document_id},
)
extract_response.raise_for_status()
task_id = extract_response.json()["taskId"]
while True:
task_response = requests.get(f"{BASE_URL}/pdf-services/api/tasks/{task_id}", headers=HEADERS)
task = task_response.json()
print(task)
if task["status"] == "COMPLETED":
result_document_id = task["resultDocumentId"]
break
if task["status"] == "FAILED":
raise RuntimeError(task.get("error"))
time.sleep(2)
download_response = requests.get(
f"{BASE_URL}/pdf-services/api/documents/{result_document_id}/download",
headers=HEADERS,
)
with open("extraction_result.zip", "wb") as f:
f.write(download_response.content) This code starts the extraction as an asynchronous task, since structural analysis takes longer than a typical request-response cycle. It posts the documentId, gets back a taskId, then polls the task status endpoint every two seconds until the status flips to COMPLETED or FAILED. Once complete, the task response includes a resultDocumentId pointing at a ZIP archive, downloaded in the final step. On the sample NDA, this whole flow (upload, extract, poll, download) completes in well under ten seconds.
Run this command from your terminal:
python3 step2_extract.py The expected output should look like the following:
{'taskId': '6ab519d30a17a67b90dea85d', 'status': 'IN_PROGRESS', 'progress': 20}
{'taskId': '6ab519d30a17a67b90dea85d', 'status': 'COMPLETED', 'progress': 100, 'resultDocumentId': '6ab519d5316b427cfaec5212'} Unzip extraction_result.zip and, on this run, you get exactly two files. Run this command from your terminal:
unzip extraction_result.zip && ls The expected output should look like the following:
page_p0.pdf_0.png
StructureInfo.json That JSON is the real output of this article. Here’s an abbreviated version of what it actually contains, taken from the same live run against the sample NDA (the full StructureInfo.json from this run is available if you want to see every element):
{
"analyzeResult": {
"elements": [
{
"type": "title",
"content": { "text": "Mutual Non-Disclosure Agreement" },
"region": { "page": 1, "boundingBox": [142, 70, 470, 70, 470, 99, 142, 99] },
"id": "title1"
},
{
"type": "paragraph",
"content": {
"text": "This Mutual Non-Disclosure Agreement (the \"Agreement\") is entered into as of March 3, 2026 (the \"Effective Date\"), by and between Northwind Robotics, Inc., ... (\"Party A\"), and Blue Harbor Analytics LLC, ... (\"Party B\")."
},
"id": "paragraph1"
},
{
"type": "head",
"content": { "text": "2. Term and Renewal" },
"id": "head2",
"level": 1
},
{
"type": "table",
"content": {
"body": {
"rowCount": 6,
"columnCount": 2,
"cells": [
{ "paragraph": { "content": { "text": "Effective Date" } }, "rowIndex": 1, "columnIndex": 0 },
{ "paragraph": { "content": { "text": "March 3, 2026" } }, "rowIndex": 1, "columnIndex": 1 }
]
}
}
}
]
}
} The response is a flat list of elements, each carrying a type (title, head, paragraph, or table, among others) and the element’s content.text. For title, head, and paragraph elements, a region.boundingBox gives its position on the page. table elements don’t follow that shape, since their region is an empty object, and position instead lives in a plural regions array (alongside a plural scores array), so code that reads element["region"]["boundingBox"] generically across every element type raises a KeyError the moment it reaches a table. Paragraphs carry plain text; tables carry a content.body.cells array with rowIndex/columnIndex coordinates instead of a 2D array, since that’s the shape that survives merged cells and irregular tables cleanly. Every field name here comes directly from a real response; none of it is asserted from documentation alone.
Mapping the raw extraction response to a typed schema
StructureInfo.json describes the document’s structure. It doesn’t hand you party_a and effective_date directly, so the next step is a small amount of post-processing that turns the element list into the schema from the introduction.
import json
import re
import zipfile
with zipfile.ZipFile("extraction_result.zip") as z:
with z.open("StructureInfo.json") as f:
structure = json.load(f)
elements = structure["analyzeResult"]["elements"]
def normalize(text):
return " ".join(text.split())
paragraphs = [normalize(el["content"]["text"]) for el in elements if el["type"] == "paragraph"]
full_text = " ".join(paragraphs)
record = {}
match = re.search(r'([A-Z][\w\s,.]+?)\s*\("Party A"\)', full_text)
if match:
record["party_a"] = match.group(1).split(",")[0].strip()
match = re.search(r'([A-Z][\w\s,.]+?)\s*\("Party B"\)', full_text)
if match:
record["party_b"] = match.group(1).split(",")[0].strip()
match = re.search(r'as of\s+([A-Z][a-z]+ \d{1,2}, \d{4})', full_text)
if match:
record["effective_date"] = match.group(1)
match = re.search(r'expiring on\s+([A-Z][a-z]+ \d{1,2}, \d{4})', full_text)
if match:
record["renewal_date"] = match.group(1)
match = re.search(r'upon \w+ \((\d+)\) days.{0,10}prior written notice', full_text)
if match:
record["termination_notice_days"] = int(match.group(1))
match = re.search(r'\$([\d,]+)\)?\s*\(the "Liability Cap"\)', full_text)
if match:
record["liability_cap"] = f"${match.group(1)}"
print(json.dumps(record, indent=2)) This code reads the ZIP directly without extracting it to disk, then joins every paragraph element’s text into one searchable string. Because the raw text carries mid-string line breaks where a sentence wraps across a line in the source PDF, the normalize helper collapses any run of whitespace down to a single space before the string gets used, which is what keeps the regular expressions below from silently failing on a hidden newline. From there, a handful of targeted patterns pull out the fields this NDA’s clause language reliably contains, including the parenthetical ("Party A")/("Party B") labels this template uses to tag each signer, the “as of” and “expiring on” date phrases, the notice-period clause, and the dollar figure tagged (the "Liability Cap") in the liability clause. The liability clause writes the figure as fifty thousand dollars ($50,000) (the "Liability Cap"), so the regex allows an optional closing parenthesis between the digits and the label rather than assuming the label follows the number directly. Run against the sample NDA, this produces exactly the record shown in the introduction.
Run this command from your terminal:
python3 map_schema.py The expected output should look like the following:
{
"party_a": "Northwind Robotics",
"party_b": "Blue Harbor Analytics LLC",
"effective_date": "March 3, 2026",
"renewal_date": "March 3, 2028",
"termination_notice_days": 30,
"liability_cap": "$50,000"
} A production version of this would likely walk the table element’s cells too, since the sample NDA’s key-dates table restates the same fields in a much more parseable, label-value shape, but the paragraph-text approach shown here works even for contracts that don’t include a summary table.
Enriching the record with eSign audit metadata
The extraction above tells you what the contract says. It doesn’t tell you whether it’s actually been signed, or by whom, or when. That’s what Foxit eSign’s activity history endpoint adds, closing the loop between “here’s what the contract promises” and “here’s proof it was executed.”
eSign authenticates separately from PDF Services, with its own client ID and secret and its own token exchange. Find this pair by signing in to the eSign portal as the account owner, opening the account’s API settings page, and clicking “View All Credentials” (this is owner-gated and triggers a one-time email confirmation, so a non-owner login won’t see the button). Export them the same way you exported the PDF Services pair:
export FOXIT_ESIGN_CLIENT_ID="your_esign_client_id"
export FOXIT_ESIGN_CLIENT_SECRET="your_esign_client_secret" With those in place, exchange them for a bearer token:
esign_response = requests.post(
"https://na1.foxitesign.foxit.com/api/oauth2/access_token",
data={
"client_id": os.environ["FOXIT_ESIGN_CLIENT_ID"],
"client_secret": os.environ["FOXIT_ESIGN_CLIENT_SECRET"],
"grant_type": "client_credentials",
"scope": "read-write",
},
)
esign_response.raise_for_status()
esign_token = esign_response.json()["access_token"] This posts your eSign credentials as form-encoded data (not JSON) and gets back a bearer token, which every subsequent eSign call uses in an Authorization header. This is a separate credential pair and a separate token from the PDF Services calls above; see the eSign activation note in the “Authenticating with the Foxit PDF Services API” section above if you haven’t turned this on yet.
Sending the same credentials as a JSON body instead of data= is a real, reproducible mistake. Run this command from your terminal to reproduce it:
python3 -c "
import os, requests
r = requests.post(
'https://na1.foxitesign.foxit.com/api/oauth2/access_token',
json={
'client_id': os.environ['FOXIT_ESIGN_CLIENT_ID'],
'client_secret': os.environ['FOXIT_ESIGN_CLIENT_SECRET'],
'grant_type': 'client_credentials',
'scope': 'read-write',
},
)
print(r.status_code, r.reason)
" The expected output should look like the following:
415 Unsupported Media Type Sending the NDA for signature
The activity history endpoint only has something to report once a contract has actually gone out for signature, so this tutorial sends the same sample NDA through eSign to get a real folder ID to query. POST /api/folders/createfolder accepts the file directly as base64, which sidesteps hosting it somewhere with a public URL first:
import base64
with open("nda_sample.pdf", "rb") as f:
encoded_pdf = base64.b64encode(f.read()).decode("utf-8")
create_folder_response = requests.post(
"https://na1.foxitesign.foxit.com/api/folders/createfolder",
headers={"Authorization": f"Bearer {esign_token}"},
json={
"folderName": "nda_sample",
"inputType": "base64",
"base64FileString": [encoded_pdf],
"fileNames": ["nda_sample.pdf"],
"parties": [
{"partyNumber": 1, "name": "Alex Rivera", "email": "[email protected]"}
],
"sendNow": True,
},
)
create_folder_response.raise_for_status()
folder_id = create_folder_response.json()["folder"]["folderId"]
print(folder_id) This code base64-encodes the same nda_sample.pdf used in the extraction step and posts it to the folder-creation endpoint, along with inputType: "base64" (required whenever the file comes as base64 rather than a fileUrls array) and a single party to sign. sendNow: true dispatches the invitation immediately instead of leaving the folder in DRAFT, and the response nests the new folder’s ID at folder.folderId, which is the folder_id the next call reads.
Once a contract has actually been sent for signature, its activity history is available by folder ID:
history_response = requests.get(
f"https://na1.foxitesign.foxit.com/api/folders/viewActivityHistory?folderId={folder_id}",
headers={"Authorization": f"Bearer {esign_token}"},
)
history_response.raise_for_status()
activity = history_response.json()["details"]
print(json.dumps(activity, indent=2)) Called against a real folder right after sending it for signature, this is the actual response:
{
"folderId": 36096051,
"enclosedDocuments": "nda_sample",
"envelopeRecipients": "Alex Rivera",
"author": "annika annika",
"status": "SHARED",
"dateCreated": "24 Sep 2026, 02:48:35, PDT",
"dateSent": "24 Sep 2026, 02:48:35, PDT",
"activities": [
{
"activity": "annika annika created this folder",
"folderStatus": "CREATED",
"action": "Created",
"time": "24 Sep 2026, 02:48:35, PDT",
"source": "API"
},
{
"activity": "Invitation sent to Alex Rivera ( [email protected])",
"folderStatus": "SHARED",
"action": "Invitation Sent",
"time": "24 Sep 2026, 02:48:35, PDT",
"source": "Web"
}
]
} The endpoint refers to the contract’s signing container as a “folder” in the API’s own field names (folderId, folderStatus), even though the eSign portal’s UI labels the same thing an “envelope.” Both terms describe the same object; this article uses “folder” since that’s what the API actually returns. details.status tracks the folder’s lifecycle (SHARED once sent, moving through PARTIALLY SIGNED or COMPLETED as signers act, ending at EXECUTED once every signature is applied and finalized), and activities is an ordered log of every event with a timestamp and a source (API or Web, depending on how the action was triggered). Before you build this into a pipeline, know that this endpoint only works once a folder has actually been shared or sent. Calling it against a folder still in DRAFT status returns an error rather than an empty activity list, so don’t rely on it as a general-purpose status check before the folder is sent. Run this command from your terminal, pointed at a folder still in DRAFT status:
python3 view_activity_history.py The expected output should look like the following:
{"result": "error", "error_description": "logs of a non-shared folder can not be viewed."}
The final step merges this into the schema dict built earlier:
record["folder_status"] = activity["status"]
record["signing_activity"] = [
{"event": a["action"], "time": a["time"]} for a in activity["activities"]
]
print(json.dumps(record, indent=2)) That gives you one complete record per contract, its extracted terms and its signing history, in a single dict. Run this command from your terminal:
python3 merge_record.py The expected output should look like the following, using the same folder queried above:
{
"party_a": "Northwind Robotics",
"party_b": "Blue Harbor Analytics LLC",
"effective_date": "March 3, 2026",
"renewal_date": "March 3, 2028",
"termination_notice_days": 30,
"liability_cap": "$50,000",
"folder_status": "SHARED",
"signing_activity": [
{ "event": "Created", "time": "24 Sep 2026, 02:48:35, PDT" },
{ "event": "Invitation Sent", "time": "24 Sep 2026, 02:48:35, PDT" }
]
} With these three steps, you can turn any signed contract into a single record your downstream system can use: run the extraction, pull the audit trail, and merge the two.
Common mistakes
- Sending JSON to the eSign token endpoint : it requires form-encoded data (
data=, notjson=inrequests). A JSON body returns a 415 error. - Calling the activity history endpoint on a draft folder : it only works once the folder has been shared or sent; a draft returns an error instead of an empty result.
- Assuming
region.boundingBoxis a four-number rectangle : it’s an eight-number polygon (four corner point pairs), not[x, y, width, height]. - Reading
element["region"]["boundingBox"]on every element type without checkingtypefirst :tableelements carry an emptyregionobject and expose position throughregionsandscores(both plural) instead, so a generic per-element loop raises aKeyErrorthe moment it reaches a table. - Treating table cells as a 2D array : table content lives in
content.body.cells, a flat list withrowIndex/columnIndexon each cell, not a nestedrowsarray. - Skipping whitespace normalization before regex matching : paragraph text preserves the source PDF’s line wraps as literal characters mid-sentence, which breaks patterns that assume a single space between words.
Get started
The pipeline in this tutorial extracts what a contract says and proves how it was signed, in two API calls plus a lightweight mapping step, no regex-per-template maintenance burden and no manual copy-paste. Once you have a structured record per contract, the obvious next steps are automated renewal alerts before a notice period closes, obligation tracking against the liability and termination terms, and pushing the merged record straight into a BI dashboard or CLM system.
Create a free Foxit developer account, no credit card required, and run this extraction against one of your own contracts using the interactive API reference.
Contract metadata extraction FAQs
What is contract metadata extraction?
Contract metadata extraction is the process of pulling key details out of a contract, such as party names, effective dates, renewal dates, notice periods, and liability caps, and turning them into structured data. Instead of copying terms into a spreadsheet by hand, you get a typed record that feeds a CLM tool, a CRM, or a renewal-alert script.
What contract fields can I extract with the Foxit API?
You can extract any text the contract contains, including parties, effective and renewal dates, termination notice periods, and liability caps. The Foxit PDF Services API returns the document’s titles, headings, paragraphs, and tables as structured JSON. A short mapping step then turns that output into the exact fields your downstream system needs.
Do I need a separate parser for every contract template?
No. The structural extraction API returns the same JSON format for every PDF, so you don’t need to parse raw layouts for each template. You still map fields to your schema, usually with patterns tuned to your clause language. Contracts with a key-dates summary table are easier, since the table cells come back as label-value pairs.
How do I get the signing audit trail for a contract?
Call the Foxit eSign activity history endpoint with the contract’s folder ID. It returns the folder’s status and a timestamped log of every event, such as when the contract was created and when invitations went out. The endpoint only works after the folder has been shared or sent. A draft folder returns an error.
Can I try the Foxit API for free?
Yes. A free Foxit developer account gives you live API credentials right away, with no credit card and no approval step. The free plan includes 500 credits per year, which is enough to build and test a full contract metadata extraction pipeline. You can also test calls in the interactive API reference before writing code.
How to Extract Invoice Data from PDFs into Structured JSON

Invoice PDFs rarely follow one layout, so generic text extraction breaks on multi-column tables, wrapped cells, and scanned pages. This guide walks through the four API calls that convert a raw invoice PDF into typed JSON, plus the post-processing code that maps the response onto a clean invoice schema your backend can use right away.
Invoice PDFs are structurally unpredictable. Vendor A ships a five-column line-item table, vendor B embeds the same information in a paragraph block, and half the scanned copies in a legacy archive have no text layer at all. Generic text extraction reads characters in the order they were written to the file rather than the reading order a human sees, so field values drift with every layout variation.
The Foxit PDF Structural Extraction API, also known as the PDF Structural Analysis API, addresses this directly. You submit a PDF invoice and receive a typed, hierarchical JSON document with named element types, bounding regions, and an addressable table cell grid. This guide covers the four REST calls that turn a raw PDF into a StructureInfo.json file, the Python post-processing that maps that output onto a clean invoice schema, and the edge cases your pipeline will hit on real vendor documents. Every response shape and field name below comes from a live run against the API, not from the reference docs alone.
Why invoice PDFs break generic parsers
Three structural problems cause most invoice parsing failures, and OCR accuracy is only one of them.
The first is layout variance across vendors. A PDF’s text layer records characters in the order they were drawn, which often follows vector rendering order rather than left-to-right, top-to-bottom reading order. Extract raw text from a five-column line-item table and you frequently get interleaved fragments, where description text from one column mixes with unit prices from another because the writer rendered all rows of one column before moving to the next. No string-parsing logic reliably recovers column boundaries from that flattened sequence.
The second is merged and multi-row cells. Line-item tables routinely span cells across rows for items with multi-line descriptions. Text extraction collapses those cell boundaries into a flat string and drops the row-to-total relationship an accounting system needs.
The third is rasterized scans with no text layer. A PDF created by scanning a paper invoice contains only an embedded image, so anything that reads the text layer alone comes back empty. That kind of file has image data but no searchable text at all. Tools built for scanned input bundle an OCR step rather than skipping it, and any pipeline you build has to do the same before extraction can happen.
Structure-aware extraction addresses all three by classifying document regions into typed elements before exposing their content.
Invoice fields to target before touching the API
Define the target schema before writing code. A concrete target tells you which elements to read from StructureInfo.json and which to skip, which saves iteration time on every invoice you process.
A workable invoice schema covers three groups:
- Header fields, including vendor name, invoice number, invoice date, due date, and payment terms
- Line items, a repeating array of description, quantity, unit price, and line total
- Footer totals, including subtotal, tax amount, and total amount due
{
"vendor_name": "",
"invoice_number": "",
"invoice_date": "",
"due_date": "",
"payment_terms": "",
"line_items": [
{
"description": "",
"quantity": "",
"unit_price": "",
"line_total": ""
}
],
"subtotal": "",
"tax": "",
"total_due": ""
} Keep every value a string at extraction time. Type conversion, currency parsing, and date normalization belong downstream, after validation, where a bad value can be rejected with context instead of raising inside the parser.
The sample invoice used throughout this guide is invoice_full_test.pdf, so you can run every call below against the same document.
The input document. Notice that the Subtotal, Tax Rate, Tax Amount, and Total Due labels sit in the second-to-last column rather than the first. That detail determines how the post-processing code has to find them.
Prerequisites
You need the following before the first API call:
- Python 3.9 or newer and pip
- A virtual environment via venv, so the dependency below stays isolated
- The requests library for HTTP calls
- A code editor such as VS Code with the Python extension
- A free Foxit developer account
Scaffold the workspace in one shot:
mkdir invoice-extraction && cd invoice-extraction && python3 -m venv .venv && source .venv/bin/activate && pip install requests Then download the sample invoice into that folder:
curl -L -o invoice_full_test.pdf https://github.com/lucienchemaly/foxit-demo-templates/raw/main/invoice_full_test.pdf Foxit API authentication and setup
Signing up activates a free Developer plan that includes 500 credits per year with no credit card required. A structural extraction call costs one credit, while the upload, polling, and download calls are not billed, so a full run of the workflow below costs a single credit.
The account creation screen. The free Developer plan is enough to work through this entire guide.
Foxit authenticates PDF Services requests with a client ID and client secret passed as HTTP headers, so there is no OAuth token exchange to implement. Both values come from the default application created in your Developer Portal dashboard, alongside the base URL your calls need.
The credentials panel. Copy the Client ID and Client Secret into environment variables rather than pasting them into source files.
Export them into your shell so no credential is ever committed:
export FOXIT_CLIENT_ID="your_client_id"
export FOXIT_CLIENT_SECRET="your_client_secret" The structural extraction reference page carries a Test Request button that fires live calls straight from the browser, which is the quickest way to confirm your credentials work before writing any Python. The endpoint is currently labelled Trial in the reference, so expect its surface to evolve.
Pin your parser to the version field inside the analyzeResult response. The current schema ships as 1.0.7, and pinning prevents silent breakage if that changes.
The four-step PDF to JSON invoice extraction workflow
The API is asynchronous. You upload a document, start a task, poll until the task completes, then download the result.
All four paths sit under https://na1.fusion.foxit.com/pdf-services. Calling them without that prefix returns 404.
The path prefix matters more than it looks. The four endpoints live under /pdf-services/api/..., and requesting a bare /documents/{id}/download returns 404 rather than a helpful error.
import io
import json
import os
import time
import zipfile
import requests
BASE_URL = "https://na1.fusion.foxit.com/pdf-services"
HEADERS = {
"client_id": os.environ["FOXIT_CLIENT_ID"],
"client_secret": os.environ["FOXIT_CLIENT_SECRET"],
}
POLL_SECONDS = 2
POLL_TIMEOUT = 120
def extract_structure(pdf_path: str) -> dict:
# Step 1: upload the PDF (multipart/form-data, 100 MB maximum)
with open(pdf_path, "rb") as handle:
upload = requests.post(
f"{BASE_URL}/api/documents/upload",
headers=HEADERS,
files={"file": (os.path.basename(pdf_path), handle, "application/pdf")},
)
upload.raise_for_status()
document_id = upload.json()["documentId"]
# Step 2: start the structural extraction task
started = requests.post(
f"{BASE_URL}/api/documents/pdf-structural-extract",
headers=HEADERS,
json={"documentId": document_id},
)
started.raise_for_status()
task_id = started.json()["taskId"]
# Step 3: poll until COMPLETED, bounded, and handle FAILED
deadline = time.monotonic() + POLL_TIMEOUT
while True:
response = requests.get(f"{BASE_URL}/api/tasks/{task_id}", headers=HEADERS)
response.raise_for_status()
task = response.json()
if task["status"] == "COMPLETED":
break
if task["status"] == "FAILED":
raise RuntimeError(f"extraction task {task_id} FAILED: {task}")
if time.monotonic() > deadline:
raise TimeoutError(f"task {task_id} stuck at {task['status']}")
time.sleep(POLL_SECONDS)
# Step 4: download the result ZIP and read StructureInfo.json
result = requests.get(
f"{BASE_URL}/api/documents/{task['resultDocumentId']}/download",
headers=HEADERS,
)
result.raise_for_status()
with zipfile.ZipFile(io.BytesIO(result.content)) as archive:
return json.loads(archive.read("StructureInfo.json")) This code:
- Reads both credentials from the environment.
- Uploads the PDF as multipart form data and captures the returned
documentId. - Hands that id to the extraction endpoint to receive a
taskId. - Polls the task endpoint every two seconds, bounded by a deadline, checking explicitly for
FAILEDso a rejected document raises instead of spinning forever. - Once the status reads
COMPLETED, downloads the ZIP archive using the task’sresultDocumentIdand readsStructureInfo.jsonout of it in memory.
A real run against the sample invoice. The task reports IN_PROGRESS at 20 percent before reaching COMPLETED, and the final object carries every field from the schema defined earlier.
How to map raw output to a clean invoice schema
Choosing an invoice data extraction API is only half the work. The other half is mapping whatever it returns onto a schema your backend already understands, and that mapping is where the shape of the response starts to matter.
StructureInfo.json wraps everything in an analyzeResult object with four top-level keys, version, pages, info, and elements. The elements array is where the work happens. Each element carries a type drawn from twelve values, including paragraph, table, title, image, form, and formula, along with its bounding region and content. The same API can also extract embedded images as standalone image files, in addition to returning them as typed image elements within StructureInfo.json.
Two details in that structure cause most of the bugs in a first implementation, and neither is obvious from the field names.
The actual response shape from a live extraction. A table’s cells are nested at content.body.cells, cell text sits at paragraph.content.text, and region.boundingBox is an eight-number polygon rather than an x, y, width, height rectangle.
A table element does not expose a top-level cells array. Its grid is nested at content.body.cells, where each cell carries rowIndex, columnIndex, and a paragraph object. Cell text then sits one level deeper still, at paragraph.content.text, because content is an object rather than a string. Reaching for cell["paragraph"]["content"] returns a dict, not the text you want.
Blank cells are the second detail. When a vendor leaves a cell empty, the API still returns the cell with its indices and a paragraph object, but that paragraph has no content key at all. An unguarded read raises KeyError partway through a document that looked fine in testing.
def element_text(element: dict) -> str:
"""Return an element's text, or an empty string when it carries none."""
text = element.get("content", {}).get("text", "")
return " ".join(text.split())
def cell_text(cell: dict) -> str:
"""Return a table cell's text, or an empty string when the cell is blank."""
return element_text(cell.get("paragraph", {})) In this code, element_text reads the nested content.text value and normalizes its whitespace, which matters because cell text can contain a literal \r\n where a label wraps across two lines. Using " ".join(text.split()) collapses those into single spaces, whereas .strip() leaves a mid-string newline untouched. cell_text then reuses that helper for table cells, returning an empty string for a blank cell instead of raising.
With the accessors in place, build a grid and read it row by row.
import re
FOOTER_LABELS = ("subtotal", "tax rate", "tax amount", "tax", "total due", "total")
HEADER_PATTERNS = {
"vendor_name": r"bill to:\s*(.+)",
"invoice_number": r"invoice number:\s*(.+)",
"invoice_date": r"invoice date:\s*(.+)",
"due_date": r"due date:\s*(.+)",
"payment_terms": r"payment is due within (.+?) of",
}
def parse_invoice(structure_info: dict) -> dict:
elements = structure_info["analyzeResult"]["elements"]
invoice = {key: "" for key in HEADER_PATTERNS}
invoice.update(line_items=[], subtotal="", tax="", total_due="")
# Header fields come from paragraph elements above the table
for element in elements:
if element["type"] != "paragraph":
continue
text = element_text(element)
for field, pattern in HEADER_PATTERNS.items():
match = re.search(pattern, text, re.IGNORECASE)
if match and not invoice[field]:
invoice[field] = match.group(1).strip()
tables = [element for element in elements if element["type"] == "table"]
if not tables:
return invoice
grid: dict = {}
for cell in tables[0]["content"]["body"]["cells"]:
grid.setdefault(cell["rowIndex"], {})[cell["columnIndex"]] = cell_text(cell)
# Resolve columns from the header row instead of assuming positions
columns = {name.lower(): index for index, name in grid.get(0, {}).items() if name}
def column_for(*candidates, default):
for candidate in candidates:
for name, index in columns.items():
if candidate in name:
return index
return default
description_col = column_for("description", "item", default=1)
quantity_col = column_for("qty", "quantity", default=2)
unit_price_col = column_for("unit price", default=3)
line_total_col = column_for("total", "amount", default=4)
for row_index in sorted(index for index in grid if index > 0):
row = grid[row_index]
label = next(
(value.lower().rstrip(":").strip() for value in row.values()
if value.lower().rstrip(":").strip() in FOOTER_LABELS),
None,
)
if label:
value = row[max(row)]
if label == "subtotal":
invoice["subtotal"] = value
elif label == "tax amount":
invoice["tax"] = value
elif label in ("total due", "total"):
invoice["total_due"] = value
continue
if row.get(description_col):
invoice["line_items"].append({
"description": row.get(description_col, ""),
"quantity": row.get(quantity_col, ""),
"unit_price": row.get(unit_price_col, ""),
"line_total": row.get(line_total_col, ""),
})
return invoice In this code, you first walk the paragraph elements and pull header fields out with labelled regular expressions, which works because Foxit exposes each header line as its own element with its reading order preserved. You then flatten the table into a {rowIndex: {columnIndex: text}} grid and resolve column positions from the header row by name, so a vendor who adds a leading row-number column does not shift every field by one. Each subsequent row is classified before it is read, so that if any cell in the row matches a known footer label the row is treated as a total and its value taken from the last populated column, and otherwise the row becomes a line item. Scanning the whole row for the label is the part that matters, because footer labels do not sit in the first column.
Footer totals living inside the line-item table is convenient rather than awkward, since one pass over the cell grid covers line items and totals together. Form elements do not appear on a typical invoice, so there is no need to look for them.
Before and after
The two blocks below show the same data on either side of that mapping. First, one real cell exactly as the API returns it, taken verbatim from the run above:
{
"paragraph": {
"type": "paragraph",
"content": {
"text": "API Integration\r\nConsulting"
},
"region": {
"page": 1,
"boundingBox": [171, 300, 258, 300, 258, 328, 171, 328]
},
"id": "paragraph12",
"paragraphOrder": 12
},
"rowSpan": 1,
"columnSpan": 1,
"rowIndex": 1,
"columnIndex": 1,
"region": {
"page": 1,
"boundingBox": [171, 300, 258, 300, 258, 328, 171, 328]
},
"score": 0.8555269837379456
} That fragment is the shape of every cell you will handle. The text is nested at paragraph.content.text rather than sitting directly on the cell. The position arrives as an eight-number boundingBox polygon on both the cell and its paragraph, not as a rectangle. And the value itself contains a literal \r\n where the description wrapped onto a second line in the source table, which is the case .strip() silently fails to clean.
Second, the complete object parse_invoice returns for the whole document, which is what your backend actually consumes:
{
"vendor_name": "Acme Corporation",
"invoice_number": "INV-2025-0042",
"invoice_date": "07/15/2025",
"due_date": "08/14/2025",
"payment_terms": "30 days",
"line_items": [
{
"description": "API Integration Consulting",
"quantity": "8",
"unit_price": "$ 195.00",
"line_total": "$1,560.00"
},
{
"description": "Document Automation Setup",
"quantity": "1",
"unit_price": "$ 750.00",
"line_total": "$ 750.00"
}
],
"subtotal": "$2,310.00",
"tax": "$ 184.80",
"total_due": "$2,494.80"
} The wrapped description has become the single clean string "API Integration Consulting", the header fields have been lifted out of the paragraph elements above the table, and the four footer rows have been separated from the two genuine line items. That output is backend-ready, so you can write it straight to a database, push it to a reporting pipeline, or validate it against an accounts-payable schema without further parsing.
Common mistakes
- Dropping the path prefix. All four endpoints sit under
/pdf-services/api/.... A bare/documents/{id}/downloadreturns 404. - Reading
cellsoff the table element. The grid is nested atcontent.body.cells. A top-levelcellslookup raisesKeyError. - Treating
paragraph.contentas a string. It is an object, so the text is atparagraph.content.text. - Assuming footer labels are in column 0. On real invoices they commonly sit in the second-to-last column, with the value beside them.
- Forgetting blank cells. A blank cell keeps its
paragraphobject but carries nocontentkey. - Polling without a bound. A
FAILEDtask never becomesCOMPLETED, so an unboundedwhile Trueloop hangs. - Trusting
info.basicInfo.elementCounts. It can disagree with the length of theelementsarray, so size loops from the array itself. - Using
.strip()to clean cell text. A wrapped label contains a mid-string\r\nthat.strip()leaves in place. Use" ".join(text.split()).
Invoice parsing FAQ
What is invoice data extraction from PDF?
Invoice data extraction from PDF is the programmatic conversion of semi-structured PDF invoice content into a schema-typed data object. The source can be a digital-native PDF with an embedded text layer or a scanned image-only PDF that needs OCR first. The output is a structured record, typically JSON, with typed fields for header values, line items, and totals that downstream systems consume without manual parsing.
How do I extract line items from a PDF invoice?
Line items live in table elements inside StructureInfo.json. Read the grid from content.body.cells, where every cell carries a rowIndex and columnIndex, build a {rowIndex: {columnIndex: text}} dictionary, resolve the column positions from the header row, then read each data row in column order. Classify rows before reading them so footer totals are not appended as line items.
Can an extraction API handle scanned PDF invoices?
The PDF Structural Extraction API expects a PDF that already has a text layer. Tested against an image-only PDF, it returns no text and an empty table rather than an error. To handle scans, run the document through Foxit’s OCR endpoint first (POST /pdf-services/api/documents/analyze/pdf-ocr with outputFormat set to PDF), then pass the OCR output through the four-step workflow. That makes five calls rather than four, and the OCR step is billed as its own credit.
What does the JSON output from PDF invoice extraction look like?
The downloaded ZIP unpacks to StructureInfo.json, holding an analyzeResult object with version, pages, info, and elements keys. The elements array carries every classified region, each with a type drawn from twelve values. A table element nests its grid at content.body.cells, and each cell’s text sits at paragraph.content.text.
Why build a grid instead of iterating the cells array directly?
A grid keyed by row and column decouples your field mapping from the order the API happens to return cells in, and it lets you address a specific position directly, which is what the footer-label check needs. It also makes missing cells visible as absent keys rather than as silently shifted values.
What element types does the API classify?
The API classifies regions into twelve element types, including paragraph, table, title, image, form, and formula. On a typical invoice, paragraph elements carry the header fields while a single table element carries both line items and footer totals, so filtering by type lets you target only what your schema needs.
How should I handle invoices where footer totals sit outside the line-item table?
Some layouts place totals in a separate table element or in standalone paragraph elements below the main table. Keep the row-classification logic in its own function so you can apply it to a second table element, then fall back to scanning paragraph elements for currency-formatted strings next to known label text.
Wrapping up
The four-step workflow of upload, extract, poll, and download produces a typed, hierarchical JSON document from any digital-native invoice PDF. Post-processing the elements array through a row and column grid turns that into a clean invoice object your backend can consume directly. The same four calls extend to purchase orders, receipts, and any other tabular financial document, with only the mapping logic changing to match the target schema.
The Foxit PDF Structural Extraction API is part of the broader Foxit PDF Services API, which covers conversion, compression, OCR, and other document operations under the same credential set. The infrastructure is SOC 2 Type II certified, with GDPR-supporting features and HIPAA-aligned controls including BAA availability, which matters for teams processing financial documents under compliance review.
The complete script from this guide is available as extract_invoice.py if you want to run it before adapting it.
Create your free developer account and start turning invoice PDFs into structured JSON today. No credit card required, and the 500 credits on the free Developer plan are enough to build and test something real.
How Foxit compares to Google Document AI for document data extraction

Seven Google Document AI processors are being retired in June 2026, pushing teams to look at alternatives. This comparison walks through integration setup, extraction architecture, output schema, and data residency for Foxit’s PDF Structural Extraction API against Google Document AI, so you can decide with real implementation detail instead of a feature list.
Seven Google Document AI processors hit end-of-life on 30 June 2026. Google is retiring the Enterprise Document OCR, Expense, Custom classifier, Custom splitter, Invoice, Pay slip, and Bank statement parsers, and processor versions follow a rolling schedule where each version is deprecated six months after a newer one ships.
For many teams, the deprecation notice does more than prompt a migration ticket. It opens a broader question about whether Google Document AI is still the right foundation for the extraction stack, and what the credible Google Document AI alternatives actually look like once you compare them on implementation detail rather than feature lists.
This article gives you the technical specifics to make that call, comparing the Foxit PDF Structural Extraction API and Google Document AI across five dimensions that drive the real build-vs-switch decision, covering integration overhead, extraction architecture, output schema, document and language coverage, and data residency.
Five axes for evaluating Google Document AI alternatives
Any extraction API comparison lives or dies on the criteria it uses. These five dimensions cover what a production engineering team actually cares about, going well beyond a proof-of-concept benchmark.
Integration complexity measures how many external dependencies you must provision before your first call returns data. A tool that requires a GCP project, service account, IAM role grants, and billing enablement adds meaningful friction before a single byte of document gets processed. For teams with CI/CD pipelines and strict access-control policies, every new cloud dependency is a potential blocker.
Extraction architecture covers how the API reads a document internally, including what happens when a file mixes scanned pages, machine-typed text, and embedded tables in the same document.
Output schema determines how much post-processing your downstream systems require. A flat token list forces you to reconstruct document structure yourself, while a pre-labeled semantic taxonomy reduces that burden before the data reaches your RAG pipeline or BI dashboard.
Document and language coverage sets the practical ceiling on what you can run through the API in production. Language breadth matters especially for multi-region workloads processing invoices or contracts in non-Latin scripts.
Data residency encompasses where documents travel during processing, how long they remain on third-party infrastructure, and what audit evidence you can produce for compliance reviews. For regulated industries, this dimension often decides the question before the others are evaluated.
Integration setup and authentication overhead
Getting to a first call on Google Document AI requires a GCP project, a service account with an IAM role assignment (at minimum roles/documentai.apiUser), billing enablement on the project, and an environment variable pointing to a downloaded service account JSON key. Teams outside the GCP ecosystem absorb all of that as onboarding cost before any extraction runs.
Foxit’s path is shorter. Create a free developer account at the Foxit Developer Portal, retrieve your client_id and client_secret from the default application, and attach them as two HTTP headers on every request. The entire setup takes minutes and requires nothing from GCP.
Prerequisites
To run the code below you need Python 3.8+, the requests library installed into an isolated virtual environment with pip, an editor such as VS Code with the Python extension (PyCharm or Sublime Text work equally well), and a free Foxit developer account from app.developer-api.foxit.com/sign-up to supply the two credential values. Scaffold the workspace in one shot:
mkdir foxit-extract && cd foxit-extract && python3 -m venv .venv && source .venv/bin/activate && pip install requests Extraction then follows a four-step asynchronous workflow, annotated at each step:
export FOXIT_CLIENT_ID="your_client_id"
export FOXIT_CLIENT_SECRET="your_client_secret" Extraction then follows a four-step asynchronous workflow, annotated at each step:
import os
import requests
import time
BASE_URL = "https://na1.fusion.foxit.com/pdf-services/api"
HEADERS = {
"client_id": os.environ["FOXIT_CLIENT_ID"], # lowercase snake_case, not Authorization: Bearer
"client_secret": os.environ["FOXIT_CLIENT_SECRET"]
}
# Step 1: Upload the document (multipart/form-data, field name "file", max 100 MB)
with open("contract.pdf", "rb") as f:
upload_resp = requests.post(
f"{BASE_URL}/documents/upload",
headers=HEADERS,
files={"file": f}
)
document_id = upload_resp.json()["documentId"]
# Step 2: Start structural extraction
extract_resp = requests.post(
f"{BASE_URL}/documents/pdf-structural-extract",
headers=HEADERS,
json={"documentId": document_id}
)
task_id = extract_resp.json()["taskId"]
# Step 3: Poll every 2 seconds until COMPLETED (statuses are uppercase)
result_doc_id = None
for _ in range(60):
status_resp = requests.get(
f"{BASE_URL}/tasks/{task_id}",
headers=HEADERS
)
payload = status_resp.json()
if payload["status"] == "COMPLETED":
result_doc_id = payload["resultDocumentId"]
break
if payload["status"] == "FAILED":
raise RuntimeError(f"Extraction failed: {payload}")
time.sleep(2)
if result_doc_id is None:
raise TimeoutError("Extraction did not complete within 120 seconds")
# Step 4: Download the ZIP archive containing StructureInfo.json
result_resp = requests.get(
f"{BASE_URL}/documents/{result_doc_id}/download",
headers=HEADERS
)
with open("extraction_result.zip", "wb") as out:
out.write(result_resp.content) Authentication uses lowercase snake_case header names on every call. The upload endpoint accepts multipart/form-data with the PDF file under the field name file, with a 100 MB size limit per document.
The four calls against the live API. Note the 202 on the extract call and the COMPLETED status before any download is attempted.
The response shape from that run. Every element sits under analyzeResult, and text elements carry region.boundingBox as an eight-number polygon rather than a four-number rectangle. A table element is the exception, since its region comes back empty and its geometry sits in a regions array instead.
The table below puts both platforms side by side on the integration and output dimensions:
| Dimension | Google Document AI | Foxit PDF Structural Extraction API |
|---|---|---|
| Account setup | GCP project, service account, IAM role, billing | Free developer account, no credit card |
| Authentication | Service account JSON key via GOOGLE_APPLICATION_CREDENTIALS | client_id and client_secret as HTTP headers |
| Call pattern | Synchronous or async depending on processor | Four-step async (upload, extract, poll, download) |
| Output format | Document proto (blocks, paragraphs, tokens) | StructureInfo.json with 12 semantic element types |
| Cloud dependency | GCP-native; Vertex AI integration available | Cloud-agnostic, any stack |
| Language coverage | Varies by processor | 200+ languages via dedicated OCR layer |
Common mistakes and troubleshooting
Four failure modes account for most of the time lost on a first integration. Only the first one reports itself clearly; the other three surface as exceptions in your own code rather than as API errors.
- Sending an
Authorization: Bearerheader : PDF Services authenticates with two separate lowercase headers,client_idandclient_secret. There is no token exchange step and no OAuth flow to implement. This is the one mistake the API names outright, returning HTTP 400 with{"allow": false, "reason": "Missing credentials: provide both 'client_id' and 'client_secret' headers."}. - Treating the extract call as synchronous :
pdf-structural-extractreturns HTTP 202 with ataskId, never the result. Read the status fromGET /tasks/{taskId}, which also returns aprogresspercentage, and note that the values are uppercase (PENDING,IN_PROGRESS,COMPLETED,FAILED). Comparing against lowercase strings produces a poll loop that never exits, which is why the sample above also breaks out onFAILEDand caps its attempts. - Reading
region.boundingBoxon every element : text elements such astitle,head, andparagraphcarryregionas{page, boundingBox}, but atableelement returns an emptyregionand puts its geometry in aregionsarray instead. A loop that assumes one shape raisesKeyErroron the first document containing a table. - Indexing
elementsat the JSON root : every result nests underanalyzeResult, sodata["elements"]raisesKeyErrorwhiledata["analyzeResult"]["elements"]works. The same applies to uploads above the 100 MB per-document limit, which fail at the upload step rather than during extraction.
Extraction architecture, output format, and document coverage
Google Document AI’s processing model is processor-centric. You select a processor type (Invoice Parser, Form Parser, Document OCR), and the service returns a Document proto containing position-anchored blocks, paragraphs, and tokens. Semantic meaning depends on which processor you deployed, so a Form Parser and an Invoice Parser return structurally similar protos but with different field-level annotations.
Foxit’s PDF Structural Extraction API runs three coordinated layers on every document, regardless of document type. The OCR layer handles rasterized content across more than 200 languages. The layout recognition layer maps spatial relationships and table cell grids, resolving multi-column text blocks, overlapping text-image regions, stamped signatures on top of text fields, and engineering drawing annotations. The AI parsing layer then classifies content semantically, assigning each element a type from a fixed taxonomy of twelve labels.
The rendered pipeline. Every document takes the same path, so there is no processor to choose per document type.
Those twelve types appear in StructureInfo.json inside the returned ZIP archive, covering title, head, paragraph, table, image, headerFooter, form, hyperlink, footnote, sidebar, annotation, and formula. Each element carries its reading-order position and spatial coordinates, so the structure your downstream system receives reflects how a human would read the original document rather than raw storage order.
The practical delta shows up in RAG pipeline integration. Google Document AI’s Document proto gives you text and coordinates, but your pipeline needs a post-processing step to decide what each block means semantically. With StructureInfo.json, you filter to table elements, iterate rows, and pass the content directly to your embedding model, because the semantic classification happened upstream.
The output schema comparison below clarifies where each platform puts the interpretive work:
| Schema dimension | Google Document AI (Document proto) | Foxit (StructureInfo.json) |
|---|---|---|
| Structure model | Hierarchical, covering pages, blocks, paragraphs, and tokens | Flat list of semantically typed elements with spatial metadata |
| Semantic labels | Field-level labels tied to specific processor selection | 12 fixed element types, processor-independent |
| Table representation | Cell tokens within a table block | Dedicated table element type with cell grid coordinates |
| Reading order | Implicit (coordinate ordering required client-side) | Explicit, preserved in element sequence |
| Formula support | Limited | Dedicated formula element type |
Document coverage on both platforms is broad. Foxit processes scanned PDFs, image-based PDFs, multi-page contracts, invoices, and form-heavy documents. The layout layer handles edge cases that trip up simpler OCR tools, including stamped signatures overlapping text fields, mixed raster-vector pages, and footnote regions that appear spatially disconnected from their reference markers.
Data privacy and ecosystem independence
Regulated workloads ask two questions before any technical evaluation, starting with where the document goes and what audit evidence you can produce.
Foxit’s API compliance page documents SOC 2 Type II independent audit, HIPAA-aligned features with Business Associate Agreement (BAA) support, and GDPR-supporting features including redaction, anonymization, and secure metadata handling. Foxit’s AI service documentation states that input documents and results are held temporarily and deleted within 24 hours. If your organization requires a BAA, Foxit can provide one.
Google Document AI routes all processing through GCP infrastructure. Teams subject to data residency requirements need to select the appropriate GCP region, review Google’s data processing addendum, and confirm their cloud agreement covers the specific data types being processed. That review is standard for teams already operating within GCP, but it adds a compliance surface for teams that are not.
Foxit’s API is cloud-agnostic. Your team calls it from any existing stack, passing two credential headers, and extracts documents without spinning up a GCP project, provisioning a storage bucket, or accepting GCP billing terms. For teams evaluating outside GCP, that independence cuts both technical and commercial risk from the decision.
When to use Google Document AI and when to use Foxit
The right choice depends on your existing infrastructure and what your extraction output needs to do.
| Scenario | Best fit | Key reason |
|---|---|---|
| Teams already deep in GCP who want Vertex AI integration | Google Document AI | Native Vertex AI pipeline support and Google-managed processor versions reduce ops overhead |
| High-volume PDF processing outside the GCP ecosystem | Foxit | Cloud-agnostic with credit-based pricing, with no GCP billing or IAM dependency |
| Workloads with strict data residency or BAA requirements | Foxit | SOC 2 Type II audit, HIPAA-aligned features with BAA support, and GDPR-supporting features |
| Teams that need semantic element classification ready for downstream consumption | Foxit | StructureInfo.json delivers 12 pre-labeled element types without a client-side post-processing step |
The fourth scenario is worth walking through in detail. Your team has a contract review pipeline that needs to extract all tables and footnotes from multi-page PDFs and push them into a downstream system. With the Foxit API, the workflow runs like this:
- Upload the PDF to
/pdf-services/api/documents/uploadand receive adocumentId. - POST to
/pdf-services/api/documents/pdf-structural-extractwith thedocumentIdand receive ataskId. - Poll
/pdf-services/api/tasks/{taskId}every two seconds untilstatusequalsCOMPLETED. - Download the result ZIP from
/pdf-services/api/documents/{resultDocumentId}/downloadand parseStructureInfo.json.
Once you have StructureInfo.json, filtering to table and footnote elements is a single-pass list comprehension. The labeled elements arrive with spatial coordinates and reading order intact, so your downstream system receives structured, ordered data ready for indexing, embedding, or display, with no second model call, no coordinate sorting, and no block-level classification required.
Teams running active Vertex AI pipelines in GCP, with processors not among the seven being retired, have no technical reason to switch. For everyone else, the four API calls above give you a working extraction against your own documents in minutes.
Google Document AI FAQ
What is Google Document AI?
Google Document AI is a managed cloud service for document parsing and data extraction, built on GCP processors. You select a processor type (such as Invoice Parser, Form Parser, or Document OCR), send a document via the API, and receive a structured Document proto containing text, coordinates, and field-level annotations. All processing runs on Google Cloud Platform infrastructure.
How does the Foxit PDF Structural Extraction API differ from Google Document AI?
Foxit’s API runs three coordinated processing layers on every document (OCR, layout recognition, and AI parsing) regardless of document type, while Google Document AI uses a processor model where semantic classification depends on the specific processor you select. The output schemas also differ. Foxit returns StructureInfo.json inside a ZIP archive with twelve pre-labeled element types preserving reading order and spatial relationships, while Google Document AI returns a Document proto with hierarchical blocks, paragraphs, and tokens that require client-side semantic interpretation. Foxit is also cloud-agnostic and needs no GCP project, while Google Document AI is GCP-native.
What are Foxit’s data-handling and compliance commitments for the extraction API?
Foxit’s API compliance page documents SOC 2 Type II independent audit, HIPAA-aligned features with Business Associate Agreement (BAA) support, and GDPR-supporting features including redaction, anonymization, and secure metadata handling. Foxit’s AI service documentation states that input documents and results are held temporarily and deleted within 24 hours. Foxit does not claim HIPAA certification or GDPR certification, and the API compliance page does not state that documents are never stored, so teams with specific retention requirements should review the documentation directly and request a BAA where applicable.
What output format does the Foxit PDF Structural Extraction API return?
The API returns a ZIP archive containing StructureInfo.json. That file classifies every element in the document using one of twelve labeled types, including title, head, paragraph, table, image, headerFooter, form, hyperlink, footnote, sidebar, annotation, and formula. Each element includes spatial coordinates and reading-order position, so the structure your downstream system receives reflects how a human would read the original document. Table elements carry cell grid coordinates, making row-level data extraction straightforward without additional parsing.
Can I try the Foxit PDF Structural Extraction API without a paid plan?
Yes. Create a free developer account at app.developer-api.foxit.com/sign-up. No credit card is required. Once you register, your client_id and client_secret are available immediately in the Developer Portal, and you can run extractions against your own documents using the API Playground or the downloadable Postman collection.
How does Foxit handle scanned or image-based PDFs?
Foxit’s OCR layer processes rasterized content across more than 200 languages, so scanned PDFs and image-based documents (including TIFFs) are processable without pre-conversion. The layout recognition layer then maps spatial relationships and resolves edge cases such as multi-column text blocks, overlapping text-image regions, and footnote regions that appear spatially disconnected from their reference markers.
Which document types does Google Document AI support after the June 2026 deprecations?
After 30 June 2026, Google is retiring the Enterprise Document OCR, Expense, Custom classifier, Custom splitter, Invoice, Pay slip, and Bank statement processors. Remaining processors (including Form Parser and Document OCR for non-deprecated versions) continue to operate on their own rolling deprecation schedule, where each version is deprecated six months after a newer one ships. Teams relying on any of the seven retired processors need to migrate before that date.
Conclusion
Across all five axes, the practical difference between Google Document AI alternatives comes down to how much infrastructure you take on to reach a first result. Foxit requires two credential headers. Google’s setup adds a GCP project, service account, IAM configuration, and billing enablement before you process a single document. Foxit’s three-layer extraction model (OCR, layout recognition, AI parsing) delivers semantic classification across every document type without processor selection. StructureInfo.json‘s twelve labeled element types reduce client-side post-processing compared to Google’s Document proto. Both platforms handle the major document types, and Foxit’s 200-plus language OCR covers non-Latin scripts across all document categories. Foxit’s SOC 2 Type II audit, HIPAA-aligned BAA support, and GDPR-supporting features give regulated teams a documented compliance baseline, and the cloud-agnostic model means your team runs document extraction without taking on GCP billing, IAM governance, or ecosystem lock-in.
Create a free developer account at app.developer-api.foxit.com/sign-up, no credit card required, and run the four-step extraction against your own document today.
How to Turn PDFs into Structured Data with Foxit’s PDF Structural Extraction API

PDF data extraction with Foxit’s Structural Extraction API turns messy invoices and tables into typed JSON, complete with bounding regions and addressable cells. This tutorial walks through the four REST calls, upload, extract, poll, and download, and shows working Python code that builds a clean dictionary from an invoice’s line items. It also covers common mistakes like case-sensitive auth headers and stale document IDs.
Pull text out of a multi-column invoice and you get a flat string with column headers mixed into values, row boundaries gone, and field labels indistinguishable from the data they describe. Foxit’s PDF Structural Extraction API returns typed JSON instead, where every element carries a type, its text, a bounding region, and, for tables, an addressable grid of cells.
This tutorial walks the four REST calls that get you there, uploading a PDF, starting the analysis, polling the task, and downloading the result. By the end you’ll have working Python code that turns an invoice into a dictionary your pipeline can address by key.
Raw text vs. structured extraction
What separates raw text extraction from structured extraction is the shape of the output, not the accuracy of the characters.
Take a vendor invoice with a line-item table covering description, quantity, and unit price. Text extraction returns something like "1 API Integration Consulting 10 $ 150.00 $1,500.00". The content is all there, but the row and column relationships are gone, so your parsing code has to reconstruct structure the PDF already encoded, and it has to do that differently for every layout you encounter.
Structured extraction preserves what raw text discards. The pdf-structural-extract endpoint returns each element with a type, a content object holding the text and its font styling, and a region giving the page number and bounding polygon. Tables come back as a cell grid with explicit rowIndex and columnIndex values, so a cell’s position is data rather than something you infer from coordinates.
Prerequisites
- Python 3.8+ with pip and a virtual environment via venv.
- The requests library for the HTTP calls.
- curl if you want to try the endpoints before writing code.
- A code editor, VS Code with the Python extension is a good default, though PyCharm or Sublime Text work equally well.
- A Foxit Developer account, free with no credit card, created at app.developer-api.foxit.com/sign-up. Activate the Developer plan (500 credits per year) and copy the Client ID and Client Secret from the APIs Dashboard.
- A sample PDF, so you do not have to build one. This tutorial uses invoice_table_test.pdf, a one-page invoice with a five-column line-item table.
Scaffold the workspace in one shot:
mkdir foxit-extract && cd foxit-extract
python3 -m venv .venv && source .venv/bin/activate
pip install requests
curl -L -o invoice.pdf https://github.com/lucienchemaly/foxit-demo-templates/raw/main/invoice_table_test.pdf
export FOXIT_CLIENT_ID="your_client_id"
export FOXIT_CLIENT_SECRET="your_client_secret" Here is the invoice the rest of the tutorial extracts from.
The source document. The five-column table and the labeled fields above it are what the extraction turns into addressable JSON.
Authentication
PDF Services authenticates with two named request headers on every call, client_id and client_secret, both lowercase with an underscore. There is no OAuth exchange and no bearer token, and wrapping the credentials in an Authorization: Bearer header returns a 400 instead. The base host for every endpoint in this tutorial is https://na1.fusion.foxit.com/pdf-services.
Keep the values in environment variables rather than in the file, so nothing secret travels with your code.
The four-call extraction flow
Structural extraction is an asynchronous job, so it runs in four steps.
The four calls and what each one hands to the next. The id you download with comes from the finished task, not the upload.
- Upload the PDF and receive a
documentId. - Start the analysis against that id and receive a
taskId. - Poll the task until its
statusreachesCOMPLETED, which also returns aresultDocumentId. - Download the result, a ZIP archive holding the structured JSON.
Step 1: Upload the document
Send the PDF as multipart/form-data to the upload endpoint, using the form field name file.
curl -X POST "https://na1.fusion.foxit.com/pdf-services/api/documents/upload" \
-H "client_id: $FOXIT_CLIENT_ID" \
-H "client_secret: $FOXIT_CLIENT_SECRET" \
-F "[email protected]" The -F flag is what makes curl send a multipart body, and the @ prefix tells it to read the file from disk rather than treat the value as a literal string. Uploads are capped at 100 MB, and an uploaded document is deleted after 24 hours, so treat the documentId as short-lived rather than a permanent handle.
A successful upload returns a single key:
{
"documentId": "6a6c9834a820c33d30d222e5"
} Step 2: Start the structural analysis
POST that id to the extraction endpoint with a JSON body.
curl -X POST "https://na1.fusion.foxit.com/pdf-services/api/documents/pdf-structural-extract" \
-H "client_id: $FOXIT_CLIENT_ID" \
-H "client_secret: $FOXIT_CLIENT_SECRET" \
-H "Content-Type: application/json" \
-d '{"documentId": "6a6c9834a820c33d30d222e5"}' The call returns HTTP 202 with a taskId rather than the finished document, since analysis runs asynchronously. documentId is the only required field in the body, and a password-protected source PDF takes an optional password alongside it. Full request and response details live in the PDF Structural Extraction reference, which also carries the endpoint’s Trial designation, so pin the schema version you parse against rather than assuming it is stable.
{
"taskId": "6a6c9835d24a2429666f61b6"
} Step 3: Poll the task
Ask for the task by id until it finishes.
curl "https://na1.fusion.foxit.com/pdf-services/api/tasks/6a6c9835d24a2429666f61b6" \
-H "client_id: $FOXIT_CLIENT_ID" \
-H "client_secret: $FOXIT_CLIENT_SECRET" The response carries the state, a percentage, and, once the work is done, the id of the result document:
{
"taskId": "6a6c9835d24a2429666f61b6",
"status": "COMPLETED",
"progress": 100,
"resultDocumentId": "6a6c98375e2cab6bb50e740b"
} Task statuses are uppercase. The schema enum runs PENDING, IN_PROGRESS, COMPLETED, and FAILED, so a comparison against a lowercase "completed" never matches and your loop spins until it times out. Portal copy sometimes says “processing” in prose, but IN_PROGRESS is the value on the wire.
Step 4: Download the result
Fetch the finished artifact using the resultDocumentId from the poll, not the documentId from the upload. Confusing the two is the most common 4xx at this step.
curl -o extract.zip \
"https://na1.fusion.foxit.com/pdf-services/api/documents/6a6c98375e2cab6bb50e740b/download" \
-H "client_id: $FOXIT_CLIENT_ID" \
-H "client_secret: $FOXIT_CLIENT_SECRET" The response comes back as application/zip. Unzipping it gives you StructureInfo.json, the structured output, alongside a rendered PNG of each analyzed page (page_p0.pdf_0.png for a one-page file).
The whole flow in Python
Here is the complete script, reading credentials from the environment.
import os
import time
import zipfile
import json
import requests
BASE = "https://na1.fusion.foxit.com/pdf-services/api"
HEADERS = {
"client_id": os.environ["FOXIT_CLIENT_ID"],
"client_secret": os.environ["FOXIT_CLIENT_SECRET"],
}
def upload(path):
with open(path, "rb") as fh:
r = requests.post(f"{BASE}/documents/upload", headers=HEADERS, files={"file": fh})
r.raise_for_status()
return r.json()["documentId"]
def start_extract(document_id):
r = requests.post(
f"{BASE}/documents/pdf-structural-extract",
headers={**HEADERS, "Content-Type": "application/json"},
json={"documentId": document_id},
)
r.raise_for_status()
return r.json()["taskId"]
def wait_for_task(task_id, interval=3, timeout=180):
deadline = time.time() + timeout
while time.time() < deadline:
r = requests.get(f"{BASE}/tasks/{task_id}", headers=HEADERS)
r.raise_for_status()
body = r.json()
if body["status"] == "COMPLETED":
return body["resultDocumentId"]
if body["status"] == "FAILED":
raise RuntimeError(f"Extraction failed: {body.get('error')}")
time.sleep(interval)
raise TimeoutError(f"Task {task_id} unfinished after {timeout}s")
def download_zip(result_id, out="extract.zip"):
r = requests.get(f"{BASE}/documents/{result_id}/download", headers=HEADERS)
r.raise_for_status()
with open(out, "wb") as fh:
fh.write(r.content)
return out
document_id = upload("invoice.pdf")
result_id = wait_for_task(start_extract(document_id))
archive = download_zip(result_id)
with zipfile.ZipFile(archive) as z:
structure = json.loads(z.read("StructureInfo.json"))
analyze = structure["analyzeResult"]
print("schema", analyze["version"]["schema"], "pages", len(analyze["pages"])) In this code, you upload the invoice and keep the returned documentId, hand that id to the extraction endpoint to get a taskId, then poll the task on a fixed interval until it reports COMPLETED and yields a resultDocumentId. The download call writes the ZIP to disk, and rather than unpacking it to a folder you read StructureInfo.json straight out of the archive. The top-level key is analyzeResult, which is where the schema version, the page list, and the element array all live.
A three-second interval with a 180-second ceiling is comfortable for single-page documents. Back off rather than tightening the loop if you process long files, since polling every second only burns request budget without finishing the job sooner.
Reading the structured JSON
analyzeResult holds four things worth knowing about, an info block of document metadata, a version block, the pages array, and the elements array that carries the content.
{
"analyzeResult": {
"version": {
"schema": "1.0.7",
"software": "FoxitPDFAnalyzer",
"model": "idp-analysis"
},
"pages": [
{ "pageNumber": 1, "size": {}, "state": {} }
],
"elements": [
{
"type": "title",
"content": {
"text": "INVOICE",
"style": { "fontFamilyName": "Arial", "fontSize": 24.0 }
},
"region": {
"page": 1,
"boundingBox": [90, 71, 189, 71, 189, 99, 90, 99]
},
"score": 0.88,
"id": "title1"
}
]
}
} Each element follows the same shape. The type classifies it, and extracting this invoice returns title, head, paragraph, and table. The schema defines a wider set, adding image, headerFooter, form, hyperlink, footnote, sidebar, annotation, and formula, so branch on the types your documents actually produce rather than assuming only four exist. The text and its font styling sit under content, so you read content.text rather than a top-level text key. The region gives the one-based page plus a boundingBox, and that box is an eight-number polygon listing four corner pairs in order, not a four-number rectangle. Every element also carries a confidence score and a stable id such as title1 or paragraph2, and paragraphs additionally carry a paragraphOrder for reading sequence.
Tables are the interesting case. Rather than a headers array and a two-dimensional rows array, a table exposes a cell list under content.body:
{
"type": "table",
"content": {
"body": {
"rowCount": 4,
"columnCount": 5,
"cells": [
{
"paragraph": { "type": "paragraph", "content": { "text": "Description" } },
"rowSpan": 1,
"columnSpan": 1,
"rowIndex": 0,
"columnIndex": 1
}
]
}
}
} Each cell states its own rowIndex and columnIndex along with rowSpan and columnSpan, and its text lives at paragraph.content.text. That is more verbose than a plain grid, but it means merged cells stay describable and you never have to infer column membership from x-coordinates.
Turning the cell list into rows
Since the API hands you cells rather than rows, build the grid yourself once and work with it afterwards.
def table_to_grid(table):
body = table["content"]["body"]
grid = [["" for _ in range(body["columnCount"])] for _ in range(body["rowCount"])]
for cell in body["cells"]:
text = cell.get("paragraph", {}).get("content", {}).get("text", "")
grid[cell["rowIndex"]][cell["columnIndex"]] = text.replace("\r\n", " ")
return grid
tables = [e for e in analyze["elements"] if e["type"] == "table"]
header, *data_rows = table_to_grid(tables[0])
line_items = [dict(zip(header, row)) for row in data_rows]
text_blocks = {
e["id"]: e["content"].get("text", "")
for e in analyze["elements"]
if e["type"] in ("title", "head", "paragraph")
}
print(header)
for item in line_items:
print(item) The code above allocates an empty grid from rowCount and columnCount, then drops each cell’s text into its stated position, which sidesteps any assumption about cell ordering in the array. Cell text can contain literal \r\n where a label wraps inside its column, so the replace call flattens that to a space before it reaches your data layer. Splitting the first row off as the header lets you zip each remaining row into a dictionary keyed by column name, and the same comprehension pattern collects the title, heading, and paragraph text by element id.
Running it against the sample invoice prints the real extraction:
['#', 'Description', 'Qty', 'Unit Price', 'Line Total']
{'#': '1', 'Description': 'API Integration Consulting', 'Qty': '10', 'Unit Price': '$ 150.00', 'Line Total': '$1,500.00'}
{'#': '2', 'Description': 'Compliance Review', 'Qty': '5', 'Unit Price': '$ 200.00', 'Line Total': '$1,000.00'}
{'#': '', 'Description': '', 'Qty': '', 'Unit Price': 'Subtotal:', 'Line Total': '$2,500.00'} Two things in that output are worth designing around. The unit price arrives as the string "$ 150.00", so currency parsing is still your job, and the final row is a subtotal rather than a line item, which is a reminder that the analyzer reports table geometry rather than business meaning. Filter trailing rows on an empty # or Description before you treat them as products. If you want to inspect a full result without running the calls yourself, the StructureInfo_sample.json from this exact run is available to read.
Feeding the output into an agent or downstream workflow
Once the table is a list of dictionaries and the labeled text is keyed by id, the payload is already agent-ready.
agent_context = {
"document": {"schema": analyze["version"]["schema"], "pages": len(analyze["pages"])},
"text_blocks": text_blocks,
"line_items": line_items,
} Because every element also carries a region, you can layer spatial checks on top, such as confirming a table sits below a particular heading by comparing the y values in their bounding polygons before you trust the association. Foxit also publishes an MCP server for PDF Services, so the same operations are reachable from an agent that speaks the Model Context Protocol rather than raw HTTP.
Common mistakes
- PascalCase auth headers : the keys are lowercase
client_idandclient_secret.ClientIdandClientSecretdo not authenticate, and neither does anAuthorization: Bearerheader, which returns a 400. - Comparing status to a lowercase string : task statuses are uppercase, so test against
COMPLETEDandFAILED. - Downloading with the upload id : the download path takes the
resultDocumentIdfrom the completed task, not thedocumentIdfrom the upload. - Reading
elementsfrom the root : the array is nested underanalyzeResult, sostructure["analyzeResult"]["elements"]is the path. - Expecting
bboxor a rows array : positions arrive asregion.boundingBoxwith eight numbers, and tables arrive ascontent.body.cellswith index fields rather than a headers plus rows pair. - Treating the ZIP as the JSON : the download is an archive, and the structured output is the
StructureInfo.jsonentry inside it. - Reusing a stale
documentId: uploads are removed after 24 hours, and the cap on an upload is 100 MB. - Polling every second : that exhausts request budget without speeding anything up. A few seconds between checks is enough.
PDF data extraction FAQ
What element types does the structural extraction return?
Extracting this invoice produces title, head, paragraph, and table elements. Every element carries type, content, region, score, and id, with tables adding a cell grid under content.body.
How is this different from raw text extraction for tables?
Raw text collapses a table into one string and loses row and column boundaries. Structural extraction reports rowCount, columnCount, and a cell list where each cell states its own rowIndex and columnIndex, so position is data rather than inference.
Is the extraction synchronous?
No. The extract call returns HTTP 202 with a taskId, and you poll GET /pdf-services/api/tasks/{taskId} until the status reaches COMPLETED, which is when resultDocumentId appears.
What does the download actually contain?
A ZIP archive holding StructureInfo.json plus a rendered PNG per analyzed page. The JSON is the structured output and the PNG is useful for visual spot checks.
What schema version does the output use?
The sample run reports analyzeResult.version.schema of 1.0.7, produced by FoxitPDFAnalyzer with the idp-analysis model. Read the version from the payload rather than hardcoding it, since it can move.
Does a failed task tell me why?
The task object surfaces the failure state in status as FAILED, so branch on that and log the whole task body when it happens.
Can I extract several documents at once?
Each upload and each task is independent, so run them concurrently and keep one taskId per document. The upload cap is 100 MB per file.
Get started with Foxit’s PDF Structural Extraction API
The pattern is four calls. Upload the PDF for a documentId, start pdf-structural-extract for a taskId, poll until COMPLETED for a resultDocumentId, then download the ZIP and read StructureInfo.json. From there analyzeResult.elements gives you typed titles, headings, paragraphs, and a table cell grid you can turn into dictionaries in a few lines.
Create a free developer account (no credit card) at account.foxit.com/site/sign-up, grab your Client ID and Secret from the APIs Dashboard, and run the script above against invoice_table_test.pdf to see the structured output for yourself.
Building Agentic Document Workflows: How LLM Agents Use PDF APIs to Convert, Extract, and Sign at Scale

This guide walks through building agentic document workflows by exposing Foxit’s PDF and eSign APIs as callable MCP tools, so any compatible agent host can run the full document lifecycle in one automated pipeline.
Agentic document workflows go beyond retrieval, since they convert, transform, merge, and sign documents without human intervention. This guide shows how to expose Foxit’s production PDF API as callable MCP tools so any LLM agent can execute the full document lifecycle (OCR, extraction, generation, and legally binding signatures) in a single automated pipeline.
Most LLM-powered applications have solved the retrieval problem. The harder part of agentic document workflows is action, the moment your agent needs to convert a scanned invoice to searchable text, merge a dozen contract pages into a package, and route it for a legally binding signature without a human in the loop.
RAG gets text into a context window, which is useful for reading. Once you need to produce, transform, or sign a document, you’ve moved into document operations territory. A plain text API won’t close that delta, and bolting together a dozen bespoke REST wrappers every time you need a new pipeline quickly becomes the bottleneck.
The Model Context Protocol (MCP) gives agents a standard way to discover and call tools. Document workflows have been missing a tool surface that exposes real PDF operations as callable MCP tools, backed by a production-ready API. This guide walks through exactly how to build that.
What You Need Before You Start
Five prerequisites are required to follow this guide. You need a Foxit developer account, the open-source MCP server, an MCP-compatible host, three environment variables, and a Python workspace for the signing example.
A Foxit developer account. Sign up at account.foxit.com/site/sign-up (no credit card required for the free Developer plan). The Foxit Developer Portal issues your Client ID and Client Secret, gives you access to the API Playground, and tracks usage in real time.
The open-source MCP server. Clone github.com/foxitsoftware/foxit-pdf-api-mcp-server. The repo ships two active implementations, a Python build (using FastMCP, Python 3.11+, and the uv package manager) and a TypeScript build (Node.js 18+, pnpm). The original stdio-python variant is deprecated, so use the current Python or TypeScript implementation.
An MCP-compatible host. You need somewhere to run the agent. Claude Desktop, Cursor, or VS Code with GitHub Copilot all work, and any MCP-compliant custom agent framework will also connect to the server.
A Python workspace for the signing example. The eSign walkthrough later in this guide runs a short Python script, so you need Python 3.8+ and the requests library. That walkthrough also uses a separate set of eSign credentials, which you set up in its own section rather than here. Scaffold an isolated workspace in one shot:
mkdir agentic-docs && cd agentic-docs
python3 -m venv .venv && source .venv/bin/activate
pip install requests Three environment variables. Before launching your MCP host process, export these:
export FOXIT_CLOUD_API_HOST="https://na1.fusion.foxit.com/pdf-services"
export FOXIT_CLOUD_API_CLIENT_ID="your_client_id"
export FOXIT_CLOUD_API_CLIENT_SECRET="your_client_secret" Never hardcode credentials in config files. The MCP server reads these at startup and uses them to authenticate every request to the PDF Services API.
What “Agentic” Actually Means for Document Workflows
An agentic document workflow executes operations on documents (converting formats, applying OCR, merging pages, routing for signature) rather than simply retrieving text from them. The tool surface required is fundamentally different from a RAG setup.
Retrieval-augmented generation pulls text from a document and injects it into a prompt. An agentic document workflow does something to a document, whether it converts a format, applies OCR to make a scanned image searchable, merges pages from multiple sources, or routes the result for signature.
In a tool-use architecture, the LLM doesn’t call the API directly. It picks the right operation from a catalog of tools based on the task, calls it with structured inputs, processes the result, and decides whether to continue the chain or hand off to the next step. If you’ve worked with web-search or code-execution tools in LangChain or AutoGen, the pattern is identical. The model reasons about which tool to invoke, not about how the underlying HTTP request works.
A REST API is an HTTP surface. An MCP tool is a named, typed function with an input schema, an output contract, and a description the model uses to decide when and whether to call it. MCP standardizes that interface so any compliant host can discover the full tool catalog, call individual operations, and chain results without custom adapter code.
A well-designed MCP server eliminates the bespoke integration layer. Without one, every document-heavy agent pipeline requires someone to write and maintain that plumbing from scratch.
Architecture Overview: Two Modes for Agent-Driven PDF Processing
The Foxit PDF API MCP Server wraps Foxit’s cloud PDF Services API as 30+ callable MCP tools, covering every stage of a document lifecycle. Foxit PDF Editor is the first PDF editor in the industry to act as an MCP Host, connecting outward to external MCP Servers and acting on open documents.
Those two facts define two distinct architectural modes.
Mode 1: Programmatic pipeline. Your MCP host (Claude Desktop, Cursor, VS Code with GitHub Copilot, or a custom agent) registers the Foxit PDF API MCP Server. The agent calls PDF tools directly, the server translates those calls into Foxit PDF Services REST requests, and structured results return to the agent. The agent never writes REST plumbing. This is the right model for automated pipelines running without a human in the loop.
Mode 2: In-app orchestration. Foxit PDF Editor acts as the MCP Host. Its embedded AI Assistant connects to external MCP Servers (Jira, Salesforce, Gmail, Notion, GitHub, Google Workspace) and acts on the open document. You could extract fields from a contract PDF and open a Jira ticket without leaving the editor. This is the right model when a knowledge worker needs AI assistance during document review.
Mode 1 is what the rest of this guide builds. Its data flow runs like this:

The agent calls tools, the MCP server handles the REST layer against PDF Services, and a prepared document hands off to eSign at the end of the chain.
One detail to understand before you build is that each successful Foxit PDF Services API call consumes one credit from your plan. Failed requests (4xx or 5xx) do not consume credits. The Developer Dashboard shows real-time usage, so you can see exactly what a pipeline costs per document before scaling it up.
Setting Up the Foxit MCP Server
The server exposes tools across six categories (document lifecycle, creation, conversion, manipulation, security, and forms) plus OCR and document compare.
The full tool catalog breaks down as follows:
- Document lifecycle : upload, download, delete
- Creation : Word, Excel, PowerPoint, HTML, URL, plain text, and image to PDF
- Conversion : PDF to Word, Excel, PowerPoint, HTML, plain text, and image
- Manipulation : merge, split, extract pages, compress, flatten, linearize, watermark, and page operations
- Security : add and remove passwords, set permissions
- Forms : export and import form data as JSON
OCR and document compare are also in the catalog. Signing lives in the eSign API covered in Section 6.
Mode 1: Programmatic Pipeline Setup
Clone the repo and pick your implementation. For the Python version with VS Code and GitHub Copilot, create or update your .vscode/mcp.json with the following:
{
"servers": {
"foxit-pdf": {
"command": "uv",
"args": [
"--directory",
"/absolute/path/to/foxit-pdf-api-mcp-server",
"run",
"foxit-pdf-api-mcp-server"
],
"env": {
"FOXIT_CLOUD_API_HOST": "${env:FOXIT_CLOUD_API_HOST}",
"FOXIT_CLOUD_API_CLIENT_ID": "${env:FOXIT_CLOUD_API_CLIENT_ID}",
"FOXIT_CLOUD_API_CLIENT_SECRET": "${env:FOXIT_CLOUD_API_CLIENT_SECRET}"
}
}
}
} VS Code launches the MCP server as a subprocess through uv, which runs the cloned Python build from its directory. The three ${env:...} references pull credentials from the shell environment instead of hardcoding them in the file, so replace /absolute/path/to/foxit-pdf-api-mcp-server with the path where you cloned the repo and restart VS Code to load the server. Claude Desktop uses the same shape under an mcpServers key and can run the published npm package directly with "command": "npx" and "args": ["-y", "@foxitsoftware/foxit-pdf-api-mcp-server"], so you do not have to clone anything for that host.
Mode 2: In-App Orchestration Setup
Open Foxit PDF Editor, click the AI Assistant tab in the Ribbon, and launch AI Chat to open the right-hand panel. In the bottom left of that panel, click MCP Tools, then click Add MCP Server to configure a new MCP service. Fill in the required fields and save. Once configured, the server appears in the MCP Tools list and its tools activate inside AI Chat.
In both modes, the server reads your Client ID and Client Secret from the environment variables set at startup. No additional gateway configuration is required.
Core Document Operations Agents Can Execute
With the server running, your agent has 30+ callable PDF operations available. Five categories do the heaviest lifting in production pipelines, namely conversion, OCR, structural extraction, merge/split, and document generation via DocGen.
Conversion. An agent receiving an uploaded DOCX triggers the Word-to-PDF creation tool before any downstream step. The output is a standards-compliant PDF that every subsequent operation (OCR, extraction, merge) can work with consistently, eliminating manual conversion and format ambiguity downstream.
OCR. When an agent ingests a scanned or image-only PDF, an OCR call should precede any extraction step. Calling the OCR tool makes the document searchable and text-extractable, which is required for invoice and contract pipelines where key fields sit inside scanned images. The agent calls OCR, waits for the result, and proceeds.
Structural extraction. After OCR, an agent extracts text, tables, and form-field data as structured JSON. Foxit’s structural extraction returns per-page content plus images, giving you a payload that routes cleanly into a BI tool or a second LLM step for analysis or classification. For the full response schema, refer to the Foxit MCP Server developer blog.
Merge and split. An agent assembling a contract package from multiple source documents calls the merge tool with an ordered list of PDFs. An agent pre-processing a large compliance document for parallel LLM analysis calls the split tool to divide it into per-section chunks. Both operations are synchronous and safe to retry on failure.
Document generation via DocGen. For dynamically generated contracts, invoices, or reports, the Foxit Document Generation API accepts a DOCX template with {{dynamic_tags}} and a JSON data payload from a CRM, database, or form response. It returns a finished PDF via POST /document-generation/api/GenerateDocumentBase64. A ready-to-use template lives in the Foxit demos repo if you want to test the call without authoring one. When you upload a DOCX template directly, the 4 MB post-base64 encoding cap applies, so slim templates down by stripping embedded fonts and large images before encoding. The agent supplies the JSON payload at runtime, so a single template can produce thousands of unique documents.
A representative end-to-end pipeline runs like this. An agent ingests a purchase order scan, calls OCR to make it searchable, extracts the structured fields as JSON, merges that data into a contract template via DocGen, and hands the finished PDF off to eSign. Every step is a tool call. The agent reasons about sequencing while the MCP server handles the REST layer.
Agent-Triggered Signing Workflows via the eSign API
Document signing uses a separate REST service, the Foxit eSign API, which has its own credentials and completes the pipeline in three calls. The agent exchanges its credentials for a token, creates a signing folder from the prepared PDF, and dispatches it to the signer.
The eSign API runs on its own host and issues its own Client ID and Client Secret from the eSign portal, separate from the PDF Services credentials the MCP server uses. Export the three eSign variables the script reads before running it:
export FOXIT_ESIGN_BASE_URL="https://na1.foxitesign.foxit.com"
export FOXIT_ESIGN_CLIENT_ID="your_esign_client_id"
export FOXIT_ESIGN_CLIENT_SECRET="your_esign_client_secret" The folder can only be sent if the signer has a signature field, and the simplest way to place one is with Foxit eSign text tags embedded in the document. Download the ready-to-sign sample, agent_agreement.pdf, into your workspace as agreement.pdf. It already carries the tag that maps a signature field to the first party, so the folder is sendable as is. Then run:
import base64
import os
import requests
BASE_URL = os.environ["FOXIT_ESIGN_BASE_URL"] # https://na1.foxitesign.foxit.com
CLIENT_ID = os.environ["FOXIT_ESIGN_CLIENT_ID"]
CLIENT_SECRET = os.environ["FOXIT_ESIGN_CLIENT_SECRET"]
def get_access_token():
resp = requests.post(
f"{BASE_URL}/api/oauth2/access_token",
data={
"client_id": CLIENT_ID,
"client_secret": CLIENT_SECRET,
"grant_type": "client_credentials",
"scope": "read-write",
},
timeout=30,
)
resp.raise_for_status()
return resp.json()["access_token"]
def route_for_signature(pdf_path, signer):
token = get_access_token()
headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
with open(pdf_path, "rb") as fh:
encoded = base64.b64encode(fh.read()).decode()
folder = requests.post(
f"{BASE_URL}/api/folders/createfolder",
headers=headers,
json={
"folderName": "Agent Service Agreement",
"inputType": "base64",
"base64FileString": [encoded],
"fileNames": ["agreement.pdf"],
"processTextTags": True,
"sendNow": False,
"parties": [
{
"permission": "FILL_FIELDS_AND_SIGN",
"firstName": signer["first_name"],
"lastName": signer["last_name"],
"emailId": signer["email"],
"sequence": 1,
}
],
},
timeout=60,
)
folder.raise_for_status()
folder_id = folder.json()["folder"]["folderId"]
sent = requests.post(
f"{BASE_URL}/api/folders/sendDraftFolder",
headers=headers,
json={"folderId": folder_id},
timeout=60,
)
sent.raise_for_status()
return folder_id
if __name__ == "__main__":
fid = route_for_signature(
"agreement.pdf",
{"first_name": "Jordan", "last_name": "Lee", "email": "[email protected]"},
)
print(f"Folder {fid} sent for signature") In this code, you read the eSign credentials from the environment and exchange them for a bearer token at the access_token endpoint, where the request is form-encoded rather than JSON (sending JSON returns a 415). You then base64-encode the local PDF and post it to createfolder with inputType set to base64 so the API reads the base64FileString array, with processTextTags set to True so the document’s text tags become a real signature field, and with sendNow set to False so the folder is created as a draft instead of emailing anyone immediately. The parties array names the signer with FILL_FIELDS_AND_SIGN permission, you read the new id at folder.folderId, and you pass it to sendDraftFolder, which dispatches the draft to the signer. To confirm the result, call GET /api/folders/viewActivityHistory?folderId={id}, which returns the activity log once the folder has been shared (a draft returns logs of a non-shared folder can not be viewed). Foxit uses “folder” throughout the eSign API, never “envelope.”
Compliance is built into the API layer. The Foxit eSign API supports eIDAS, the ESIGN Act, UETA, HIPAA, and GDPR, covering the requirements for agents operating in legal, healthcare, and finance contexts. No separate compliance infrastructure is required.
Production Considerations: Compliance, Cost, and Error Handling
The Foxit PDF Services and eSign APIs are SOC 2 Type II certified, with HIPAA BAA support, GDPR compliance, and CCPA coverage built in. Three additional concerns (credit consumption, idempotency, and async polling) determine whether a pipeline runs reliably at scale.
Credit consumption. The free Developer plan includes 500 credits per year (annual reset, no rollover). The Startup plan is $1,750/year for 3,500 credits. The Business plan is $4,500/year for 150,000 credits. Each successful API call consumes one credit; 4xx and 5xx responses do not. A pipeline processing 50 documents per day burns through those allocations quickly. Monitor real-time usage in the Developer Dashboard before moving to production and size your plan accordingly.
Idempotency. Merge, flatten, and convert calls are safe to retry on failure. Signing-folder creation is not, so gate createfolder behind a state check so the agent doesn’t create duplicate folders and dispatch duplicate signing requests to the same signers.
Async operations. Translation and batch conversion operations are asynchronous, so they return a job ID immediately, and your agent should poll the job status endpoint roughly every three seconds until the status is COMPLETED or FAILED before proceeding to the next step in the chain. Handling these concerns at build time separates a working pipeline from one that generates support tickets.
Common Mistakes
- Dropping the
/api/prefix on eSign calls : Every eSign path lives under/api/, as in/api/folders/createfolder. Omitting it returns a 404 against a docs-style path that does not exist. - Sending the token request as JSON : The
access_tokenendpoint is form-encoded. A JSON body returns415 Unsupported Media Type, so pass the credentials as form data. - Forgetting
inputType: base64: When you send a base64 PDF without it,createfolderrejects the request withfileUrls or base64FileString cannot be empty. URL mode usesfileUrlsandfileNamesinstead. - Sending a signer with no signature field : A
FILL_FIELDS_AND_SIGNparty needs a field. If the document has no text tag like${s:1:______}and you skipprocessTextTags,sendDraftFolderreturnsPlease assign a signature field. Use underscores in the tag placeholder, since an empty placeholder does not create a field. - Expecting a signing tool in the MCP server : The 30+ MCP tools cover PDF operations, not signatures. Signing is the eSign API, a separate service with separate credentials.
Agentic Document Workflows FAQ
What is an agentic document workflow?
An agentic document workflow is an automated pipeline in which an LLM agent executes operations on documents (conversion, OCR, extraction, merging, generation, and signing) without human intervention. Unlike retrieval-augmented generation, which only reads documents, an agentic workflow produces and transforms them using callable tools exposed through a protocol like MCP.
How does the Model Context Protocol (MCP) work with PDF APIs?
MCP defines a standard interface for exposing named, typed functions, called tools, that an LLM agent can discover and invoke. A PDF API MCP server wraps REST endpoints as MCP tools with input schemas and output contracts. The agent selects the right tool based on task context, calls it with structured parameters, and processes the result, without writing any HTTP request logic.
What PDF operations does the Foxit MCP server expose?
The Foxit PDF API MCP Server exposes 30+ tools covering document lifecycle (upload, download, delete), creation (Word, Excel, PowerPoint, HTML, image to PDF), conversion (PDF to multiple formats), manipulation (merge, split, compress, OCR, watermark), security (password management), and forms (JSON import/export).
Does every API call consume a credit even if it fails?
No. Only successful Foxit PDF Services API calls consume credits. Requests that return 4xx or 5xx status codes do not count against your plan. The Developer Dashboard provides real-time usage tracking so you can measure pipeline cost per document before scaling.
How do I trigger document signing from an agent without human intervention?
After preparing a document, your agent calls the Foxit eSign API directly. It authenticates with client_credentials, POSTs to /api/folders/createfolder with the base64 PDF and a parties entry for the signer, then POSTs to /api/folders/sendDraftFolder with the returned folderId. The signing email workflow triggers automatically, and the agent can poll /api/folders/viewActivityHistory for the audit trail.
What compliance standards does the Foxit eSign API meet?
The Foxit eSign API supports eIDAS, the U.S. ESIGN Act, UETA, HIPAA, GDPR, and CCPA. The PDF Services API is SOC 2 Type II certified with HIPAA BAA support. No separate compliance wrappers are required for agents operating in legal, healthcare, or financial contexts.
What is the difference between Mode 1 and Mode 2 in the Foxit MCP architecture?
Mode 1 is a programmatic pipeline where an external LLM agent (Claude Desktop, Cursor, VS Code with GitHub Copilot, or a custom framework) registers the Foxit MCP Server and calls PDF tools automatically. Mode 2 is in-app orchestration where Foxit PDF Editor acts as the MCP Host, connecting to external services like Jira or Salesforce while a knowledge worker reviews the open document.
Why should signing-folder creation be gated behind a state check?
The /api/folders/createfolder endpoint is not idempotent. If an agent retries on failure without a state check, it will create duplicate folders and send duplicate signing requests to the same signers. Merge, flatten, and convert operations are safe to retry; folder creation requires the agent to verify no existing folder was created before calling the endpoint again.
Start Building: Free Developer Access in Minutes
The full pipeline in this guide is available to test today. Activate a free Foxit Developer plan to get your Client ID, Client Secret, access to the API Playground, and 500 credits for real requests. No credit card required.
Clone the open-source MCP server, export the three environment variables, and register the server in Claude Desktop, Cursor, or VS Code with GitHub Copilot. At that point, 30+ PDF tools are callable from your agent with no local SDK to install and no REST plumbing to write.
Once a document is prepared, extend the pipeline into legally binding signatures with the eSign API. The architecture in this guide covers the full document lifecycle from conversion and OCR through extraction, generation, merging, and signing, all in a single agentic document workflow.
Create your free developer account to clone the open-source MCP server and make 30+ PDF tools callable from your agent in minutes, no credit card required.