Invoice Scanner API
Welcome to the Invoice Scanner API documentation. Our API allows you to programmatically scan, extract, and manage invoice data from PDF and image files.
Base URL: https://invoicescan.eu/api
Authentication
The Invoice Scanner API uses API keys to authenticate requests. You can generate API keys from your dashboard.
Using API Keys
Include your API key in the request header:
curl https://invoicescan.eu/api/invoices \
-H "X-API-Key: sk_your_api_key_here"
Important: Keep your API keys secure. Do not share them in publicly accessible areas such as GitHub, client-side code, etc.
Rate Limits
API rate limits are based on your subscription plan:
| Plan | Scans/Month | Price |
|---|---|---|
| Free | 10 | $0 |
| Pro | 1,000 | $49 |
| Ultimate | 10,000 | $99 |
| Unlimited | 100,000 | $199 |
Error Handling
The API uses conventional HTTP response codes to indicate success or failure:
200
Success - Request completed successfully
400
Bad Request - Invalid parameters
401
Unauthorized - Invalid or missing API key
403
Forbidden - Subscription limit exceeded
404
Not Found - Resource not found
500
Server Error - Something went wrong on our end
Error Response Format
{
"message": "Subscription limit exceeded",
"errors": {
"scans": ["You have used 10/10 scans this month"]
}
}
Upload Invoice
Upload an invoice file (PDF, JPG, PNG, DOC, DOCX) for processing. The API will extract structured data from the invoice.
Endpoint
POST /api/invoices
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| file | file | Yes | Invoice file (PDF, JPG, PNG, DOC, DOCX, max 10MB) |
| company_id | integer | No | Existing company ID to assign invoice to |
| company_name | string | No | Company name to find or create |
| company_vat_id | string | No | Company VAT ID to find or create (highest priority match) |
| company_tax_id | string | No | Company Tax ID to find or create |
| auto_create_company | boolean | No | Auto-create company if not found (default: false) |
| vendor_id | integer | No | Vendor ID to assign to invoice |
| type | string | No | Invoice type (e.g., 'purchase', 'sales') |
| is_hard_scan | boolean | No | Mark as hard scan (requires manual review) |
| webhook_url | string | No | URL to receive webhook notification when processing completes |
Example Request
curl -X POST https://invoicescan.eu/api/invoices \
-H "X-API-Key: sk_your_api_key_here" \
-F "file=@/path/to/invoice.pdf" \
-F "company_vat_id=BG123456789" \
-F "auto_create_company=true" \
-F "webhook_url=https://your-app.com/webhook"
Response (202 Accepted)
{
"message": "Invoice uploaded successfully",
"job_id": "019a7307-ec8a-72c4-9b3c-1b2ce9196b10",
"status": "pending"
}
Get Invoice
Retrieve the processing status and extracted data for a specific invoice.
Endpoint
GET /api/invoices/{id}
Example Request
curl https://invoicescan.eu/api/invoices/019a7307-ec8a-72c4-9b3c-1b2ce9196b10 \
-H "X-API-Key: sk_your_api_key_here"
Response (200 OK)
{
"job_id": "019a7307-ec8a-72c4-9b3c-1b2ce9196b10",
"status": "completed",
"result": {
"invoice_number": "082000530981",
"invoice_date": "15/10/2025",
"vendor_name": "Hetzner Online GmbH",
"vendor_address": "Industriestr. 25, 91710 Gunzenhausen, Germany",
"customer_name": "MICROWEBER FINANCE EOOD",
"customer_address": "Mr. Peter Ivanov, Bratq Chakrin 10, 1000 Sofia, Bulgaria",
"line_items": [
{
"description": "AX41-NVMe Dedicated Server",
"quantity": 288,
"unit_price": "€0.0571",
"total": "€16.4448"
}
],
"subtotal": "€310.42",
"tax": "€0.00",
"grand_total": "€310.42"
},
"error": null,
"created_at": "2025-11-11T13:08:10Z",
"updated_at": "2025-11-11T13:09:45Z"
}
List Invoices
Retrieve a paginated list of all your invoices with optional filtering.
Endpoint
GET /api/invoices
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| page | integer | Page number (default: 1) |
| per_page | integer | Results per page (default: 20) |
| company_id | integer | Filter by company ID |
| company_name | string | Filter by company name (partial match) |
| company_vat_id | string | Filter by company VAT ID (normalized match) |
| company_tax_id | string | Filter by company Tax ID |
| vendor_id | integer | Filter by vendor ID |
| status | string | Filter by status: pending, processing, completed, failed |
| exclude_status | string | Exclude specific status |
| type | string | Filter by invoice type |
| is_checked | boolean | Filter by checked status (true/false) |
| date_from | date | Filter invoices from date (YYYY-MM-DD) |
| date_to | date | Filter invoices to date (YYYY-MM-DD) |
| sort | string | Sort field (created_at, updated_at) |
| order | string | Sort order (asc, desc) |
Example Request
curl "https://invoicescan.eu/api/invoices?page=1&status=completed&company_vat_id=BG123456789" \
-H "X-API-Key: sk_your_api_key_here"
Response (200 OK)
{
"data": [
{
"job_id": "019a7307-ec8a-72c4-9b3c-1b2ce9196b10",
"status": "completed",
"session_id": null,
"created_at": "2025-11-11T13:08:10Z",
"updated_at": "2025-11-11T13:09:45Z"
}
],
"meta": {
"current_page": 1,
"last_page": 1,
"per_page": 20,
"total": 1
}
}
Delete Invoice
Delete a specific invoice by its job ID.
Endpoint
DELETE /api/invoices/{id}
Example Request
curl -X DELETE https://invoicescan.eu/api/invoices/019a7307-ec8a-72c4-9b3c-1b2ce9196b10 \
-H "X-API-Key: sk_your_api_key_here"
Response (200 OK)
{
"message": "Invoice deleted successfully"
}
Scan Invoice (Synchronous)
Upload and process an invoice synchronously. This endpoint waits for processing to complete and returns the extracted data immediately. Maximum wait time is configurable.
Endpoint
POST /api/invoices
Note: This is the same endpoint as async upload. The client polls the status endpoint automatically until completion or timeout.
Example Request
curl -X POST https://invoicescan.eu/api/invoices \
-H "X-API-Key: sk_your_api_key_here" \
-F "file=@/path/to/invoice.pdf"
# Then poll for results
curl https://invoicescan.eu/api/invoices/{job_id} \
-H "X-API-Key: sk_your_api_key_here"
Generate QR Code
Generate a QR code that redirects to the invoice scanner. Optionally link to a specific company.
Endpoint
POST /api/invoices/qr
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
| company_id | integer | No | Company ID to link QR code to (optional) |
Example Request
curl -X POST https://invoicescan.eu/api/invoices/qr \
-H "X-API-Key: sk_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"company_id": 1}'
Returns an SVG QR code image that can be displayed or saved.
Response
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="200" height="200">
<!-- QR Code SVG content -->
</svg>
List Companies
Retrieve a paginated list of all companies associated with your account.
Endpoint
GET /api/companies
Example Request
curl https://invoicescan.eu/api/companies \
-H "X-API-Key: sk_your_api_key_here"
Response (200 OK)
{
"data": [
{
"id": 1,
"name": "ACME Corporation",
"vat_number": "BG123456789",
"address": "123 Business St",
"created_at": "2025-01-01T00:00:00Z",
"updated_at": "2025-01-01T00:00:00Z"
}
],
"meta": {
"current_page": 1,
"last_page": 1,
"per_page": 20,
"total": 1
}
}
Create Company
Create a new company in your account.
Endpoint
POST /api/companies
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Company name |
| vat_number | string | No | VAT/Tax identification number |
| address | string | No | Company address |
Example Request
curl -X POST https://invoicescan.eu/api/companies \
-H "X-API-Key: sk_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"name": "ACME Corporation",
"vat_number": "BG123456789",
"address": "123 Business St, Sofia, Bulgaria"
}'
Response (201 Created)
{
"id": 1,
"name": "ACME Corporation",
"vat_number": "BG123456789",
"address": "123 Business St, Sofia, Bulgaria",
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-01-15T10:30:00Z"
}
Update Company
Update an existing company's information.
Endpoint
PUT /api/companies/{id}
Example Request
curl -X PUT https://invoicescan.eu/api/companies/1 \
-H "X-API-Key: sk_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"name": "ACME Corp Updated"
}'
Get Company
Retrieve details of a specific company by ID.
Endpoint
GET /api/companies/{id}
Example Request
curl https://invoicescan.eu/api/companies/1 \
-H "X-API-Key: sk_your_api_key_here"
Response (200 OK)
{
"id": 1,
"name": "ACME Corporation",
"vat_number": "BG123456789",
"tax_id": "123456789",
"address": "123 Business St, Sofia, Bulgaria",
"email": null,
"phone": null,
"is_active": true,
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-01-15T10:30:00Z"
}
Update Company
Update an existing company's information.
Endpoint
PUT /api/companies/{id}
Example Request
curl -X PUT https://invoicescan.eu/api/companies/1 \
-H "X-API-Key: sk_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"name": "ACME Corp Updated",
"email": "contact@acmecorp.com"
}'
Delete Company
Delete a company from your account.
Endpoint
DELETE /api/companies/{id}
Example Request
curl -X DELETE https://invoicescan.eu/api/companies/1 \
-H "X-API-Key: sk_your_api_key_here"
Get Company Invoices
Get all invoices associated with a specific company.
Endpoint
GET /api/companies/{company_id}/invoices
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| status | string | Filter by status (pending, processing, completed, failed) |
| page | integer | Page number (default: 1) |
| per_page | integer | Results per page (default: 20) |
| sort_by | string | Sort field (default: created_at) |
| sort_order | string | Sort order: asc or desc (default: desc) |
Example Request
curl "https://invoicescan.eu/api/companies/1/invoices?status=completed&page=1" \
-H "X-API-Key: sk_your_api_key_here"
Response (200 OK)
{
"data": [
{
"job_id": "019a7307-ec8a-72c4-9b3c-1b2ce9196b10",
"status": "completed",
"company_id": 1,
"created_at": "2025-11-11T13:08:10Z",
"updated_at": "2025-11-11T13:09:45Z",
"result": {
"invoice_number": "INV-2025-001",
"grand_total": "€1,200.00",
"..."
}
}
],
"meta": {
"current_page": 1,
"last_page": 3,
"per_page": 20,
"total": 57
}
}
Extract Company Data
Extract company information from a document using AI (e.g., business card, letterhead).
Endpoint
POST /api/companies/extract
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| file | file | Yes | Document file (PDF, JPG, PNG, max 10MB) |
Example Request
curl -X POST https://invoicescan.eu/api/companies/extract \
-H "X-API-Key: sk_your_api_key_here" \
-F "file=@business_card.jpg"
Response (200 OK)
{
"name": "Extracted Company Ltd",
"vat_number": "BG123456789",
"address": "123 Business Street, Sofia",
"email": "contact@extracted.com",
"phone": "+359 2 123 4567",
"website": "https://extracted.com"
}
List Vendors
Get all vendors for a specific company.
Endpoint
GET /api/companies/{company_id}/vendors
Example Request
curl https://invoicescan.eu/api/companies/1/vendors \
-H "X-API-Key: sk_your_api_key_here"
Create Vendor
Add a new vendor to a company.
Endpoint
POST /api/companies/{company_id}/vendors
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
| vendor_name | string | Yes | Vendor name |
| vendor_vat | string | No | VAT number |
| vendor_address | string | No | Vendor address |
Example Request
curl -X POST https://invoicescan.eu/api/companies/1/vendors \
-H "X-API-Key: sk_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"vendor_name": "Office Supplies Inc",
"vendor_vat": "VAT123456"
}'
📊 Account Codes & Document Classification
🔍 Overview
Our system provides powerful invoice classification using two separate but complementary systems:
user-defined account_code and
AI-extracted document_code.
👤 Your Account Codes
What: Your company's custom accounting classification system
- User-defined - You create and manage these codes
- Company-specific - Different for each company
- Examples: "60101" (Materials), "60201" (Goods), "6000" (Expenses)
- Purpose: Internal categorization for your accounting system
🤖 AI Document Codes
What: Automatic classification based on Bulgarian Chart of Accounts
- AI-extracted - Automatically determined from invoice content
- Standardized - Based on Bulgarian accounting standards (Сметкоплан)
- Examples: "601" (Materials), "602" (Goods), "704" (Services)
- Cannot be changed - Reflects the invoice's actual nature
🎯 Key Concepts
account_code (User-Defined)
Your custom accounting codes for categorizing invoices in your system. You create and manage these via the API endpoints below. They can be linked to:
internal_code- Internal SKU/material codes for warehouse integrationbarcode_mapping- Array of barcodes to automatically categorize productsdescription_mapping- Product descriptions for text-based matchingcategory- Additional categorization field
document_code (AI-Extracted)
Automatically extracted by our AI analyzing the invoice content against the Bulgarian Chart of Accounts. The AI considers:
- Line item descriptions and nature
- Transaction type (purchase, sale, expense)
- Bulgarian accounting classification standards
- Industry-specific patterns
Note: This field is automatically determined and cannot be manually set or changed. It reflects the true accounting nature of the transaction.
document_type_code (Bulgarian VAT)
Bulgarian VAT document classification (also AI-determined):
01- Фактура (Standard Invoice)02- Дебитно известие (Debit Note)03- Кредитно известие (Credit Note)11- Фактура при касов метод (Cash-basis Invoice)12- Дебитно известие при касов метод (Cash-basis Debit Note)13- Кредитно известие при касов метод (Cash-basis Credit Note)
📦 Material & Goods Inventory Codes
Question: "При покупка на материали и стоки, които ще се заприхождават в склад има ли някаква функционалност, за настройка на кодове на материали и стоки?"
Answer: Yes! The CompanyAccountCode
model supports extensive warehouse/inventory functionality through these fields:
internal_code
Internal SKU or material code for your warehouse system. Maps your account codes to specific products/materials in your inventory.
barcode_mapping
Array of barcodes. When an invoice line item has a matching barcode, it's automatically categorized to this account code.
description_mapping
Array of product descriptions for text-based matching. Automatically assigns account codes based on product names.
barcode_internal_code_mapping
Direct mapping from barcodes to internal codes, enabling complex warehouse/ERP integrations.
💡 Example: Create an account code "60101" (Materials) with
internal_code: "MAT-001" and
barcode_mapping: ["4820024700016", "4820024700023"].
When an invoice contains these barcodes, the system can automatically categorize and map to your warehouse inventory.
📋 JSON Response Fields Explanation
When you retrieve an invoice, the response includes these classification fields:
{
"job_id": "019c763c-3196-706f-83eb-ca2f585f62f9",
"status": "completed",
"result": {
// AI-Extracted Classification (Bulgarian Standards)
"document_code": "601",
"document_code_description": "Разходи за материали",
"document_code_group": "60 - Operating Expenses",
"document_code_confidence": 0.95,
"document_code_reasoning": "Line items contain materials...",
// Bulgarian VAT Classification
"document_type_code": "01",
"document_type_description": "Фактура",
// Invoice Details
"invoice_number": "INV-2025-001",
"invoice_date": "2025-01-15",
"vendor_name": "Supplier Ltd",
"grand_total": "€1,200.00",
// Line Items (may include your account codes if mapped)
"line_items": [
{
"description": "Office Materials",
"quantity": 10,
"unit_price": "€100.00",
"total": "€1,000.00",
"account_code": "60101" // Your custom code (if mapped)
}
]
}
}
🔄 Typical Workflow
-
Create Company: Set up your company via
POST /api/companies -
Define Account Codes: Create your accounting structure via
POST /api/companies/{id}/account-codes- Add
internal_codefor warehouse SKUs - Add
barcode_mappingfor automatic product categorization - Add
description_mappingfor text-based matching
- Add
-
Upload Invoices: Upload PDFs via
POST /api/invoices -
AI Processing: System automatically extracts
document_code(Bulgarian standard) and attempts to match your customaccount_codevia barcode/description mapping - Retrieve Results: Get structured data with both AI classification and your custom codes
List Account Codes
Get all account codes for a specific company.
Endpoint
GET /api/companies/{company_id}/account-codes
Example Request
curl https://invoicescan.eu/api/companies/1/account-codes \
-H "X-API-Key: sk_your_api_key_here"
Create Account Code
Add a new account code to a company.
Endpoint
POST /api/companies/{company_id}/account-codes
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
| account_code | string | Yes | Account code number |
| account_name | string | Yes | Account name/description |
| account_type | string | Yes | Type: expense, revenue, asset, liability |
Example Request
curl -X POST https://invoicescan.eu/api/companies/1/account-codes \
-H "X-API-Key: sk_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"account_code": "6000",
"account_name": "Office Supplies",
"account_type": "expense"
}'
Bulk Import Account Codes
Import multiple account codes at once from tab-separated text.
Endpoint
POST /api/companies/{company_id}/account-codes/bulk-import
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
| pasted_text | string | Yes | Tab-separated account codes (code\tname per line) |
Example Request
curl -X POST https://invoicescan.eu/api/companies/1/account-codes/bulk-import \
-H "X-API-Key: sk_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"pasted_text": "100\tCash\n200\tBank\n300\tAccounts Receivable"
}'
Bulk Delete Account Codes
Delete multiple account codes at once.
Endpoint
POST /api/companies/{company_id}/account-codes/bulk-delete
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
| ids | array | Yes | Array of account code IDs to delete |
Example Request
curl -X POST https://invoicescan.eu/api/companies/1/account-codes/bulk-delete \
-H "X-API-Key: sk_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"ids": [1, 2, 3, 4, 5]
}'
PHP SDK Example
Example using PHP to upload and process an invoice:
<?php
$apiKey = 'sk_your_api_key_here';
$apiUrl = 'https://invoicescan.eu/api/invoices';
// Upload invoice
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => $apiUrl,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'X-API-Key: ' . $apiKey,
],
CURLOPT_POSTFIELDS => [
'file' => new CURLFile('/path/to/invoice.pdf'),
'webhook_url' => 'https://your-app.com/webhook',
],
]);
$response = curl_exec($curl);
$result = json_decode($response, true);
curl_close($curl);
// Get job_id
$jobId = $result['job_id'];
// Poll for result
$maxAttempts = 30;
for ($i = 0; $i < $maxAttempts; $i++) {
sleep(2);
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => $apiUrl . '/' . $jobId,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'X-API-Key: ' . $apiKey,
],
]);
$response = curl_exec($curl);
$result = json_decode($response, true);
curl_close($curl);
if ($result['status'] === 'completed') {
print_r($result['result']);
break;
}
}
Analyze PDF File
Analyze a PDF file and extract each page as a base64 encoded image. This endpoint processes PDF files page-by-page and returns high-quality image representations of each page.
Endpoint
POST /api/invoices-file-analyze
Authentication
This endpoint requires authentication via Sanctum (session-based auth).
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| file | file | Yes | PDF file to analyze (max 10MB) |
| scale | number | No | Rendering scale (0.5 to 4.0, default: 2.0) |
| format | string | No | Output format: jpeg or png (default: jpeg) |
| quality | number | No | Image quality (0.1 to 1.0, default: 0.85) |
Example Request (cURL)
curl -X POST https://invoicescan.eu/api/invoices-file-analyze \
-H "Accept: application/json" \
-H "Cookie: your-session-cookie" \
-F "file=@/path/to/document.pdf" \
-F "scale=2.0" \
-F "format=jpeg" \
-F "quality=0.85"
Example Request (JavaScript)
const formData = new FormData();
formData.append('file', pdfFile);
formData.append('scale', 2.0);
formData.append('format', 'jpeg');
formData.append('quality', 0.85);
const response = await fetch('/api/invoices-file-analyze', {
method: 'POST',
headers: {
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
},
credentials: 'include',
body: formData
});
const result = await response.json();
console.log(result);
Success Response (200 OK)
{
"success": true,
"numPages": 3,
"pages": [
{
"pageNumber": 1,
"width": 1654,
"height": 2339,
"image": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD..."
},
{
"pageNumber": 2,
"width": 1654,
"height": 2339,
"image": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD..."
},
{
"pageNumber": 3,
"width": 1654,
"height": 2339,
"image": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD..."
}
]
}
Error Response (500 Internal Server Error)
{
"success": false,
"error": "Failed to analyze PDF",
"details": "Error message details..."
}
💡 Use Cases
- Preview PDF pages before processing
- Extract visual content for OCR processing
- Generate thumbnails for PDF documents
- Create image-based PDF viewers
- Backend image processing and analysis
⚠️ Important Notes
- Maximum file size: 10MB
- Only PDF files are supported
- Higher scale values produce larger images
- JPEG format is recommended for smaller file sizes
- Processing time increases with page count and scale