π¨βπ» Public API
API Base
All the API endpoints described in this article are relative to the base URL: https://api.airparser.com.
Authentication
To access the API, you will need the API key that you will find in your account:

This API key should be included in the X-API-Key HTTP header.
Unauthenticated responses will return in a HTTP 401 Unauthorized code.
Here's a request example using cURL:
curl -X GET https://api.airparser.com/inboxes/ -H "X-API-Key: <YOUR_API_KEY>"
Documents
Parse a Document
Airparser supports 2 upload modes: sync and async.
Use sync mode if you need to wait for the result and receive the parsed data directly in the response.
Async mode is better if you simply want to upload documents for parsing. In this case, the document will be processed in the background and the parsed data will be sent to your configured integrations such as webhooks, Zapier, Make, n8n, or other destinations.
Your Inbox ID can be found in the browser location bar:

Parse a Document β Sync
API Endpoint: POST /inboxes/<inbox_id>/upload-sync
Uploads a document, waits for parsing to complete, and returns the extracted data in the same response. The request will wait up to 60 seconds. If parsing takes longer (rare), the response will include parsing_in_progress: true along with the document ID β you can then retrieve the result later via webhook or by polling the document endpoint.
Parameters:
file: Binary file object
meta (object, optional): Custom payload data. Will be included in the parsed JSON as the
__meta__field. Useful for linking the document to a record in your external database.
Supported formats: EML, PDF, HTML, TXT, MD and more.
Max file size: 20MB.
Returns: Parsed document object
{ "doc_id": "64abc123def456...", "parsing_in_progress": false, "status": "parsed", "name": "invoice.pdf", "content_type": "application/pdf", "created_at": "2026-03-10T12:00:00.000Z", "processed_at": "2026-03-10T12:00:04.321Z", "json": { "invoice_number": "INV-001", "total": 150.00, "__meta__": { "my_id": 42 } }}
If parsing is still in progress after 60 seconds:
{ "doc_id": "64abc123def456...", "parsing_in_progress": true, "status": "parsing", "name": null, "content_type": null, "created_at": null, "processed_at": null, "json": null}
Code samples
CURL:
curl \ -X POST \ https://api.airparser.com/inboxes/<INBOX_ID>/upload-sync \ -F 'file=@./receipt.pdf' \ -H "X-API-Key: <YOUR_API_KEY>"
PHP:
<?php $apikey = '<API_KEY>';$url = 'https://api.airparser.com/inboxes/<INBOX_ID>/upload-sync';$filepath = './invoice.pdf'; $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url);curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);curl_setopt($curl, CURLOPT_HTTPHEADER, array( 'X-API-Key: ' . $apikey));curl_setopt($curl, CURLOPT_POST, true); $meta = array( 'foo' => 'bar', 'my_id' => 42,); curl_setopt($curl, CURLOPT_POSTFIELDS, array( 'file' => curl_file_create($filepath, 'application/pdf', 'invoice.pdf'), 'meta' => json_encode($meta))); $response = curl_exec($curl);curl_close($curl); $result = json_decode($response, true); if ($result['parsing_in_progress']) { echo "Parsing is taking longer than expected. Doc ID: " . $result['doc_id'];} else { echo "Parsed data: "; print_r($result['json']);}
Python:
import requests header = {"X-API-Key": "<API_KEY>"}url = "https://api.airparser.com/inboxes/<INBOX_ID>/upload-sync" with open('invoice.pdf', 'rb') as f: files = {'file': f} response = requests.post(url, files=files, headers=header) result = response.json() if result['parsing_in_progress']: print('Parsing still in progress. Doc ID:', result['doc_id'])else: print('Parsed data:', result['json'])
Node.js:
const fetch = require("node-fetch");const fs = require("fs");const FormData = require("form-data"); const APIKEY = "<YOUR_API_KEY>";const inboxId = "<INBOX_ID>";const filePath = "/path/to/your/file.pdf";const metadata = { my_id: 42 }; // optional async function importFileSync(inboxId, filePath, metadata) { const url = `https://api.airparser.com/inboxes/${inboxId}/upload-sync`; const form = new FormData(); form.append("file", fs.createReadStream(filePath)); form.append("meta", JSON.stringify(metadata)); const response = await fetch(url, { method: "POST", body: form, headers: { "X-API-Key": APIKEY }, }); const result = await response.json(); if (result.parsing_in_progress) { console.log("Parsing still in progress. Doc ID:", result.doc_id); } else { console.log("Parsed data:", result.json); }} importFileSync(inboxId, filePath, metadata);
Parse a Document β Async
API Endpoint: POST /inboxes/<inbox_id>/upload
Uploads a document and returns immediately with a document ID. Parsing happens in the background. Use webhooks to receive the parsed result when it's ready.
Parameters:
file: Binary file object
meta (object, optional): Custom payload data. Will be included in the parsed JSON as the meta field.
Supported formats: EML, PDF, HTML, TXT, MD and more.
Max file size: 20MB
Returns: Document ID (string)
Code samples
CURL:
curl \ -X POST \ https://api.airparser.com/inboxes/<INBOX_ID>/upload \ -F 'file=@./receipt.pdf' \ -H "X-API-Key: <YOUR_API_KEY>"
PHP:
<?php $apikey = '<API_KEY>';$url = 'https://api.airparser.com/inboxes/<INBOX_ID>/upload';$filepath = './invoice.pdf'; $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url);curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);curl_setopt($curl, CURLOPT_HTTPHEADER, array( 'X-API-Key: ' . $apikey));curl_setopt($curl, CURLOPT_POST, true); $meta = array( 'foo' => 'bar', 'my_id' => 42,); curl_setopt($curl, CURLOPT_POSTFIELDS, array( 'file' => curl_file_create($filepath, 'application/pdf', 'invoice.pdf'), 'meta' => json_encode($meta))); $response = curl_exec($curl);curl_close($curl); echo "Document ID: " . $response;
Python:
import requests header = {"X-API-Key": "<API_KEY>"}url = "https://api.airparser.com/inboxes/<INBOX_ID>/upload" with open('invoice.pdf', 'rb') as f: files = {'file': f} response = requests.post(url, files=files, headers=header) print("Document ID:", response.text)
Node.js:
const fetch = require("node-fetch");const fs = require("fs");const FormData = require("form-data"); const APIKEY = "<YOUR_API_KEY>";const inboxId = "<INBOX_ID>";const filePath = "/path/to/your/file.pdf";const metadata = { my_id: 42 }; // optional async function importFile(inboxId, filePath, metadata) { const url = `https://api.airparser.com/inboxes/${inboxId}/upload`; const form = new FormData(); form.append("file", fs.createReadStream(filePath)); form.append("meta", JSON.stringify(metadata)); const response = await fetch(url, { method: "POST", body: form, headers: { "X-API-Key": APIKEY }, }); const docId = await response.json(); console.log("Document ID:", docId);} importFile(inboxId, filePath, metadata);
Get a document
GET /docs/<document_id>/extended
This endpoint allows to retrieve the parsed data as JSON but we highly recommend using webhooks for real-time data sending instead.
List documents
GET /inboxes/<inbox_id>/docs
Optional parameters:
page (number)
from (string): 'from' date. Format: YYYY-MM-DD
to (string): 'to' date. Format: YYYY-MM-DD
q (string): search query
statuses (array of strings): Document statuses. Accepted values: importing, parsed, fail, new, quota, parsing, exception.
Inboxes
List inboxes
GET /inboxes
Delete an inbox
DELETE /inboxes/<inbox_id>
Extraction Schema
Create/edit an extraction schema
Updates or creates an extraction schema for a specific inbox. The schema defines how documents should be parsed and what data should be extracted.
POST /inboxes/<inbox_id>/schema
Request body:
fields: Array of field definitions
Response:
Returns
boolean- true if the schema was successfully updated, throws an error otherwise.
Field Types
The schema supports four types of fields:
1. Scalar Field
Used for single values like strings, numbers, or booleans.
{ "type": "scalar", "data": { "name": "total_amount", "description": "The total amount from the invoice", "type": "decimal", "default_value": "0.00" }}
Scalar field types:
`string`: Text values
`integer`: Whole numbers
`decimal`: Decimal numbers
`boolean`: True/false values
2. List Field
Used for arrays of objects with consistent structure.
{ "type": "list", "data": { "name": "line_items", "description": "List of items in the invoice", "attributes": [ { "name": "product_name", "description": "Name of the product", "type": "string", "default_value": "" }, { "name": "quantity", "description": "Quantity ordered", "type": "integer", "default_value": "0" } ] }}
3. Object Field
Similar to list but for single objects.
{ "type": "object", "data": { "name": "shipping_address", "description": "Shipping address details", "attributes": [ { "name": "street", "description": "Street address", "type": "string", "default_value": "" }, { "name": "city", "description": "City name", "type": "string", "default_value": "" } ] }}
4. Enum Field
Used for fields with a predefined set of possible values.
{ "type": "enum", "data": { "name": "status", "description": "Order status", "values": ["pending", "processing", "shipped", "delivered"] }}
Complete Example
{ "fields": [ { "type": "scalar", "data": { "name": "invoice_number", "description": "Invoice reference number", "type": "string", "default_value": "" } }, { "type": "list", "data": { "name": "items", "description": "List of items in the invoice", "attributes": [ { "name": "description", "description": "Item description", "type": "string", "default_value": "" }, { "name": "amount", "description": "Item amount", "type": "decimal", "default_value": "0.00" } ] } }, { "type": "enum", "data": { "name": "payment_status", "description": "Current payment status", "values": ["paid", "pending", "overdue"] } } ]}
Validation Rules
Field names must be 1-100 characters long and contain only lowercase letters, numbers, and underscores
Field names must be unique within the schema
Descriptions must not exceed 3000 characters
Default values must not exceed 400 characters
Enum values must be unique and 1-100 characters long
List and Object attributes must have unique names within their scope
All text fields are automatically trimmed
Error Responses
The API will return an error if:
The fields array is empty
Any field has an invalid type
Any field name is invalid or duplicate
Any description or default value exceeds length limits
Any enum has duplicate values or invalid value lengths
Clone an extraction schema between inboxes
POST /inboxes/<inbox_id>/schema-clone
Parameters:
inbox_id(path parameter): The source inbox from which the extraction schema will be cloned.
Request body:
destination_inbox_id: The target inbox where the extraction schema will be copied.
Response:
Returns:
booleanβ true if the schema was successfully cloned, otherwise false.