DATEV CSV-Export
Exportiert gespeicherte Rechnungen für einen Datumsbereich als DATEV-kompatible CSV-Datei.
Status: Beta — externe DATEV-Importvalidierung steht aus.
Der Export ist durch automatisierte Tests abgedeckt und erzeugt CSV im DATEV-Format, wurde aber noch nicht durch einen Import in eine echte DATEV-Rechnungswesen-Umgebung validiert. Verlassen Sie sich für die produktive Buchhaltung nicht darauf, ohne die erzeugte Datei mit einer qualifizierten Steuerberatung oder Ihrer eigenen DATEV-Umgebung zu prüfen.
Bekannte Einschränkungen:
- Nur CSV; DATEV XML wird nicht unterstützt.
- Belegnummern, die das 12-Zeichen-Limit des älteren Formats überschreiten, blockieren den Export, statt gekürzt zu werden — eine Referenz wird nie stillschweigend mehrdeutig.
- Rechnungen, die dieselbe DATEV-Belegnummer ergeben, blockieren den Export, bis eine von ihnen eine abweichende Export-Belegnummer erhält.
- Mögliche Doppelrechnungen müssen vor dem Export geprüft werden.
- Ein echter DATEV-Importtest steht noch aus.
/v1/exports/datevProDATEV-Export ist für Pro und Business verfügbar. Der Endpunkt erzeugt eine Windows-1252-kodierte CSV aus gespeicherten Rechnungen Ihres Workspaces, soweit sie im Retention-Fenster Ihres Tarifs sichtbar sind.
Anfrage
Verwenden Sie POST /v1/exports/datev mit den Query-Parametern from und to.
| Query-Parameter | Typ | Pflicht | Beschreibung |
|---|---|---|---|
from | date | Ja | Startdatum, YYYY-MM-DD |
to | date | Ja | Enddatum, YYYY-MM-DD |
curl -X POST "https://api.parsurai.com/v1/exports/datev?from=2026-06-01&to=2026-06-30" \
-H "X-API-Key: $PARSURAI_API_KEY" \
-o datev_export.csv
import httpx
response = httpx.post(
"https://api.parsurai.com/v1/exports/datev",
headers={"X-API-Key": api_key},
params={"from": "2026-06-01", "to": "2026-06-30"},
)
with open("datev_export.csv", "wb") as file_obj:
file_obj.write(response.content)
Antwort
Bei Erfolg gibt der Endpunkt einen CSV-Bytestream zurück:
HTTP/1.1 200 OK
Content-Type: application/octet-stream
Content-Disposition: attachment; filename=datev_export.csv
Die CSV-Bytes sind als windows-1252 kodiert.
Exportierte Felder
Der Exporter schreibt eine DATEV-Metadatenzeile, den DATEV-Spaltenkopf und danach eine Zeile pro Rechnung. Aktuell gemappte Felder:
| DATEV-Spalte | Quelle |
|---|---|
Umsatz (ohne Soll/Haben-Kz) | invoice.total_amount.amount |
Soll/Haben-Kennzeichen | Immer S |
WKZ Umsatz | invoice.total_amount.currency |
Konto | 1600 |
Gegenkonto (ohne BU-Schlüssel) | 70000 |
Belegdatum | invoice.issue_date als DDMM |
Leistungsdatum | invoice.issue_date als DDMMYYYY |
Belegfeld 1 | invoice.invoice_number |
Buchungstext | invoice.vendor.name |
Berater- und Mandantennummer werden serverseitig konfiguriert, nicht über die öffentliche API-Anfrage übergeben.
Fehlerbehandlung
Der DATEV-Export ist nur für Pro und Business verfügbar. Unterhalb von Pro gibt POST /v1/exports/datev den Code feature_not_in_plan zurück.
| Status | Code | Umgang |
|---|---|---|
401 | invalid_api_key | Schlüssel prüfen oder einen aktiven sk_live_-Schlüssel verwenden |
402 | feature_not_in_plan | Export-Button ausblenden oder Upgrade anbieten |
409 | datev_export_blocked | Mindestens eine Rechnung im Zeitraum ist eine ungeprüfte mögliche Doppelrechnung |
409 | datev_reference_too_long | Mindestens eine Belegnummer ist länger, als Belegfeld 1 zulässt |
409 | datev_reference_collision | Mehrere Rechnungen im Zeitraum ergeben dieselbe DATEV-Belegnummer |
422 | validation_error | from und to als YYYY-MM-DD senden |
Ungeprüfte mögliche Doppelrechnungen
Eine Rechnung, die von der Duplikaterkennung mit 0.85 oder
höher bewertet wird, stoppt den gesamten Export, bis eine Person darüber entscheidet. Es entsteht
keine Teil-CSV — eine ins DATEV gebuchte Doppelrechnung wird doppelt verbucht, deshalb scheitert der
Export lieber ganz, als stillschweigend eine Zeile wegzulassen.
Die Antwort nennt die blockierenden Rechnungen und sonst nichts:
| Feld | Bedeutung |
|---|---|
blocking_invoice_count | Wie viele Rechnungen den Export blockieren |
blocking_invoice_ids | Deren IDs, ausschließlich aus Ihrem Workspace |
Lieferantennamen, Beträge und Belegnummern werden bewusst nie zurückgegeben.
Zur Lösung halten Sie für jede genannte Rechnung mit
PATCH /v1/invoices/{invoice_id}/duplicate-review eine Entscheidung fest und starten den Export
erneut. Die möglichen Status und ihre Wirkung auf den Exportstapel beschreibt
Duplikatprüfung. Die zugehörige Gegenüberstellung der Kandidaten
liegt im Dashboard, nicht in der öffentlichen API.
Belegnummer zu lang
Belegfeld 1 fasst 12 Zeichen in der DATEV-Formatversion, die dieser Exporter schreibt. Ist eine
Belegnummer länger, wird der gesamte Export mit 409 datev_reference_too_long abgelehnt.
Belegnummern werden nie gekürzt: zwei Belegnummern mit denselben ersten 12 Zeichen würden zu
einem einzigen exportierten Wert zusammenfallen und die Verbindung zwischen Buchungszeile und Beleg
stillschweigend zerstören. Stattdessen scheitert der Export.
Die Länge wird gemessen, nachdem die von DATEV in Belegfeld 1 abgelehnten Zeichen entfernt
wurden. Eine Belegnummer kann in der App also länger als 12 Zeichen sein und trotzdem exportieren.
Die Antwort enthält nur das, was zur Eingrenzung nötig ist:
| Feld | Bedeutung |
|---|---|
max_length | Maximale Belegnummernlänge, die der Exporter akzeptiert (12) |
invoice_count | Anzahl der Rechnungen, die sie überschreiten |
invoice_ids | IDs dieser Rechnungen, ausschließlich aus Ihrem Workspace |
Die Belegnummern selbst werden bewusst nie zurückgegeben.
{
"error": {
"code": "datev_reference_too_long",
"message": "Der DATEV-Export ist blockiert, weil mindestens eine Belegnummer das 12-Zeichen-Limit des gewählten DATEV-Formats überschreitet. Korrigieren Sie die Belegnummer oder exportieren Sie mit einer bewusst aktualisierten DATEV-Formatversion.",
"max_length": 12,
"invoice_count": 2,
"invoice_ids": [
"6f1c2b8e-0f2a-4a1d-9c47-7b4e1f2a3d55",
"b3d9a1c4-52e7-4f08-8c3b-1a9d6e5f0c22"
]
}
}
So lösen Sie das Problem:
- Die App öffnet einen Korrekturdialog, der jede betroffene Rechnung mit ihrer extrahierten Belegnummer, dem heute exportierten Wert und der maximal zulässigen Länge auflistet. Längere Arbeitslisten werden seitenweise angezeigt; die Seitennavigation nennt, wie viele Rechnungen noch eine Belegnummer benötigen.
- Sie können eine separate DATEV-Belegnummer festlegen, ohne die ursprünglich extrahierte Belegnummer der Rechnung zu ändern. Die extrahierte Belegnummer bleibt exakt so erhalten, wie sie auf dem Beleg gefunden wurde, und wird weiterhin nie gekürzt.
- Lesen Sie den Kontext zu den zurückgegebenen
invoice_idsmitGET /v1/invoices/datev-export-reference-remediation, setzen Sie einen Wert mitPUT /v1/invoices/{invoice_id}/datev-export-reference-overrideund starten Sie den Export erneut. - Ein Export über einen Datumsbereich, der die betroffenen Rechnungen ausschließt, funktioniert ebenfalls und bleibt der schnellste Weg, wenn diese Rechnungen ohnehin in eine andere Periode gehören.
Die Meldung erwähnt eine neuere DATEV-Formatversion; der Exporter schreibt derzeit jedoch nur eine einzige Formatversion, ein Formatwechsel ist also aktuell keine Option.
Doppelte DATEV-Belegnummer
Zwei Rechnungen desselben Exports können ein und denselben Wert in Belegfeld 1 ergeben — weil
ihre Belegnummern identisch werden, sobald die von DATEV abgelehnten Zeichen entfernt sind, oder
weil eine abweichende DATEV-Belegnummer auf einen Wert gesetzt wurde, den eine andere Rechnung im
Zeitraum bereits ergibt.
Der gesamte Export wird dann mit 409 datev_reference_collision abgelehnt. Es wird keine CSV
erzeugt, auch keine teilweise mit den nicht betroffenen Rechnungen: zwei Buchungszeilen mit
derselben Belegnummer würden die Verbindung zwischen Zeile und Beleg genauso zerstören wie eine
gekürzte Belegnummer.
Die Antwort enthält nur das, was zur Eingrenzung nötig ist:
| Feld | Bedeutung |
|---|---|
invoice_count | Anzahl der betroffenen Rechnungen |
invoice_ids | IDs dieser Rechnungen, flach und dedupliziert, ausschließlich aus Ihrem Workspace |
collision_groups | Je ein Array von Rechnungs-IDs pro Gruppe mit gemeinsamer Belegnummer |
Der kollidierende Wert selbst wird bewusst nie zurückgegeben.
{
"error": {
"code": "datev_reference_collision",
"message": "Der DATEV-Export ist blockiert, weil mehrere Rechnungen dieselbe DATEV-Belegnummer ergeben. Vergeben Sie für die betroffenen Rechnungen eine abweichende DATEV-Belegnummer und exportieren Sie erneut.",
"invoice_count": 4,
"invoice_ids": [
"6f1c2b8e-0f2a-4a1d-9c47-7b4e1f2a3d55",
"b3d9a1c4-52e7-4f08-8c3b-1a9d6e5f0c22",
"1d7f4a90-8c31-4b6e-a0f5-2c8b9e4d7a10",
"9a5e0c73-4d18-4f2b-b7c6-3e1a8d0f5b44"
],
"collision_groups": [
[
"6f1c2b8e-0f2a-4a1d-9c47-7b4e1f2a3d55",
"b3d9a1c4-52e7-4f08-8c3b-1a9d6e5f0c22"
],
[
"1d7f4a90-8c31-4b6e-a0f5-2c8b9e4d7a10",
"9a5e0c73-4d18-4f2b-b7c6-3e1a8d0f5b44"
]
]
}
}
Zur Lösung geben Sie allen Rechnungen einer Gruppe bis auf eine eine abweichende DATEV-Belegnummer
und starten den Export erneut. collision_groups zeigt, welche Rechnungen miteinander kollidieren.
Abweichende DATEV-Belegnummer
Eine abweichende DATEV-Belegnummer ist ein separater Wert, der ausschließlich beim Erzeugen der
DATEV-Ausgabe verwendet wird. Sie ändert invoice.invoice_number nie: die extrahierte Belegnummer
bleibt exakt erhalten, und jeder andere Export und jede andere API-Antwort geben sie unverändert
zurück.
Diese Endpunkte sind nicht tarifgebunden. Der DATEV-Export selbst ist eine Pro- und Business-Funktion, aber jeder authentifizierte Eigentümer kann einen blockierten Export auflösen.
Jede Änderung wird in einem Audit-Trail festgehalten, inklusive des handelnden Benutzers und der Information, ob die Änderung über einen API-Schlüssel oder die gehostete App kam. Der Audit-Trail ist unveränderlich und vollständig geordnet: Die Datenbank selbst weist jeden Versuch ab, ein erfasstes Ereignis zu ändern oder zu löschen. Ereignisse verschwinden nur, wenn die zugehörige Rechnung gelöscht wird.
/v1/invoices/{invoice_id}/datev-export-reference-overrideSenden Sie die Belegnummer, die exportiert werden soll. Der Server normalisiert sie — die von DATEV
in Belegfeld 1 abgelehnten Zeichen werden entfernt — und speichert das Ergebnis, das nach der
Normalisierung zwischen 1 und 12 Zeichen lang sein muss.
curl -X PUT "https://api.parsurai.com/v1/invoices/6f1c2b8e-0f2a-4a1d-9c47-7b4e1f2a3d55/datev-export-reference-override" \
-H "X-API-Key: $PARSURAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"reference": "RE 2026/0042"}'
{
"invoice_id": "6f1c2b8e-0f2a-4a1d-9c47-7b4e1f2a3d55",
"reference_override": "RE2026/0042"
}
reference_override ist der normalisierte Wert, der tatsächlich exportiert wird, und kann daher
von dem abweichen, was Sie gesendet haben. Maßgeblich ist die Antwort, nicht Ihr Request-Body.
Der Aufruf ist idempotent: ein Wert, der sich zur bereits gespeicherten Belegnummer normalisiert,
liefert 200 und erzeugt kein Audit-Ereignis.
Ein unbrauchbarer Wert — nach der Normalisierung leer oder länger als 12 Zeichen — liefert 422:
{
"error": {
"code": "validation_error",
"field": "reference",
"message": "reference is not a usable DATEV export reference."
}
}
Der gesendete Wert wird bewusst nie zurückgespiegelt.
/v1/invoices/{invoice_id}/datev-export-reference-overrideEntfernt die abweichende Belegnummer, sodass die Rechnung auf ihre extrahierte Belegnummer
zurückfällt. Der Endpunkt liefert 204, unabhängig davon, ob zuvor eine gesetzt war.
curl -X DELETE "https://api.parsurai.com/v1/invoices/6f1c2b8e-0f2a-4a1d-9c47-7b4e1f2a3d55/datev-export-reference-override" \
-H "X-API-Key: $PARSURAI_API_KEY"
/v1/invoices/datev-export-reference-remediationLiest den Belegnummern-Kontext zu den invoice_ids, die ein blockierter Export zurückgegeben hat,
damit Sie entscheiden können, was Sie überschreiben.
| Query-Parameter | Typ | Pflicht | Beschreibung |
|---|---|---|---|
ids | string | Ja | Kommagetrennte Rechnungs-IDs, dedupliziert, höchstens 50, Reihenfolge bleibt erhalten |
curl "https://api.parsurai.com/v1/invoices/datev-export-reference-remediation?ids=6f1c2b8e-0f2a-4a1d-9c47-7b4e1f2a3d55,b3d9a1c4-52e7-4f08-8c3b-1a9d6e5f0c22" \
-H "X-API-Key: $PARSURAI_API_KEY"
{
"items": [
{
"invoice_id": "6f1c2b8e-0f2a-4a1d-9c47-7b4e1f2a3d55",
"invoice_number": "RE 2026/ACCOUNTING 0042",
"reference_override": "RE2026/0042",
"normalized_invoice_number": "RE2026/ACCOUNTING0042",
"max_length": 12
},
{
"invoice_id": "b3d9a1c4-52e7-4f08-8c3b-1a9d6e5f0c22",
"invoice_number": "RE 2026/0043",
"reference_override": null,
"normalized_invoice_number": "RE2026/0043",
"max_length": 12
}
]
}
| Feld | Bedeutung |
|---|---|
invoice_id | Die Rechnung, die die Zeile beschreibt |
invoice_number | Die ursprünglich extrahierte Belegnummer, unverändert |
reference_override | Die aktuell gesetzte abweichende Belegnummer, sonst null |
normalized_invoice_number | Wozu sich die ursprüngliche Belegnummer für Belegfeld 1 normalisiert |
max_length | Maximale Belegnummernlänge, die der Exporter akzeptiert (12) |
Die Einträge werden in der Reihenfolge der angefragten IDs zurückgegeben. IDs, die Ihnen nicht
gehören, fehlen einfach in items, statt abgelehnt zu werden — die Antwort bestätigt also nie, ob
die Rechnung eines anderen Workspaces existiert.
Fehlerbehandlung der abweichenden Belegnummer
| Status | Code | Umgang |
|---|---|---|
404 | not_found | Die Rechnung liegt nicht in Ihrem Workspace |
422 | validation_error | reference ist nach der Normalisierung leer oder zu lang |
422 | invalid_invoice_ids | ids ist leer, enthält keine UUID oder mehr als 50 IDs |
404 behandelt eine fehlende Rechnung und eine Rechnung aus einem anderen Workspace identisch. Die
beiden Fälle sind nie unterscheidbar, die API lässt sich also nicht nutzen, um die Existenz einer
fremden Rechnungs-ID zu bestätigen.
Erstellen Sie DATEV-Exporte erst, wenn die Extraktions- und Prüf-Workflows abgeschlossen sind. Der Exporter liest gespeicherte Rechnungen; nicht gespeicherte oder fehlgeschlagene Extraktionen werden nicht berücksichtigt.