Skip to content
Fintech

DSFinV-K Exports with fiskaly: Cash Point Closings Done Right

The export a German tax auditor actually asks for: master data setup, asynchronous cash point closing ingestion with its validation gotchas, and one-click TAR exports from your admin panel.

5 min read Updated Sep 4, 2026
DSFinV-K Exports with fiskaly: Cash Point Closings Done Right

When a German tax auditor visits a cash-based business, they don't ask for your database schema — they ask for a DSFinV-K export: a standardized bundle of CSV files describing every transaction, every VAT split and every cash-point closing, in the exact structure the Digitale Schnittstelle der Finanzverwaltung für Kassensysteme prescribes. The fiskaly DSFinV-K API turns that format from a 100-page PDF into a REST workflow. This article covers the data model, the cash-point-closing lifecycle, and how to generate audit-ready exports on demand.

Flow: cash register data becomes cash point closings, validated asynchronously, then exported as CSV in a TAR archive

Key takeaways

  • The central aggregate is the cash point closing — the Z-report of a register for a period, with sequential Z-NR numbering.
  • Master data first: cash registers (MASTER/SLAVE), VAT definitions, and purchaser agencies must exist before closings reference them.
  • Closings are ingested asynchronously (PENDING → WORKING → COMPLETED | ERROR) — only COMPLETED closings can be exported.
  • Exports arrive as TAR/ZIP of CSVs per DSFinV-K 2.3 — exactly what the auditor's IDEA software expects to import.

The data model

ResourceRoleNotes
Cash registerA physical deviceMASTER manages SLAVE terminals; linked by client ids
VAT definitionTax-rate mappingIDs 1–7 are predefined (19%, 7%, …); 1000+ are yours to define
Purchaser agencyThird party you collect revenue forThink concert tickets sold at your counter
Cash point closingThe period aggregateTransactions, payment types, cash flow, VAT allocation, Z-NR
ExportThe audit artifactTAR/ZIP of CSVs, filtered by date or client

Step 1 — Master data

# JWT auth, same pattern as the other fiskaly APIs
curl -X POST https://dsfinvk.fiskaly.com/api/v1/auth \
  -d '{"api_key": "...", "api_secret": "..."}'

# Register the till
curl -X PUT .../api/v1/cash_registers/$CLIENT_ID -d '{
  "cash_register_type": { "type": "MASTER" },
  "brand": "YourPOS", "model": "v3",
  "base_currency_code": "EUR",
  "software": { "brand": "YourPOS" }
}'

# Custom VAT definition beyond the predefined 1–7
curl -X PUT .../api/v1/vat_definitions/1001 -d '{
  "percentage": 10.7, "description": "Landwirtschaftliche Produkte"
}'

Step 2 — Submit cash point closings

At the end of each business day (or shift), your POS aggregates the day and submits one closing per register. The payload is the deep one in this API — transactions with business cases, amounts per VAT rate, and payment types — and ingestion is asynchronous:

// Illustrative C#: submit, then poll the validation state
var closingId = Guid.NewGuid();

await api.PutAsJsonAsync($"/cash_point_closings/{closingId}", new {
    client_id = registerId,
    cash_point_closing_export_id = zNumber,      // sequential Z-NR
    head = new {
        business_date = "2026-09-01",
        first_transaction_export_id = "1",
        last_transaction_export_id = "214",
    },
    cash_statement = new {
        payment = new {
            full_amount = "4321.90",
            cash_amount = "1201.40",
            payment_types = new[] {
                new { type = "CASH", currency_code = "EUR", amount = "1201.40" },
                new { type = "ECARD", currency_code = "EUR", amount = "3120.50" },
            }
        }
    },
    transactions = dayTransactions,              // the real bulk
});

var state = await PollUntilAsync(
    () => api.GetStateAsync($"/cash_point_closings/{closingId}"),
    s => s is "COMPLETED" or "ERROR");

if (state == "ERROR")
    compliance.Alert(await api.GetValidationErrorsAsync(closingId));

Field-level gotchas that surface in validation:

  • Serial numbers: ≤ 70 characters, no slashes or underscores (DSFinV-K 2.3).
  • Z-NR must be strictly sequential per register — gaps are questions an auditor will ask.
  • Amounts are strings with fixed decimal formatting; don't let your JSON serializer "help" with floats.
  • Only uncompleted closings can be deleted — model corrections as new closings, not edits.

Step 3 — Exports on demand

# Trigger, filtered by business date range
curl -X PUT .../api/v1/exports/$EXPORT_ID -d '{
  "start_date": "2026-01-01", "end_date": "2026-09-01"
}'

# Poll, then download
curl .../api/v1/exports/$EXPORT_ID
curl -o dsfinvk.tar .../api/v1/exports/$EXPORT_ID/download

Build this into your product's admin as "Download audit export" with a date picker. The retailer who can hand the auditor a USB stick in five minutes has a very different audit experience from the one who needs "a few days".

How this fits with SIGN DE

The two APIs answer different auditor questions: SIGN DE proves each transaction was signed at the time it happened (TSE log export); DSFinV-K proves the books add up (structured business data). A complete German fiscalization stack ships both — plus the §146a declaration so the authorities even know your tills exist.

FAQ

Do I submit closings in real time?

No — a closing is inherently end-of-period. Real-time is the TSE's job; DSFinV-K is the bookkeeping aggregate. Daily submission right after your Z-report is the sweet spot.

What if validation fails on day 200?

Fix the data and submit a corrected closing; keep the failed attempt's error report. Systematic validation failures are a data-model smell in your POS aggregation — worth a design review.

Can one export cover multiple registers?

Yes — filter by date range and optionally by client id. Per-store exports (one register set per establishment) map most cleanly to how audits are scoped.

Next steps

If you're building a POS or vertical SaaS touching the German market, fiscalization is a launch blocker best handled early. Book an architecture session or brief me on your project — I've mapped these regulatory flows so you don't have to learn them the audited way.

Keep reading

Related articles