Python SDK for the 0xPdf PDF-to-JSON API.
Schema in, PDF in, JSON out — 22 seconds:

Full MP4 · Try free · API docs
Use the dedicated MCP server so Claude / Cursor can parse PDFs into your JSON schema:
pip install oxpdf-mcp
# or: uvx oxpdf-mcp
Repo + Cursor config: risha-max/0xpdf-mcp · Docs: 0xpdf.io/docs#mcp
pip install "oxpdf @ git+https://github.com/risha-max/oxpdf-python.git@main"
from oxpdf import Client
client = Client(api_key="your_api_key")
# Parse with a built-in template
result = client.parse("invoice.pdf", schema_template="invoice")
print(result["data"])
# Parse with a custom schema
result = client.parse("doc.pdf", schema={
"type": "object",
"properties": {
"title": {"type": "string"},
"amount": {"type": "number"}
}
})
# Stream parse with real-time progress
for event in client.parse_stream("large.pdf", schema_template="invoice"):
if event["event"] == "page":
print(f"Progress: {event['data'].get('message')}")
elif event["event"] == "complete":
print("Done!", event["data"])
# Queue async processing and wait for completion
queued = client.upload("invoice.pdf", schema_id="your_schema_id")
status = client.wait_for_job(
queued["job_id"],
interval_seconds=2.0,
timeout_seconds=180.0,
)
print(status["status"])
from oxpdf import Client, OxPDFError
client = Client(api_key="your_api_key")
try:
result = client.parse("doc.pdf", schema_template="invoice")
except OxPDFError as e:
print(f"API error: {e} (status: {e.status_code})")
except FileNotFoundError:
print("PDF file not found")
Client(
api_key,
base_url="https://api.0xpdf.io/api/v1",
timeout=120,
max_retries=2,
retry_delay=0.5,
backoff_multiplier=2.0
)
| Method |
Description |
parse(file_path, *, schema, schema_template, schema_id, use_ocr, ocr_engine, pages) |
Sync parse — returns structured JSON |
parse_stream(file_path, *, schema, schema_template, schema_id, use_ocr, ocr_engine, pages, batch_size) |
Streaming parse via SSE — yields events |
validate(file_path, *, schema_id, schema_name) |
Dry-run validation without processing |
| Method |
Description |
upload(file_path, *, schema_id, schema_name, use_ocr, ocr_engine) |
Queue PDF for background processing |
job_status(job_id) |
Poll async job status |
wait_for_job(job_id, *, interval_seconds, timeout_seconds) |
Poll until completed/failed |
Image Extraction
| Method |
Description |
extract_images(file_path, *, pages, min_width, min_height, use_ocr, ocr_engine) |
Extract images from a PDF |
list_images(*, limit, offset) |
List extracted images |
get_image_url(image_id, *, expiration_seconds) |
Get/refresh presigned URL |
delete_image(image_id) |
Delete a specific image |
delete_all_images() |
Delete all images |
| Method |
Description |
list_files() |
List uploaded PDFs |
get_file(pdf_id) |
Get PDF metadata + download URL |
delete_file(pdf_id) |
Delete an uploaded PDF |
| Method |
Description |
list_schemas() |
List saved schemas |
get_schema(schema_id) |
Get schema with full definition |
create_schema(name, schema, *, is_default) |
Create a new schema |
update_schema(schema_id, name, schema, *, is_default) |
Update existing schema |
delete_schema(schema_id) |
Delete a schema |
set_default_schema(schema_id) |
Set as default |
generate_schema(description, *, refinement, current_schema, selected_text) |
AI-generate a schema |
| Method |
Description |
list_templates() |
Parse templates (invoice, receipt, etc.) |
list_schema_templates() |
Schema editor templates |
get_schema_template(template_id) |
Get template with full schema |
| Method |
Description |
get_analytics() |
Usage analytics |
submit_feedback(feedback) |
Submit feedback |
get_pricing(*, billing_cycle) |
Get pricing tiers |
get_current_tier() |
Current subscription & quota |