API Reference
Parse offers two ways to extract data from documents: a single-call synchronous method and a three-step asynchronous method.
All endpoints require a Bearer token in the Authorization header. See Authentication for how to create and use your API key.
Base URL: https://api-parse.conversiontools.io
Method 1: Single Call (Sync)
Upload a file and start an extraction in one request. By default the call returns immediately with a 202 response and an extraction ID - poll for the result or use a webhook. Pass wait to hold the request open and receive small documents inline.
/v1/extract
Headers
| Header | Value |
|---|---|
| Authorization | Bearer YOUR_API_KEY |
| Content-Type | multipart/form-data |
Parameters (form-data)
| Parameter | Type | Required | Description |
|---|---|---|---|
| file | File | Yes | The document to extract data from (PDF, JPEG, PNG, GIF, WebP, TIFF, BMP, HEIC, AVIF) |
| schema_id | String | No | Schema ID to control which fields to extract |
| wait | Number | No | Seconds to hold the request open and return the result inline if it finishes in time (0 = return immediately - the default; maximum 120) |
| webhook_url | String | No | Public http(s) URL notified when the extraction finishes, so you do not have to poll |
| no_cache | Boolean | No | Set to 1 to force a fresh extraction instead of reusing a stored result for an identical document |
Example
curl -X POST https://api-parse.conversiontools.io/v1/extract \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@invoice.pdf" \
-F "wait=60"Response (200 - with wait, when the document finishes in time)
{
"success": true,
"id": "ext_789...",
"filename": "invoice.pdf",
"status": "completed",
"data": {
"vendor_name": "Acme Corp",
"invoice_number": "INV-2024-001",
"date": "2024-01-15",
"total": 1650.00
},
"pages_used": 1
}Response (202 - default)
By default, and whenever the document outlives the wait window, the server returns a 202 with an extraction ID. Poll GET /v1/extractions/:id until status is completed or failed - always branch on status, never on timing. Or pass a webhook URL so you do not have to poll at all.
{
"success": true,
"id": "ext_789...",
"status": "processing"
}# Poll until the extraction reaches a terminal status
while true; do
RESULT=$(curl -s https://api-parse.conversiontools.io/v1/extractions/EXTRACTION_ID \
-H "Authorization: Bearer YOUR_API_KEY")
STATUS=$(echo "$RESULT" | grep -o '"status": *"[a-z]*"')
case "$STATUS" in
*completed*|*failed*) break ;;
esac
sleep 2
done
echo "$RESULT"Method 2: Upload + Extract (Async)
A three-step flow: upload the file first, then start an extraction, then poll for the result. This method gives you more control - you can reuse the same uploaded file for multiple extractions with different schemas.
/v1/upload
Upload a document and receive a file_id for extraction.
Parameters (form-data)
| Parameter | Type | Required | Description |
|---|---|---|---|
| file | File | Yes | The document to upload (PDF, JPEG, PNG, GIF, WebP, TIFF, BMP, HEIC, AVIF) |
Example
curl -X POST https://api-parse.conversiontools.io/v1/upload \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@invoice.pdf"Response
{
"success": true,
"file_id": "abc123...",
"filename": "invoice.pdf",
"size": 52480
}/v1/extract
Start an extraction on an uploaded file using its file_id. Optionally specify a schema_id to control which fields to extract.
Headers
| Header | Value |
|---|---|
| Authorization | Bearer YOUR_API_KEY |
| Content-Type | application/json |
Parameters (JSON body)
| Parameter | Type | Required | Description |
|---|---|---|---|
| file_id | String | Yes | The file ID returned from the upload endpoint |
| schema_id | String | No | Schema ID to control which fields to extract |
| webhook_url | String | No | Public http(s) URL notified when the extraction finishes, so you do not have to poll |
| no_cache | Boolean | No | Set to true to force a fresh extraction instead of reusing a stored result for an identical document |
Example
curl -X POST https://api-parse.conversiontools.io/v1/extract \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"file_id": "abc123...", "schema_id": "sch_456...", "webhook_url": "https://example.com/hooks/parse"}'Response
{
"success": true,
"id": "ext_789...",
"status": "processing"
}/v1/extractions/:id
Retrieve the result of an extraction. Poll this endpoint until status is completed.
Example
curl https://api-parse.conversiontools.io/v1/extractions/ext_789... \
-H "Authorization: Bearer YOUR_API_KEY"Response
{
"success": true,
"id": "ext_789...",
"filename": "invoice.pdf",
"status": "completed",
"data": {
"vendor_name": "Acme Corp",
"invoice_number": "INV-2024-001",
"date": "2024-01-15",
"items": [
{
"description": "Consulting Services",
"quantity": 10,
"unit_price": 150.00,
"amount": 1500.00
}
],
"subtotal": 1500.00,
"tax": 150.00,
"total": 1650.00,
"currency": "USD"
},
"pages_used": 1
}Webhooks
Pass a webhook_url and Parse sends a POST to it as soon as the extraction finishes or fails, so you never have to poll. The notification carries the extraction ID and status only - never the extracted data - so fetch the result from the API when it arrives. The URL must be a public http or https address; private and internal addresses are rejected. Delivery is retried a few times and never affects the extraction itself.
Notification payload
{
"event": "extraction.completed",
"id": "ext_789...",
"status": "completed",
"pages_used": 2,
"error": null,
"created_at": "2026-07-26T10:00:00.000Z",
"completed_at": "2026-07-26T10:00:41.000Z"
}Repeat Extractions
Sending the same document again with the same schema returns the stored result immediately, and it does not count against your pages. Those responses include "cached": true. Editing the schema, or passing no_cache, runs a fresh extraction.
Export to CSV / Excel
Convert a completed extraction's result into a spreadsheet. Exports are free, repeatable, and do not consume pages. Nested arrays are denormalized: header fields repeat on every row, so the output is ready for pivot tables and imports. Tip: pass output_format (csv or xlsx) on the extract request and the export starts automatically as soon as the extraction completes.
/v1/extractions/:id/export
Start the export. Idempotent per format: repeated calls return the running conversion or the finished file's status.
Example
curl -X POST https://api-parse.conversiontools.io/v1/extractions/ext_789.../export \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"format": "xlsx"}'Response
{
"success": true,
"status": "processing",
"format": "xlsx",
"progress": 0
}/v1/extractions/:id/export?format=xlsx
Poll the export. While converting, the response is JSON with status: "processing" and a progress percentage. When ready, the response body is the file itself (with Content-Disposition: attachment).
Example
curl -L -o invoice.xlsx \
"https://api-parse.conversiontools.io/v1/extractions/ext_789.../export?format=xlsx" \
-H "Authorization: Bearer YOUR_API_KEY"/v1/extractions/:id
Delete an extraction and all of its stored data (result and any export files). Source documents are always deleted automatically within 24 hours of processing; extracted results are stored until you delete them - via this endpoint or from the dashboard.
Example
curl -X DELETE https://api-parse.conversiontools.io/v1/extractions/ext_789... \
-H "Authorization: Bearer YOUR_API_KEY"Error Responses
401 Unauthorized
{
"error": "Invalid API key",
"param": "authorization"
}429 Rate Limited
{
"error": "Monthly page limit exceeded",
"code": "LIMIT_REACHED",
"message": "You've reached your monthly page limit (100 pages).",
"remedy": { "text": "View plans and upgrade", "path": "/pricing" }
}