πŸ‘¨β€πŸ’» 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.


Was this article helpful?