Last updated: March 2026 · 8 min read
Spain's VeriFactu regulation requires every business invoice to be digitally registered with AEAT (Agencia Tributaria) in real time. Each invoice must be formatted as XML, cryptographically hashed, linked to the previous invoice in a tamper-proof chain, and submitted over AEAT's secure web service.
AEAT Sync handles all of this through a single REST API. You send us the invoice data, and we generate the XML, compute the hash chain, sign it with your digital certificate, submit it to AEAT, and notify you via webhook. This guide covers how to integrate it into your backend.
VeriFactu (short for Verificable Facturación) is the Spanish government's system for verified invoicing. Under Royal Decree 1007/2023, all invoicing software used by Spanish businesses must:
Non-compliance can result in penalties. AEAT Sync ensures your invoices meet every requirement.
All requests require your API key in the X-API-Key header. Get your key from Settings after creating an account.
X-API-Key: your_api_key_here
Send a POST request to create and submit an invoice to AEAT:
{
"issuer_nif": "B12345678",
"issuer_name": "Your Company SL",
"issue_date": "2026-03-26",
"items": [
{
"description": "SaaS subscription — March 2026",
"quantity": 1,
"unit_price": "49.00",
"vat_rate": "21.00"
}
]
}
AEAT Sync returns the invoice immediately with a pending status. The background worker submits it to AEAT and sends a webhook when AEAT responds.
{
"id": "3f9a2d1e-…",
"invoice_number": "A-000042",
"status": "pending",
"hash": "a3f9d2e1...",
"previous_hash": "7b4c1a09...",
"created_at": "2026-03-26T10:00:00+00:00"
}
Download the signed XML for any invoice at:
curl -X GET https://staging.orionpathulda.io/api/v1/invoice/3f9a2d1e-.../xml \ -H "X-API-Key: your_api_key_here" \ --output invoice.xml
VeriFactu requires each invoice to contain a cryptographic hash that incorporates the previous invoice's hash. This creates a chain where modifying or deleting any invoice would break the entire sequence — making fraud detectable.
AEAT Sync computes this automatically. You never need to track hashes — just send invoice data, and the chain is maintained for you.
Register a webhook endpoint in your Webhooks settings. AEAT Sync will POST the result as soon as AEAT responds.
{
"event": "invoice.accepted",
"invoice_number": "A-000042",
"status": "accepted",
"hash": "a3f9d2e1...",
"issued_at": "2026-03-26T10:45:00Z",
"aeat_response": "CSV-123456789"
}
Every webhook request includes an X-Signature header — an HMAC-SHA256 of the request body using your webhook secret. Always verify this before processing.
import requests
resp = requests.post(
"https://staging.orionpathulda.io/api/v1/invoice",
headers={"X-API-Key": "your_api_key"},
json={
"issuer_nif": "B12345678",
"issuer_name": "Your Company SL",
"issue_date": "2026-03-26",
"items": [{
"description": "Monthly subscription",
"quantity": 1,
"unit_price": "49.00",
"vat_rate": "21.00"
}]
}
)
print(resp.json()) # {"invoice_number": "A-000042", ...}
curl -X POST https://staging.orionpathulda.io/api/v1/invoice \
-H "X-API-Key: your_api_key" \
-H "Content-Type: application/json" \
-d '{
"issuer_nif": "B12345678",
"issuer_name": "Your Company SL",
"issue_date": "2026-03-26",
"items": [{
"description": "Monthly subscription",
"quantity": 1,
"unit_price": "49.00",
"vat_rate": "21.00"
}]
}'
const resp = await fetch(
"https://staging.orionpathulda.io/api/v1/invoice",
{
method: "POST",
headers: {
"X-API-Key": "your_api_key",
"Content-Type": "application/json"
},
body: JSON.stringify({
issuer_nif: "B12345678",
issuer_name: "Your Company SL",
issue_date: "2026-03-26",
items: [{
description: "Monthly subscription",
quantity: 1,
unit_price: "49.00",
vat_rate: "21.00"
}]
})
}
);
const data = await resp.json();
console.log(data);
Yes. AEAT requires invoices to be signed with a qualified digital certificate (e.g., from FNMT). You upload your certificate in Settings, and AEAT Sync uses it to sign every invoice.
AEAT Sync returns a standard HTTP error code with a descriptive message. The invoice is not created and nothing is submitted to AEAT. Fix the issue and retry.
Yes. Enable sandbox mode in Settings. Invoices are processed normally (XML generated, hash chain maintained) but are not actually submitted to AEAT's production endpoint.
All Spanish VAT rates: 21% (general), 10% (reduced), 4% (super-reduced), and 0% (exempt). Set the vat_rate field per line item.
The Starter plan allows up to 20 invoices/month. Growth allows 500, Scale allows 5,000. See Pricing for details. Rate limits are applied per calendar month.
Get your API key and start sending test invoices in under a minute.
Complete end-to-end walkthrough, Stripe integration guide, and invoice status reference.
Start free. Scale with transparent, developer-friendly pricing.
Get notified the moment AEAT processes your invoice.