ml-connector
DATEVFishbowl

DATEV and Fishbowl integration

This connection moves operational purchasing and payment data from Fishbowl into DATEV so the accounting backend stays current without manual re-keying. ml-connector reads issued purchase orders, vendor master records, and payments from the Fishbowl REST API, then writes them into DATEV as EXTF CSV booking batches submitted to DATEV Rechnungswesen. Supporting invoice and receipt PDFs are uploaded into DATEV Unternehmen Online as client-specific document types. Because both systems are pull-only, the sync runs on a schedule and polls each job queue rather than waiting on push events. The result is that Fishbowl remains the system of record for inventory and orders while DATEV receives clean, structured bookings.

How DATEV works

DATEV is split between on-premise DATEV Rechnungswesen and the cloud DATEV Unternehmen Online layer. Authentication uses OAuth2 Authorization Code with PKCE through Login mit DATEV; there is no machine-to-machine flow, so a real tax advisor or client session is always required, and access tokens last 900 seconds with refresh. Core writes are not live: bookings are submitted as EXTF CSV files to the extf-files job API, booking suggestions go as DXSO XML jobs, and documents upload to Unternehmen Online via the documents API. The clients API returns the DATEV client id used as a path parameter everywhere. DATEV has no webhooks, so job status must be polled, and the standard chart of accounts cannot be read back through the API.

How Fishbowl works

Fishbowl Advanced runs as on-premise software, so the REST API lives on the customer's own server at a configurable host and port (default 2456) rather than a fixed cloud URL. Authentication posts an app name, app id, username, and password to the login endpoint and returns a UUID Bearer token treated as a long-lived session. It exposes vendors, purchase orders, sales orders, parts, products, inventory, and manufacture orders over JSON REST, with payments and customers reachable through the import endpoint and the data-query SQL endpoint. Fishbowl has no outbound webhooks, so changes are detected by polling list endpoints with date filters. GL accounts are not held in Fishbowl; that accounting layer is owned by the connected QuickBooks or Xero system.

What moves between them

Records flow primarily from Fishbowl into DATEV. ml-connector pulls issued purchase orders, vendor records, and payments from Fishbowl, plus the linked part and amount details, and emits them to DATEV as EXTF CSV booking batches against creditor and expense accounts, with PO and receipt PDFs going to Unternehmen Online. Vendor master data from Fishbowl populates DATEV creditor fields inside the EXTF master data rows. The cadence is scheduled polling, typically every 5 to 15 minutes against Fishbowl and a periodic batch submission to DATEV, because neither side emits events. DATEV finalized bookings are write-only and cannot be read back, so Fishbowl stays the source of truth for the operational records.

How ml-connector handles it

ml-connector holds two credential sets. For Fishbowl it stores the server URL, username, password, and app id, logging in to obtain the UUID token and re-logging in on any auth error since tokens have no documented expiry. For DATEV it runs the OAuth2 PKCE flow once with the tax advisor, then auto-refreshes the 900 second access token using client id only. On each run it polls Fishbowl purchase orders and payments by date, maps Fishbowl vendors to DATEV creditor accounts and Fishbowl tax and amount fields to DATEV Konto, Gegenkonto, Soll/Haben, and Steuerschluessel columns, then builds an EXTF CSV and submits it as an async job. The job id is polled with exponential backoff and jitter until complete. EXTF files use deterministic filenames so a retried submission is detected as a duplicate by filename and document type rather than double-posted. Key gotchas: DATEV requires UTF-8 NFC precomposed text or it silently rejects the file, document types must be fetched per client before any PDF upload, the DATEV chart of accounts must be mapped in advance because it cannot be read, and Fishbowl behind a firewall usually needs a local polling agent or SFTP CSV path.

A real-world example

A 90-person contract manufacturer in Bavaria runs production and purchasing in Fishbowl but keeps its books in DATEV through its Steuerberater. Today an accounts clerk re-types every issued purchase order and supplier payment from Fishbowl into a DATEV booking batch by hand, which is slow and drifts out of sync near month end. With this connection, ml-connector reads each issued Fishbowl PO and payment, posts it to DATEV as an EXTF booking against the correct creditor and cost center, and uploads the supplier invoice PDF to Unternehmen Online. The clerk reviews bookings in DATEV instead of keying them, and the tax advisor sees current numbers without waiting for a manual export.

What you can do

  • Issued Fishbowl purchase orders post into DATEV as structured EXTF booking batches.
  • Fishbowl vendor records map to DATEV creditor accounts inside the EXTF master data rows.
  • Supplier invoice and receipt PDFs upload into DATEV Unternehmen Online as the correct client-specific document type.
  • Fishbowl payments convert to DATEV bookings against the mapped tax codes and offset accounts.
  • Scheduled polling keeps DATEV current despite neither system supporting webhooks.

Questions

Why does this run on a schedule instead of in real time?
Neither DATEV nor Fishbowl supports outbound webhooks or event push. DATEV is pull-only and requires polling its async job status endpoints, and the Fishbowl REST API has no event subscription mechanism. ml-connector therefore polls Fishbowl list endpoints with date filters, usually every 5 to 15 minutes, and submits batched bookings to DATEV.
Can the integration read posted journal entries or the chart of accounts back from DATEV?
No. Finalized EXTF bookings sent to DATEV Rechnungswesen are write-only and cannot be retrieved through the API. The standard DATEV chart of accounts is also not exposed, so account numbers must be mapped in advance in the connector. Fishbowl stays the system of record for the operational purchase and payment data.
How does ml-connector reach an on-premise Fishbowl server?
The Fishbowl REST API runs on the customer's own server at a configurable host and port, so the server URL is a required credential field rather than a fixed cloud endpoint. When Fishbowl sits behind a firewall, a local polling agent inside the customer network or an SFTP CSV export is the usual path. The connector authenticates with the Fishbowl username and password to obtain a session token and re-logs in if that token is rejected.

Related integrations

Connect DATEV and Fishbowl

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

Get started