Developer API

Integrate invoice extraction directly into your applications. Submit files, initiate processing, and retrieve structured data through REST endpoints.

Getting Started

Generate an API token from your dashboard to authenticate your requests.

Each API call must include a bearer token in the Authorization header:

Authorization: Bearer YOUR_API_TOKEN

To obtain your token:

  1. Sign in to PayablesAgent
  2. Go to Settings > API
  3. Click "Generate New Token"
  4. Copy and store it securely (it will not be shown again)

Endpoints

Upload, extract, and retrieve results

Upload a Document

POST /api/documents/upload

Send a PDF or image file. Returns a file ID for use in the next step.

Request Body

Content-Type: multipart/form-data

{
"document": [file] // The invoice, receipt, or bill to process
}

Response

{
"success": true,
"message":"Upload complete",
"data": {
"file_id": 1234,
"name":"invoice.pdf"
 }
}

Start Extraction

POST /api/documents/extract

Initiate AI extraction on an uploaded file. Returns a hash for checking results.

Request Body

Content-Type: application/json

{
"file_id": 1234, // Required: from the upload response
"document_type_id": 5678 // Optional: use a specific template
}

Response

{
"success": true,
"message":"Extraction started",
"data": {
"extraction_id": 9876,
"extraction_hash":"abc123-def456-ghi789-jkl012"
 }
}

Get Results

GET /api/documents/extraction/{hash}

Retrieve the extracted data. Poll this endpoint until processing is complete.

Path Parameter

{hash}: The extraction_hash from the extract response

Response

{
"success": true,
"data": {
"extraction_id": 9876,
"extraction_hash":"abc123-def456-ghi789-jkl012",
"file": {
"id": 1234,
"name":"invoice.pdf"
 },
"document_type": {
"id": 5678,
"name":"Invoice"
 },
"fields": [
 {
"field_id": 101,
"content":"Vendor Name",
"value":"Acme Corp",
"is_table": false,
"page": 1
 },
 {
"field_id": 102,
"content":"Invoice Number",
"value":"INV-2024-0042",
"is_table": false,
"page": 1
 },
 {
"field_id": 103,
"content":"Invoice Date",
"value":"2024-03-15",
"is_table": false,
"page": 1
 },
 {
"field_id": 104,
"content":"Total",
"value":"$1,250.00",
"is_table": false,
"page": 1
 },
 {
"field_id": 105,
"content":"Line Items",
"is_table": true,
"page": 1,
"rows": [
 {
"cells": [
 {"value":"Widget A","is_header": false},
 {"value":"10","is_header": false},
 {"value":"$50.00","is_header": false},
 {"value":"$500.00","is_header": false}
 ]
 },
 {
"cells": [
 {"value":"Service B","is_header": false},
 {"value":"5","is_header": false},
 {"value":"$150.00","is_header": false},
 {"value":"$750.00","is_header": false}
 ]
 }
 ]
 }
 ]
 }
}

List Templates

GET /api/documents/types

Retrieve available document templates. Use these IDs when calling the extract endpoint.

Response

{
"success": true,
"data": [
 {
"id": 5678,
"name":"Invoice",
"description":"Standard vendor invoice extraction",
"is_public": true,
"fields_count": 10
 },
 {
"id": 5679,
"name":"Receipt",
"description":"Retail and expense receipt extraction",
"is_public": true,
"fields_count": 9
 }
 ]
}

Quick Start Examples

Copy these snippets to get up and running quickly

Three commands to extract invoice data

# Step 1: Upload your file
curl -X POST https://payablesagent.ai/api/documents/upload \
 -H"Authorization: Bearer YOUR_API_TOKEN"\
 -F" document=@/path/to/invoice.pdf"

# Step 2: Start extraction (use file_id from step 1)
curl -X POST https://payablesagent.ai/api/documents/extract \
 -H"Authorization: Bearer YOUR_API_TOKEN"\
 -H"Content-Type: application/json"\
 -d '{"file_id": 1234}'

# Step 3: Get results (use extraction_hash from step 2)
curl -X GET https://payablesagent.ai/api/documents/extraction/abc123-def456-ghi789-jkl012 \
 -H"Authorization: Bearer YOUR_API_TOKEN"

Full PHP integration

<?php

$token = 'YOUR_API_TOKEN';
$baseUrl = 'https://payablesagent.ai/api';

// Upload the invoice
$ch = curl_init("$baseUrl/documents/upload");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer $token"]);
curl_setopt($ch, CURLOPT_POSTFIELDS, [
 'document' => new CURLFile('/path/to/invoice.pdf')
]);

$uploadResponse = json_decode(curl_exec($ch), true);
curl_close($ch);

