ZUGFeRD & XRechnung API
Send your PDF invoice and its data, get a ZUGFeRD / Factur-X e-invoice back — totals calculated and checked against its profile, XRechnung included.
- Free plan
- No credit card
Request
curl -X POST https://apdf.io/api/pdf/einvoice/create \
-H "Authorization: Bearer TOKEN" \
-d file="FILE_URL" \
-d invoice[number]="RE-2026-0042" \
-d invoice[issue_date]="2026-11-11" \
-d invoice[due_date]="2026-11-25" \
-d invoice[currency]="EUR" \
-d invoice[seller][name]="Acme GmbH" \
-d invoice[seller][vat_id]="DE123456789" \
-d invoice[seller][address][line1]="Hauptstraße 1" \
-d invoice[seller][address][city]="Berlin" \
-d invoice[seller][address][postcode]="10115" \
-d invoice[seller][address][country]="DE" \
-d invoice[buyer][name]="Contoso AG" \
-d invoice[buyer][address][line1]="Am Markt 5" \
-d invoice[buyer][address][city]="Hamburg" \
-d invoice[buyer][address][postcode]="20095" \
-d invoice[buyer][address][country]="DE" \
-d invoice[payment][iban]="DE02120300000000202051" \
-d invoice[lines][0][name]="Consulting" \
-d invoice[lines][0][quantity]="8" \
-d invoice[lines][0][unit]="HUR" \
-d invoice[lines][0][unit_price]="120" \
-d invoice[lines][0][vat_rate]="19" \
-d invoice[charges][0][amount]="4.95" \
-d invoice[charges][0][reason]="Shipping" \
-d invoice[charges][0][vat_rate]="19"
const data = new FormData();
data.append('file', 'FILE_URL');
data.append('invoice[number]', 'RE-2026-0042');
data.append('invoice[issue_date]', '2026-11-11');
data.append('invoice[due_date]', '2026-11-25');
data.append('invoice[currency]', 'EUR');
data.append('invoice[seller][name]', 'Acme GmbH');
data.append('invoice[seller][vat_id]', 'DE123456789');
data.append('invoice[seller][address][line1]', 'Hauptstraße 1');
data.append('invoice[seller][address][city]', 'Berlin');
data.append('invoice[seller][address][postcode]', '10115');
data.append('invoice[seller][address][country]', 'DE');
data.append('invoice[buyer][name]', 'Contoso AG');
data.append('invoice[buyer][address][line1]', 'Am Markt 5');
data.append('invoice[buyer][address][city]', 'Hamburg');
data.append('invoice[buyer][address][postcode]', '20095');
data.append('invoice[buyer][address][country]', 'DE');
data.append('invoice[payment][iban]', 'DE02120300000000202051');
data.append('invoice[lines][0][name]', 'Consulting');
data.append('invoice[lines][0][quantity]', '8');
data.append('invoice[lines][0][unit]', 'HUR');
data.append('invoice[lines][0][unit_price]', '120');
data.append('invoice[lines][0][vat_rate]', '19');
data.append('invoice[charges][0][amount]', '4.95');
data.append('invoice[charges][0][reason]', 'Shipping');
data.append('invoice[charges][0][vat_rate]', '19');
fetch('https://apdf.io/api/pdf/einvoice/create', {
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/create', [
'headers' => [
'Authorization' => 'Bearer TOKEN'
],
'form_params' => [
'file' => 'FILE_URL',
'invoice[number]' => 'RE-2026-0042',
'invoice[issue_date]' => '2026-11-11',
'invoice[due_date]' => '2026-11-25',
'invoice[currency]' => 'EUR',
'invoice[seller][name]' => 'Acme GmbH',
'invoice[seller][vat_id]' => 'DE123456789',
'invoice[seller][address][line1]' => 'Hauptstraße 1',
'invoice[seller][address][city]' => 'Berlin',
'invoice[seller][address][postcode]' => '10115',
'invoice[seller][address][country]' => 'DE',
'invoice[buyer][name]' => 'Contoso AG',
'invoice[buyer][address][line1]' => 'Am Markt 5',
'invoice[buyer][address][city]' => 'Hamburg',
'invoice[buyer][address][postcode]' => '20095',
'invoice[buyer][address][country]' => 'DE',
'invoice[payment][iban]' => 'DE02120300000000202051',
'invoice[lines][0][name]' => 'Consulting',
'invoice[lines][0][quantity]' => '8',
'invoice[lines][0][unit]' => 'HUR',
'invoice[lines][0][unit_price]' => '120',
'invoice[lines][0][vat_rate]' => '19',
'invoice[charges][0][amount]' => '4.95',
'invoice[charges][0][reason]' => 'Shipping',
'invoice[charges][0][vat_rate]' => '19'
]
]);
$body = $response->getBody();
echo json_encode($body->getContents());
require 'rest-client'
response = RestClient.post(
'https://apdf.io/api/pdf/einvoice/create',
{
'file' => 'FILE_URL',
'invoice[number]' => 'RE-2026-0042',
'invoice[issue_date]' => '2026-11-11',
'invoice[due_date]' => '2026-11-25',
'invoice[currency]' => 'EUR',
'invoice[seller][name]' => 'Acme GmbH',
'invoice[seller][vat_id]' => 'DE123456789',
'invoice[seller][address][line1]' => 'Hauptstraße 1',
'invoice[seller][address][city]' => 'Berlin',
'invoice[seller][address][postcode]' => '10115',
'invoice[seller][address][country]' => 'DE',
'invoice[buyer][name]' => 'Contoso AG',
'invoice[buyer][address][line1]' => 'Am Markt 5',
'invoice[buyer][address][city]' => 'Hamburg',
'invoice[buyer][address][postcode]' => '20095',
'invoice[buyer][address][country]' => 'DE',
'invoice[payment][iban]' => 'DE02120300000000202051',
'invoice[lines][0][name]' => 'Consulting',
'invoice[lines][0][quantity]' => '8',
'invoice[lines][0][unit]' => 'HUR',
'invoice[lines][0][unit_price]' => '120',
'invoice[lines][0][vat_rate]' => '19',
'invoice[charges][0][amount]' => '4.95',
'invoice[charges][0][reason]' => 'Shipping',
'invoice[charges][0][vat_rate]' => '19'
},
{
Authorization: "Bearer TOKEN"
}
)
puts response.body
import requests
response = requests.post(
'https://apdf.io/api/pdf/einvoice/create',
headers = {
'Authorization': 'Bearer TOKEN'
},
data = {
'file': 'FILE_URL',
'invoice[number]': 'RE-2026-0042',
'invoice[issue_date]': '2026-11-11',
'invoice[due_date]': '2026-11-25',
'invoice[currency]': 'EUR',
'invoice[seller][name]': 'Acme GmbH',
'invoice[seller][vat_id]': 'DE123456789',
'invoice[seller][address][line1]': 'Hauptstraße 1',
'invoice[seller][address][city]': 'Berlin',
'invoice[seller][address][postcode]': '10115',
'invoice[seller][address][country]': 'DE',
'invoice[buyer][name]': 'Contoso AG',
'invoice[buyer][address][line1]': 'Am Markt 5',
'invoice[buyer][address][city]': 'Hamburg',
'invoice[buyer][address][postcode]': '20095',
'invoice[buyer][address][country]': 'DE',
'invoice[payment][iban]': 'DE02120300000000202051',
'invoice[lines][0][name]': 'Consulting',
'invoice[lines][0][quantity]': '8',
'invoice[lines][0][unit]': 'HUR',
'invoice[lines][0][unit_price]': '120',
'invoice[lines][0][vat_rate]': '19',
'invoice[charges][0][amount]': '4.95',
'invoice[charges][0][reason]': 'Shipping',
'invoice[charges][0][vat_rate]': '19'
}
)
print(response.text)
import (
"fmt"
"github.com/go-resty/resty/v2"
)
func main() {
client := resty.New()
data := map[string]string{
"file": "FILE_URL",
"invoice[number]": "RE-2026-0042",
"invoice[issue_date]": "2026-11-11",
"invoice[due_date]": "2026-11-25",
"invoice[currency]": "EUR",
"invoice[seller][name]": "Acme GmbH",
"invoice[seller][vat_id]": "DE123456789",
"invoice[seller][address][line1]": "Hauptstraße 1",
"invoice[seller][address][city]": "Berlin",
"invoice[seller][address][postcode]": "10115",
"invoice[seller][address][country]": "DE",
"invoice[buyer][name]": "Contoso AG",
"invoice[buyer][address][line1]": "Am Markt 5",
"invoice[buyer][address][city]": "Hamburg",
"invoice[buyer][address][postcode]": "20095",
"invoice[buyer][address][country]": "DE",
"invoice[payment][iban]": "DE02120300000000202051",
"invoice[lines][0][name]": "Consulting",
"invoice[lines][0][quantity]": "8",
"invoice[lines][0][unit]": "HUR",
"invoice[lines][0][unit_price]": "120",
"invoice[lines][0][vat_rate]": "19",
"invoice[charges][0][amount]": "4.95",
"invoice[charges][0][reason]": "Shipping",
"invoice[charges][0][vat_rate]": "19"
}
resp, _ := client.R().
SetFormData(data).
SetHeader("Authorization", "Bearer TOKEN").
Post("https://apdf.io/api/pdf/einvoice/create")
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")
.add("invoice[number]", "RE-2026-0042")
.add("invoice[issue_date]", "2026-11-11")
.add("invoice[due_date]", "2026-11-25")
.add("invoice[currency]", "EUR")
.add("invoice[seller][name]", "Acme GmbH")
.add("invoice[seller][vat_id]", "DE123456789")
.add("invoice[seller][address][line1]", "Hauptstraße 1")
.add("invoice[seller][address][city]", "Berlin")
.add("invoice[seller][address][postcode]", "10115")
.add("invoice[seller][address][country]", "DE")
.add("invoice[buyer][name]", "Contoso AG")
.add("invoice[buyer][address][line1]", "Am Markt 5")
.add("invoice[buyer][address][city]", "Hamburg")
.add("invoice[buyer][address][postcode]", "20095")
.add("invoice[buyer][address][country]", "DE")
.add("invoice[payment][iban]", "DE02120300000000202051")
.add("invoice[lines][0][name]", "Consulting")
.add("invoice[lines][0][quantity]", "8")
.add("invoice[lines][0][unit]", "HUR")
.add("invoice[lines][0][unit_price]", "120")
.add("invoice[lines][0][vat_rate]", "19")
.add("invoice[charges][0][amount]", "4.95")
.add("invoice[charges][0][reason]", "Shipping")
.add("invoice[charges][0][vat_rate]", "19")
.build();
Request request = new Request.Builder()
.url("https://apdf.io/api/pdf/einvoice/create")
.addHeader("Authorization", "Bearer TOKEN")
.post(formBody)
.build();
Response response = client.newCall(request).execute();
System.out.println(response.body().string());
}
}
Your invoice.
Now machine-readable.
The invoice looks exactly as before, pages and links included.
Its data travels inside as XML that accounting software reads.
- BASIC
- Lines and totals, for simple invoices
- EN 16931
- The European standard, the default
- EXTENDED
- The standard with room for more detail
- XRECHNUNG
- For German public authorities
Line amounts, the VAT breakdown and the totals are calculated from your lines, discounts and charges.
Invoices that book themselves.
Keep the invoice PDF your customers know, and add the data their accounting reads without typing.
Keep your invoice layout
Turn the PDF your billing already makes into an e-invoice, with its branding, pages and links kept.
Invoices to authorities
Send XRechnung invoices to German public authorities, with the Leitweg-ID as the buyer reference.
Credit notes and corrections
Issue credit notes and corrected invoices that point back to the invoices they refer to.
Every way to get paid
State a bank transfer, SEPA direct debit, card or online payment, with discounts and charges.
E-invoices from anywhere.
Turn invoices into e-invoices right where they are made.
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/create
Pick the action in any Zap and map files from earlier steps. No code and no servers to run.
Create E-Invoice
Add the Apdf node to any workflow, on n8n Cloud or self-hosted, and chain it with your automation.
Create electronic invoice
Let Claude, ChatGPT, Gemini or your own agent run it through the MCP server, on any paid plan.
create-e-invoice
1,000 e-invoices
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.
Creating 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