Accounting System Integration
Getting booked invoices out of SpendOne and into your financial system. Export is asynchronous and job-based throughout: you request an export, poll the job, then fetch the file. There is no real-time synchronization path and no push into your ledger.
Supported methods
An export profile is configured per tenant with one of five methods:
| Method | What it produces |
|---|---|
CSV | A CSV file shaped by a configurable export profile |
EMAIL | The export file delivered by email |
SAP | An SAP-shaped file, fetched through the SAP download URL |
DATEV | A booking proposal submitted to DATEV Unternehmen Online |
DATEV_REWE | A document upload to DATEV Unternehmen Online followed by a Rechnungswesen booking entry |
GET /api/v1/csv-export/method returns the method this tenant is configured for.
POST /api/v1/fi-export/jobs reads that setting and routes to whichever method
the tenant runs, so an integration that uses the job flow below needs no
per-method branching. The DATEV-specific endpoints exist alongside it and are
described under DATEV.
The export job flow
POST /api/v1/fi-export/jobs
Authorization: Bearer <access-token>
Content-Type: application/json
{
"invoice_codes": ["INV-1042"],
"purchase_order_codes": [],
"task_codes": []
}
Then poll and download:
GET /api/v1/fi-export/jobs # list jobs
GET /api/v1/fi-export/jobs/{job_code} # one job's status
GET /api/v1/fi-export/jobs/{job_code}/download-url # signed URL for the file
GET /api/v1/fi-export/jobs/{job_code}/sap-download-url # the SAP variant
One job carries many invoices, so this is the bulk path as well as the
single-invoice one. GET /api/v1/fi-export/jobs/{job_code} answers with both
halves of the outcome: the job's own total_items / successful_items /
failed_items counters, and a submissions array with one entry per invoice
carrying its invoice_code, status and error_message. Read the array, not
only the counters, to find out which invoice failed.
Configuring the mapping
Before a first export, the chart of accounts and the export shape have to exist:
GET /api/v1/accounts # chart of accounts
POST /api/v1/accounts/import # bulk-load it
On a DATEV tenant, GET /api/v1/datev/accounts returns the accounting accounts
the MAESN integration exposes for the tenant, and the per-entity export
configuration sits at GET /api/v1/datev/exports/configs, GET and PATCH /api/v1/datev/exports/configs/{code}.
For the CSV method, the column layout is a profile:
GET /api/v1/csv-export/profiles
POST /api/v1/csv-export/profiles
POST /api/v1/csv-export/profiles/{code}/fields
GET /api/v1/csv-export/available-fields
GET /api/v1/csv-export/targets # S3 or SFTP destination
GET /api/v1/csv-export/lookup-tables # value translation tables
Tax-code translation is separate, and required before an invoice with an unmapped
tax rate can be transferred: GET /api/v1/tax-mappings. An unmapped rate fails the
transfer with problem type booking-tax-code-unmapped.
Journal entries
The booking itself is inspectable and editable before export:
GET /api/v1/journal-entries
GET /api/v1/journal-entries/{code}
POST /api/v1/journal-entries/{code}/lines
PUT /api/v1/journal-entries/{code}/lines/{id}
DELETE /api/v1/journal-entries/{code}/lines/{id}
The proposal that precedes it lives on the invoice:
GET /api/v1/invoices/{code}/booking-proposal and its PUT.
Related
- Pull invoice data for reading invoices, bookings and export jobs back out.
- Core Concepts for what has to be configured before a first export.
- API Basics for the response envelope and error model.
DATEV
DATEV is one of the five export methods, not the general shape of an export: a
tenant on CSV, EMAIL or SAP never touches anything in this section, and
POST /api/v1/fi-export/jobs covers all five. What follows is what the DATEV
and DATEV_REWE methods add on top.
The connection is an OAuth app. GET /api/v1/datev/status reports whether it is
live, and GET /api/v1/datev/auth-url starts the flow. The redirect targets that
flow hands DATEV are served by the platform and are not part of the published
surface: a browser reaches them, an integration never calls them.
DELETE /api/v1/datev/account-key disconnects the stored account key.
For the DATEV method an invoice can also be submitted one at a time, and the
result is tracked as a submission rather than a file:
POST /api/v1/invoices/{code}/send-to-datev # 202, transmission runs in the background
GET /api/v1/invoices/{code}/datev-submissions # every submission for it
GET /api/v1/invoices/{code}/datev-submission/latest # the most recent
GET /api/v1/datev/submissions/{id} # one submission by id
POST /invoices/{code}/send-to-datev always enqueues a DATEV Unternehmen Online
booking proposal, which is the DATEV mode's shape; it does not read the
tenant's configured export method, and it answers 503 when the MAESN
integration is not configured. The two-leg DATEV_REWE flow has no per-invoice
route, so a ReWe tenant exports through POST /api/v1/fi-export/jobs.