ZUGFeRD & XRechnung Validator API
Send the URL of a ZUGFeRD, Factur-X or XRechnung PDF and get every rule it breaks — PDF/A-3 and the EN 16931 and XRechnung rules, each with its code.
- Free plan
- No credit card
Request
curl -X POST https://apdf.io/api/pdf/einvoice/validate \
-H "Authorization: Bearer TOKEN" \
-d file="FILE_URL"
const data = new FormData();
data.append('file', 'FILE_URL');
fetch('https://apdf.io/api/pdf/einvoice/validate', {
headers: {'Authorization': 'Bearer TOKEN'},
method: 'POST',
body: data
})
.then(response => response.json())
.then(json => console.log(json));
use GuzzleHttp\Client;
$client = new Client();
$response = $client->post(
'https://apdf.io/api/pdf/einvoice/validate', [
'headers' => [
'Authorization' => 'Bearer TOKEN'
],
'form_params' => [
'file' => 'FILE_URL'
]
]);
$body = $response->getBody();
echo json_encode($body->getContents());
require 'rest-client'
response = RestClient.post(
'https://apdf.io/api/pdf/einvoice/validate',
{
'file' => 'FILE_URL'
},
{
Authorization: "Bearer TOKEN"
}
)
puts response.body
import requests
response = requests.post(
'https://apdf.io/api/pdf/einvoice/validate',
headers = {
'Authorization': 'Bearer TOKEN'
},
data = {
'file': 'FILE_URL'
}
)
print(response.text)
import (
"fmt"
"github.com/go-resty/resty/v2"
)
func main() {
client := resty.New()
data := map[string]string{
"file": "FILE_URL"
}
resp, _ := client.R().
SetFormData(data).
SetHeader("Authorization", "Bearer TOKEN").
Post("https://apdf.io/api/pdf/einvoice/validate")
fmt.Println(resp.String())
}
import okhttp3.*;
class Pdf {
public static void main(String[] args) throws Exception {
OkHttpClient client = new OkHttpClient();
FormBody formBody = new FormBody.Builder()
.add("file", "FILE_URL")
.build();
Request request = new Request.Builder()
.url("https://apdf.io/api/pdf/einvoice/validate")
.addHeader("Authorization", "Bearer TOKEN")
.post(formBody)
.build();
Response response = client.newCall(request).execute();
System.out.println(response.body().string());
}
}
Every rule.
Before it counts.
An e-invoice has to be a valid archive PDF and a valid invoice.
Both are checked, and each finding names the rule it breaks.
rule is the code of the standard, so the fix is one search away.
- PDF/A-3
- The archive format every e-invoice uses
- Schema
- The XML against the schema of its profile
- EN 16931
- The business rules of the European standard
- Factur-X
- The rules of the ZUGFeRD / Factur-X profile
- XRechnung
- The German rules, for XRECHNUNG invoices
Catch it before they do.
A rejected e-invoice comes back when payment is already late. Check it the moment it is made or arrives.
Check before sending
Validate every invoice your billing makes before it goes out, so no customer has to send one back.
Check what arrives
Validate the e-invoices suppliers send before you book them, and reply with the exact rule broken.
Test your own generator
Run the files your own e-invoice code makes through the same checks, with rule codes to look up.
Archive with confidence
Know that what you store is a valid archive PDF with a valid invoice inside, not just any PDF.
Validate from anywhere.
Check every e-invoice where it is made or where it arrives.
One account and one monthly allowance behind every route.
One authenticated POST from any language. Copy-paste samples in cURL, Node.js, Python and more.
POST /api/pdf/einvoice/validate
Pick the action in any Zap and map files from earlier steps. No code and no servers to run.
Validate E-Invoice
Add the Apdf node to any workflow, on n8n Cloud or self-hosted, and chain it with your automation.
Validate electronic invoice
Let Claude, ChatGPT, Gemini or your own agent run it through the MCP server, on any paid plan.
validate-e-invoice
1,000 validations
a month. Free.
Start on the free plan and move up only when your volume does — up to 1,000,000 operations a month on Business.
- One call is one operation, however many pages.
- Only calls that do the work are counted.
- Hard limits, so no surprise overage charges.
Validating e-invoices, answered
Your code made the PDF.
Then it went dark.
Opened, read, signed or ignored — you never see any of it. Send the PDFs you generate as personal links, and every open, page read, comment and signature comes back to your software as a webhook. Need it signed? Same link. Same account, same API key, one more call.
API · Webhook · MCP