if (!$uploadResponse['success']) {
 die('Upload failed: ' . $uploadResponse['message']);
}

$fileId = $uploadResponse['data']['file_id'];
echo"Uploaded file ID: $fileId\n";

// Start extraction
$ch = curl_init("$baseUrl/documents/extract");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer $token",
"Content-Type: application/json"
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['file_id' => $fileId]));

$extractResponse = json_decode(curl_exec($ch), true);
curl_close($ch);

if (!$extractResponse['success']) {
 die('Extraction failed: ' . $extractResponse['message']);
}

$hash = $extractResponse['data']['extraction_hash'];
echo"Extraction hash: $hash\n";

// Fetch results
$ch = curl_init("$baseUrl/documents/extraction/$hash");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer $token"]);

$results = json_decode(curl_exec($ch), true);
curl_close($ch);

// Display extracted fields
foreach ($results['data']['fields'] as $field) {
 echo"{$field['content']}: {$field['value']}\n";
}

JavaScript / Node.js integration

const API_TOKEN = 'YOUR_API_TOKEN';
const BASE_URL = 'https://payablesagent.ai/api';

async function extractInvoice(file) {
 // Step 1: Upload
 const formData = new FormData();
 formData.append('document', file);

 const uploadRes = await fetch(`${BASE_URL}/documents/upload`, {
 method: 'POST',
 headers: { 'Authorization': `Bearer ${API_TOKEN}` },
 body: formData
 });
 const uploadData = await uploadRes.json();

 if (!uploadData.success) throw new Error(uploadData.message);
 console.log('File ID:', uploadData.data.file_id);

 // Step 2: Extract
 const extractRes = await fetch(`${BASE_URL}/documents/extract`, {
 method: 'POST',
 headers: {
 'Authorization': `Bearer ${API_TOKEN}`,
 'Content-Type': 'application/json'
 },
 body: JSON.stringify({ file_id: uploadData.data.file_id })
 });
 const extractData = await extractRes.json();

 if (!extractData.success) throw new Error(extractData.message);
 console.log('Extraction hash:', extractData.data.extraction_hash);

 // Step 3: Get results (may need polling for large files)
 const resultsRes = await fetch(
 `${BASE_URL}/documents/extraction/${extractData.data.extraction_hash}`,
 { headers: { 'Authorization': `Bearer ${API_TOKEN}` } }
 );
 const results = await resultsRes.json();

 // Return structured data
 return results.data.fields.reduce((acc, field) => {
 acc[field.content] = field.is_table ? field.rows : field.value;
 return acc;
 }, {});
}

// Usage with file input
document.querySelector('#invoice-input').addEventListener('change', async (e) => {
 const file = e.target.files[0];
 const data = await extractInvoice(file);
 console.log('Extracted:', data);
});

Python integration

import requests
import time

API_TOKEN = 'YOUR_API_TOKEN'
BASE_URL = 'https://payablesagent.ai/api'

def extract_invoice(file_path):
 headers = {'Authorization': f'Bearer {API_TOKEN}'}

 # Step 1: Upload
 with open(file_path, 'rb') as f:
 upload_res = requests.post(
 f'{BASE_URL}/documents/upload',
 headers=headers,
 files={'document': f}
 )

 upload_data = upload_res.json()
 if not upload_data.get('success'):
 raise Exception(f"Upload failed: {upload_data.get('message')}")

 file_id = upload_data['data']['file_id']
 print(f"File ID: {file_id}")

 # Step 2: Start extraction
 extract_res = requests.post(
 f'{BASE_URL}/documents/extract',
 headers={**headers, 'Content-Type': 'application/json'},
 json={'file_id': file_id}
 )

 extract_data = extract_res.json()
 if not extract_data.get('success'):
 raise Exception(f"Extraction failed: {extract_data.get('message')}")

 hash_id = extract_data['data']['extraction_hash']
 print(f"Extraction hash: {hash_id}")

 # Step 3: Poll for results
 time.sleep(2) # Wait for processing

 results_res = requests.get(
 f'{BASE_URL}/documents/extraction/{hash_id}',
 headers=headers
 )

 results = results_res.json()

 # Return as dictionary
 extracted = {}
 for field in results['data']['fields']:
 extracted[field['content']] = field.get('rows') if field['is_table'] else field['value']

 return extracted

# Run it
if __name__ == '__main__':
 data = extract_invoice('/path/to/invoice.pdf')
 print(data)

Limits & Help

What to expect and where to find assistance

Rate Limits

Pro accounts: 500 requests per hour. If you exceed the limit, you will receive a 429 response containing a Retry-After header.

Need Help?

Questions about integration or running into an issue?