ml-connector
DATEVSlack

DATEV and Slack integration

DATEV runs the accounting: clients, documents, and the EXTF and DXSO booking jobs that feed DATEV Rechnungswesen and DATEV Unternehmen Online. Slack runs team communication. Connecting the two puts DATEV accounting activity where the finance team already works. When a booking job completes or fails, ml-connector posts the result to a Slack channel, and when someone drops an invoice PDF into a watched channel, ml-connector uploads it to DATEV Unternehmen Online against the right client. Slack has no invoices, ledgers, or accounts of its own, so it stays the notification and approval layer while DATEV stays the system of record. ml-connector handles the very different auth on each side and moves the data on a schedule you control.

How DATEV works

DATEV exposes clients and documents through REST APIs on per-product hosts such as accounting-clients.api.datev.de and accounting-documents.api.datev.de, while finalized bookings go in as asynchronous EXTF CSV jobs to DATEV Rechnungswesen and booking suggestions go in as DXSO XML jobs to DATEV Unternehmen Online. Authentication is OAuth 2.0 Authorization Code with PKCE through login.datev.de, a real user must consent, the access token lasts only 900 seconds, and a refresh sends the client_id without the client_secret. DATEV publishes no outbound webhooks, so job status is read by polling the job endpoint until it reports complete or failed. Finalized bookings are write-only: posted journal entries and the standard chart of accounts cannot be read back through the API.

How Slack works

Slack exposes users, conversations, messages, and files through the Slack Web API at slack.com/api with dot-namespaced methods like chat.postMessage, conversations.list, files.info, and users.lookupByEmail, returning JSON over HTTPS. Server-side calls use a non-expiring bot token with the xoxb- prefix obtained through OAuth 2.0, and list methods page with a cursor. The Events API pushes workspace activity such as message, file_shared, and reaction_added to a public HTTPS endpoint by HTTP POST, each request signed with HMAC-SHA256 using the signing secret and required to be acknowledged within three seconds. Slack is a communication platform, so it has no native invoice, ledger, vendor, or account objects.

What moves between them

Most data moves from DATEV into Slack as notifications. After ml-connector submits an EXTF or DXSO job and polls it to a result, it posts a message to the configured Slack channel reporting the client, the document or batch, and whether the job completed or failed. A smaller flow moves from Slack into DATEV: when a user uploads an invoice PDF to a watched channel, the file_shared event triggers ml-connector to download the file and upload it to DATEV Unternehmen Online as a document of the correct client-specific type, and an approver can release a held booking by adding an agreed reaction to its Slack message. Cadence is event-driven on the Slack side and poll-driven on the DATEV side. Posted journals and the chart of accounts are not readable from DATEV, so ml-connector never tries to mirror the ledger into Slack.

How ml-connector handles it

ml-connector stores both credential sets encrypted. On the DATEV side it runs the OAuth2 PKCE flow, sends the bearer token plus the X-DATEV-Client-Id header on every call, and refreshes the 900-second access token with the client_id alone before it expires. On the Slack side it calls the Web API with the xoxb- bot token and verifies every inbound Events API request by recomputing the HMAC-SHA256 signature over v0:timestamp:body with the signing secret, rejecting any request whose timestamp is older than five minutes, and answering the url_verification challenge when the Request URL is set. Because the bot must already be a member of a channel to read it, ml-connector joins or is invited to the watched channels first. Invoice PDFs from Slack are uploaded with PUT and a stable GUID so a retried delivery is idempotent, and the document type is fetched per client because valid types differ by DATEV client. Outbound EXTF files are written in NFC-normalized UTF-8 with whitelisted filenames, since non-precomposed characters or stray special characters cause silent rejection, and ml-connector polls the async job with exponential backoff and jitter rather than waiting for a push DATEV never sends. Slack rate limits return HTTP 429 with Retry-After and chat.postMessage is capped at one message per second per channel, so notifications are paced. Inbound events are acknowledged within the three-second window and processed on a queue, deduplicated by Slack event_id, and every action carries a full audit trail and can be replayed if a downstream call fails.

A real-world example

A regional manufacturing firm with about 120 employees keeps its books in DATEV through its tax advisor and runs day-to-day operations in Slack. Before the integration, incoming supplier invoices were emailed around, someone logged into DATEV Unternehmen Online to upload each PDF, and nobody downstream knew whether a booking batch had actually posted until the advisor mentioned a rejected file days later. With DATEV and Slack connected, an employee drops the invoice PDF into a finance channel and ml-connector files it into DATEV Unternehmen Online under the right document type, while every EXTF and DXSO job result is posted back to that channel as it completes or fails. The team sees a failed booking the moment it happens, the upload step no longer needs a DATEV login, and the back-and-forth over invoice handoffs disappears.

What you can do

  • Post DATEV EXTF and DXSO booking job results to a Slack channel as each job completes or fails.
  • Route invoice PDFs dropped into a watched Slack channel into DATEV Unternehmen Online under the correct client-specific document type.
  • Let an approver release a held DATEV booking by adding an agreed reaction to its Slack message.
  • Bridge DATEV OAuth2 PKCE with its 15-minute refresh and the non-expiring Slack bot token, verifying every inbound event with the signing secret.
  • Poll DATEV jobs with backoff while acknowledging Slack events within three seconds, with event_id dedup and a full audit trail on every action.

Questions

Which direction does data move between DATEV and Slack?
Most of it moves from DATEV into Slack as notifications: ml-connector posts a message when an EXTF or DXSO booking job completes or fails. A smaller flow moves the other way, where an invoice PDF dropped into a watched Slack channel is uploaded into DATEV Unternehmen Online and an agreed reaction can release a held booking. DATEV will not return posted journals or its chart of accounts, so ml-connector never mirrors the ledger into Slack.
Can Slack store invoices or general ledger postings from DATEV?
No. Slack is a communication platform with no native invoice, ledger, vendor, or account objects, so it cannot hold accounting records. What it does well is carry messages, files, and reactions, so ml-connector uses it as the notification and approval layer: booking results appear as messages and invoice PDFs come in as files, while DATEV remains the system of record.
How does the integration handle DATEV polling and Slack's signed events?
DATEV publishes no webhooks, so after submitting an EXTF or DXSO job ml-connector polls the job endpoint with exponential backoff and jitter until it reports complete or failed. Slack instead pushes events, so each inbound request is verified by recomputing the HMAC-SHA256 signature with the signing secret, rejected if its timestamp is over five minutes old, and acknowledged within three seconds before processing on a queue. Slack deliveries are deduplicated by event_id and DATEV access tokens are refreshed before their 15-minute expiry.

Related integrations

Connect DATEV and Slack

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

Get started