LiveES

VeriFactu-Nachweise (ES)

Zwei Endpunkte, eine Frage: Wie weisen Sie gegenüber der AEAT nach, dass Ihre Rechnungsstellung den spanischen Vorgaben folgt? Der eine gibt die declaración responsable der Software aus, der andere die vollständige registro-Kette einer NIF.

GET/api/v1/verifactu/declaracion
GET/api/v1/verifactu/chain/{vatId}/export

Warum es diese zwei Endpunkte gibt

Real Decreto 1007/2023 verlangt zwei Dinge, die ein Prüfer sehen können muss: die Verantwortungserklärung des Software-Herstellers (Art. 13.2, ausgeführt in Art. 15 Orden HAC/1177/2024) und die Aufzeichnungen selbst (Art. 14). Die Verordnung sagt, sie müssen im System einsehbar sein — bei einem API-Produkt heißt das: über die API abrufbar. Genau das leisten diese beiden Aufrufe.

Die declaración responsable

Art. 13.2

Gibt die Verantwortungserklärung zu diesem Rechnungssystem als Klartext plus Metadaten aus. Sie beschreibt den Hersteller der Software — uns —, nicht Ihre Organisation, und ist deshalb für jeden API-Key identisch.

bash
1curl https://service.invoice-api.xhub.io/api/v1/verifactu/declaracion \
2 -H "Authorization: Bearer sk_live_abc123..."

Achten Sie auf hasPendingLegalReview. Solange dort true steht, trägt der Wortlaut noch unsere interne Prüfmarkierung: Das Dokument ist dann ein Entwurf, keine unterschriebene Erklärung. Für eine Vorlage bei der AEAT warten Sie, bis dort false steht.

Antwort der declaración

200 OK
json
1{
2 "text": "DECLARACIÓN RESPONSABLE\n\nEl productor del sistema informático de facturación ...",
3 "version": "1.5.0",
4 "hasPendingLegalReview": false,
5 "producedAt": "2026-09-28T09:14:22.318Z"
6}
FeldTypBeschreibung
textstringDie declaración responsable im Volltext, als Klartext (spanisch, Art. 13.2).
versionstringSoftware-Version, für die die Erklärung gilt — die Version aus IdSistemaInformatico.
hasPendingLegalReviewbooleantrue, solange der Wortlaut unsere interne Prüfmarkierung trägt. Dann ist das Dokument ein Entwurf.
producedAtstring (ISO-8601)ISO-8601-Zeitstempel dieser Ausgabe.

Der Export der registro-Kette

Art. 14

Gibt jeden registro der Kette zu einer NIF als EIN JSON-Dokument aus, geordnet nach Sequenznummer. Jeder Eintrag trägt den eingefrorenen registro neben seiner huella — genau das Objekt, über das der Hash gebildet wurde, unverändert durchgereicht und nie umgeformt. Der Empfänger kann den Hash damit selbst nachrechnen.

Der Export ist auf die Organisation hinter dem API-Key beschränkt. Eine Kette, die jemand anderem gehört, ist nicht sichtbar und kommt als leerer Export zurück — nicht als Fehler.

Ab 5.000 Einträgen ist ein Zeitraum Pflicht: from, to oder beide. Fehlt er, antwortet die API mit 400 und nennt die Zahl der Einträge. Beide Werte sind ISO-8601 und grenzen nach dem Zeitstempel des Eintrags ein.

Query-Parameter

FeldTypPflichtBeschreibung
fromstring (ISO-8601)-Nur Einträge, die zu diesem ISO-8601-Zeitpunkt oder danach angehängt wurden. Pflicht — allein oder zusammen mit to —, sobald die Kette das Exportlimit übersteigt.
tostring (ISO-8601)-Nur Einträge, die zu diesem ISO-8601-Zeitpunkt oder davor angehängt wurden.

Beispiel

bash
1# The whole chain of one NIF
2curl "https://service.invoice-api.xhub.io/api/v1/verifactu/chain/B12345678/export" \
3 -H "Authorization: Bearer sk_live_abc123..."
4 
5# Narrowed to a range — mandatory above 5000 entries
6curl "https://service.invoice-api.xhub.io/api/v1/verifactu/chain/B12345678/export?from=2026-01-01T00:00:00Z&to=2026-03-31T23:59:59Z" \
7 -H "Authorization: Bearer sk_live_abc123..."

Antwort des Kettenexports

