ml-connector
DATEVPlaid

DATEV and Plaid integration

DATEV runs accounting and tax for German and Austrian businesses. Plaid reads the bank accounts and transactions behind those businesses. Connecting the two takes the real money movement Plaid sees at the bank and books it into DATEV without re-keying. Each new bank transaction becomes a DATEV booking batch row, with a debit and credit account, a document number, and posting text, ready for the accountant to review. ml-connector handles the very different APIs on each side and submits the bookings on a cadence you control.

How DATEV works

DATEV is not a conventional REST system. Core accounting goes through asynchronous batch file processing: you submit an EXTF CSV booking batch as a job to DATEV Rechnungswesen, or a DXSO XML job to DATEV Unternehmen Online, then poll the job status endpoint until it completes, because DATEV has no webhooks. A small REST surface lists clients and uploads document PDFs to DUO. Authentication is OAuth2 Authorization Code with PKCE through Login mit DATEV, with a 900 second access token and refresh using the client ID only. The full chart of accounts cannot be read back via API, and finalized EXTF bookings are write-only.

How Plaid works

Plaid is a bank-data network, not an ERP, so it has no vendors, invoices, purchase orders, or GL accounts. It exposes bank Items, accounts and balances, transactions, account and routing numbers or IBAN and BIC for SEPA accounts, and ACH or wire transfers through a REST API where every call is an HTTP POST with a JSON body. Authentication uses a client ID and secret as headers, plus a per-user access token obtained when the end user completes the Plaid Link flow once in a browser. Plaid pushes signed webhooks, including SYNC_UPDATES_AVAILABLE when new transactions are ready, verified with an ES256 JWT.

What moves between them

The flow runs from Plaid into DATEV. ml-connector pulls bank transactions from Plaid using cursor-based transaction sync, then builds an EXTF CSV booking batch where each transaction maps to an amount, a debit and credit account, a document date, a document number, and posting text, and submits it as an async job to DATEV. Account and IBAN or BIC details from Plaid identify which bank account each line belongs to. The direction is one-way, because Plaid is read-only for accounting and DATEV EXTF bookings are write-only and cannot be read back. Bank account to GL account mapping is set up first, since DATEV does not expose its chart of accounts over the API.

How ml-connector handles it

ml-connector stores both credential sets encrypted. For Plaid it sends the client ID and secret on every POST and keeps the per-user access token from Plaid Link; for DATEV it runs the OAuth2 PKCE login, sends the bearer token with the client ID header, and refreshes the 900 second token using the client ID only. It subscribes to the Plaid SYNC_UPDATES_AVAILABLE webhook, verifies the ES256 JWT against the rotating JWK, then reads the added, modified, and removed transactions by cursor. Each transaction is normalized into an EXTF row with NFC-precomposed text and a stable, deterministic filename, so a duplicate submission is rejected cleanly and a retry is safe. The batch is posted as a job and polled with backoff until it completes, because DATEV gives no synchronous confirmation. Bank accounts are mapped to DATEV GL accounts ahead of time, since the chart of accounts is not API-readable. Every record carries a full audit trail and can be replayed if a DATEV job fails.

A real-world example

A German trading company with roughly 60 staff keeps its books in DATEV through its tax advisor and runs several business current accounts at different banks. Before the integration, a bookkeeper exported bank statements each week and typed the line items into a DATEV booking batch by hand, matching each payment to a ledger account, which was slow and error-prone near month-end. With DATEV and Plaid connected, the linked bank transactions flow in as EXTF booking batches automatically, each line already carrying the document number, posting text, and the mapped debit and credit accounts. The bookkeeper reviews and finalizes instead of re-keying, and the tax advisor sees clean batches arrive on schedule.

What you can do

  • Read bank transactions from Plaid and post them into DATEV as EXTF CSV booking batches.
  • Map each Plaid bank account, including IBAN and BIC accounts, to the correct DATEV GL account before posting.
  • Bridge Plaid client ID and secret plus the per-user access token with DATEV OAuth2 PKCE login and token refresh.
  • React to Plaid SYNC_UPDATES_AVAILABLE webhooks and submit DATEV jobs, polling each to completion.
  • Use deterministic EXTF filenames and a full audit trail so duplicates are rejected and failed jobs can be replayed.

Questions

Which direction does data move between DATEV and Plaid?
The flow is Plaid into DATEV. Bank transactions and account details move from Plaid into DATEV as booking batches. Plaid is read-only for accounting and DATEV EXTF bookings are write-only, so ml-connector does not write financial entries back into Plaid.
How are bank transactions turned into DATEV bookings?
ml-connector reads Plaid transactions by cursor, then builds an EXTF CSV booking batch where each line has an amount, a debit and credit account, a document date, a document number, and posting text. That batch is submitted to DATEV as an asynchronous job and polled until it completes, since DATEV processes booking files on its own schedule and sends no webhook.
How does the integration handle the different logins on each side?
Plaid uses a client ID and secret plus a per-user access token from the one-time Plaid Link flow, while DATEV uses OAuth2 Authorization Code with PKCE through Login mit DATEV. ml-connector stores both encrypted, presents each on its own requests, and refreshes the short-lived DATEV token using the client ID only, as DATEV requires.

Related integrations

Connect DATEV and Plaid

Free to use. Add your credentials, ping your real systems, and see if we fit.

Get started