DATEV and Google Sheets integration
DATEV is the accounting backend that German tax advisors and their clients use for bookkeeping. Google Sheets is where finance staff often stage invoice and booking data before it reaches the ledger. This connection takes rows entered in a Google Sheets tab and submits them to DATEV as booking files, then reports back whether each batch was accepted. Because DATEV accepts bookings only as asynchronous EXTF CSV or DXSO XML file jobs and exposes no readable journal, the data moves from Google Sheets into DATEV, and ml-connector handles the file building, job polling, and the very different authentication on each side.
What moves between them
The flow runs from Google Sheets into DATEV. ml-connector reads booking and invoice rows from a designated Google Sheets tab, transforms each row into the EXTF CSV fields DATEV requires (such as amount, debit and credit account, document date, document number, posting text, tax code, and cost center) or into DXSO XML for booking suggestions, and submits the file as an asynchronous job. Document PDFs staged with a link or file reference can be uploaded into DATEV Unternehmen Online alongside the bookings. After each job is polled to completion, the job status and any DATEV error code are written back into a status column on the same sheet. DATEV journals are write-only, so no posted entries are read back into the spreadsheet.
How ml-connector handles it
ml-connector stores both credential sets encrypted and runs two separate OAuth flows, one against Google and one against Login mit DATEV, refreshing the DATEV access token every 15 minutes and sending the required X-DATEV-Client-Id header on each call. It looks up the DATEV client ID once through accounting:clients, since that ID is the path parameter for every other call. Sheet headers are mapped to EXTF fields, and because the full chart of accounts is not readable from DATEV, the GL account and tax-code mapping is configured up front rather than discovered. Files are written as UTF-8 with precomposed (NFC) characters and a deterministic filename, because DATEV rejects a duplicate filename plus document-type combination with error DCO01253, which makes re-submission retry-safe. Submission is asynchronous, so ml-connector polls the job endpoint with backoff from about 5 up to 60 seconds until it reports complete or failed, then writes that result to the sheet. To avoid posting the same rows twice, since values.append is not idempotent, it tracks a synced cursor or a status column rather than re-reading the whole tab. Reads stay within the Google per-minute quota and retry on a 429, and every batch carries a full audit trail and can be replayed.
A real-world example
A boutique accounting firm in Germany keeps about 40 small business clients on DATEV and lets junior staff capture each client's monthly cash receipts and supplier invoices in a shared Google Sheets workbook, one tab per client. Before the integration, a senior bookkeeper re-typed those rows into DATEV by hand at month-end, which was slow and introduced posting errors that surfaced only when the client review failed. With DATEV and Google Sheets connected, each tab's rows are turned into an EXTF booking file and submitted to the right DATEV client automatically, and the job result is written back next to each row so staff can see what posted and what was rejected. The bookkeeper now reviews exceptions instead of re-keying every line.
What you can do
- Turn booking and invoice rows staged in a Google Sheets tab into DATEV EXTF CSV or DXSO XML job files.
- Submit each batch to the correct DATEV client and poll the asynchronous job until it completes or fails.
- Write the job status and any DATEV error code back into a status column on the same sheet.
- Bridge Google OAuth and Login mit DATEV with PKCE, refreshing the 15-minute DATEV token automatically.
- Use deterministic filenames and a synced cursor so retries and re-runs never post the same rows twice.
Questions
- Which direction does data move between DATEV and Google Sheets?
- Data moves from Google Sheets into DATEV. Rows staged in a sheet are converted into EXTF or DXSO booking files and submitted as jobs, and the job result is written back into a status column. DATEV exposes no readable chart of accounts or posted journal, so finalized bookings are not read back into the spreadsheet.
- How does the integration handle DATEV's asynchronous job processing without webhooks?
- DATEV processes booking files as asynchronous jobs and sends no push notifications. After submitting a file, ml-connector receives a job ID and polls the job endpoint with exponential backoff, from about 5 seconds up to 60 seconds, until it reports complete or failed. The outcome is then written back to the sheet so staff can see what posted.
- What stops the same spreadsheet rows from being posted to DATEV twice?
- The Google Sheets API does not deduplicate, and values.append is not idempotent, so ml-connector tracks a synced cursor or a status column to know which rows are already done. On the DATEV side it generates a deterministic filename, and DATEV rejects a duplicate filename and document-type combination with error DCO01253, which makes a retry safe rather than a double post.
Related integrations
More DATEV integrations
Other systems that connect to Google Sheets
Connect DATEV and Google Sheets
Free to use. Add your credentials, ping your real systems, and see if we fit.
Get started