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://aeatsync.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",
"timestamp": "2026-03-26T10:45:00+00:00",
"data": {
"invoice_id": "8f2c1e0a-…",
"invoice_number": "A-000042",
"status": "accepted",
"total_amount": "121.00",
"currency": "EUR"
}
}
The invoice fields are nested under data. The record's hash and AEAT's response are not in the payload: read them with GET /api/v1/invoices/<invoice_id>.
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://aeatsync.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://aeatsync.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://aeatsync.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 — your business's own qualified digital certificate (e.g. from FNMT), and it never leaves your computer. You do not upload it: the AEAT Sync desktop companion, paired from Settings, holds the certificate locally and uses it to authenticate the submission to AEAT. Under VERI*FACTU the billing record itself is not signed; its security is the hash chain and the submission.
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.
There is no monthly cap on submissions and nothing is included on pay-as-you-go: every AEAT submission is billed at €0.04. Growth includes 600 submissions a month and Scale 1,750; beyond the allocation the same €0.04 rate applies. See Pricing. API requests are rate-limited to 120 per minute per API key.
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.
Scale with transparent, developer-friendly pricing.
Get notified the moment AEAT processes your invoice.