200 OK
json
1{
2 "vatId": "B12345678",
3 "exportedAt": "2026-09-28T09:20:04.771Z",
4 "from": "2026-01-01T00:00:00.000Z",
5 "to": "2026-03-31T23:59:59.000Z",
6 "entryCount": 2,
7 "entries": [
8 {
9 "sequenceNumber": 1,
10 "invoiceId": "inv_01J8Z3K9QW",
11 "invoiceNumber": "A/2026-0001",
12 "huella": "3C1F9A72B84E05D6C7A1938E4F20B5D8A6C3E71F9B2D48065A1C7E39F2B8D4E60",
13 "previousHuella": "",
14 "recordType": "ALTA",
15 "createdAt": "2026-01-03T08:41:12.004Z",
16 "registro": {
17 "IDFactura": {
18 "IDEmisorFactura": "B12345678",
19 "NumSerieFactura": "A/2026-0001",
20 "FechaExpedicionFactura": "03-01-2026"
21 },
22 "ImporteTotal": "1785.00"
23 },
24 "status": "ACCEPTED",
25 "resultCsv": "AAAgOKbwQ8iQ7wAAAAA",
26 "lastError": null
27 },
28 {
29 "sequenceNumber": 2,
30 "invoiceId": "inv_01J8Z4M2RT",
31 "invoiceNumber": "A/2026-0002",
32 "huella": "B7E2D46901C8A35F7E1B9D24608C5A3F1E7B9D2460C8A5F3E1B7D9460C2A8F5E3",
33 "previousHuella": "3C1F9A72B84E05D6C7A1938E4F20B5D8A6C3E71F9B2D48065A1C7E39F2B8D4E60",
34 "recordType": "ALTA",
35 "createdAt": "2026-01-04T10:02:55.612Z",
36 "registro": {
37 "IDFactura": {
38 "IDEmisorFactura": "B12345678",
39 "NumSerieFactura": "A/2026-0002",
40 "FechaExpedicionFactura": "04-01-2026"
41 },
42 "ImporteTotal": "952.00"
43 },
44 "status": "PENDING",
45 "resultCsv": null,
46 "lastError": null
47 }
48 ]
49}
FeldTypBeschreibung
vatIdstringDie NIF, zu der die Kette gehört — der Kettenschlüssel.
exportedAtstring (ISO-8601)ISO-8601-Zeitstempel DIESES Exports, nicht des letzten Eintrags.
fromstring | nullUntere Grenze des exportierten Zeitraums, oder null.
tostring | nullObere Grenze des exportierten Zeitraums, oder null.
entryCountintegerAnzahl der Einträge in entries.
entriesarrayDie Einträge, geordnet nach Sequenznummer — Aufbau unten.

Ein Eintrag der Kette

FeldTypBeschreibung
sequenceNumberintegerPosition in der Kette, ab 1 und ohne Lücken.
invoiceIdstringInterne Id der Rechnung, zu der der Eintrag gehört.
invoiceNumberstring | nullRechnungsnummer wie ausgestellt, oder null, wenn der Eintrag älter als die Nummerierung ist.
huellastringDer Eintrags-Hash (huella) wie gespeichert — aus registro nachrechenbar.
previousHuellastringHuella des vorangehenden Eintrags; beim ersten Eintrag der Kette ein leerer String.
recordTypestring | nullALTA für die Ausstellung oder ANULACION für den Storno, wie aufgezeichnet.
createdAtstring (ISO-8601)ISO-8601-Zeitstempel, zu dem der Eintrag an die Kette gehängt wurde.
registroobjectDer eingefrorene registro genau so, wie er an die AEAT ging — das Objekt, über das die huella gebildet wurde. Nicht umgeformt.
statusstring | nullÜbermittlungsstand der zugehörigen Warteschlangenzeile, etwa ACCEPTED oder PENDING, oder null.
resultCsvstring | nullDer CSV der AEAT, sobald der registro angenommen wurde.
lastErrorstring | nullLetzter Übermittlungsfehler zu diesem Eintrag, wörtlich.

Fehler

StatusCodeBeschreibung
400Bad Requestfrom oder to ist kein gültiges ISO-8601-Datum, oder die Kette ist zu groß für einen Export ohne Zeitraum — die Meldung nennt die Zahl der Einträge.
401UNAUTHORIZEDAPI-Key fehlt, ist ungültig, oder der Key hat keine Organisation.
502CONFIG_MISSINGDer Plattform fehlt zwingende VERIFACTU-Konfiguration. Die Meldung nennt jede fehlende Variable.