EU FASTER Directive · 27 Member States

Compliance infrastructure
for every EU reclaim

Submit beneficial-owner and custody-chain data to any EU member-state tax authority. Receive the official UUID per beneficial owner — the prerequisite for every WHT reclaim.

Get started → API reference
27
EU member states
3
Relief tracks
500+
Tests passing
0
External deps in test

End-to-end pipeline

From institution to UUID in four steps

Every step is validated and persisted. The pipeline fails closed before any submission — no partial reports, no silent errors.

01
Register
POST /v1/institutions
API key issued once
02
Declare event
POST /v1/dividend-events
ISIN · record date · track
03
Upload data
POST /v1/submissions
BOs · positions · eTRCs
04
Receive UUIDs
POST /v1/reports/generate
one UUID per BO

Real output

A filing, start to finish

Not a mockup. Every identifier, amount and XML fragment below is captured from an actual pipeline run against the real API — 100 SAP SE shares held in omnibus by two beneficial owners.

4 API calls
POST /v1/institutions      → Helvetia Broker AG · api_key cp_live_…
POST /v1/dividend-events   → SAP SE · DE0007164600 · record 2026-05-11
POST /v1/submissions       → 2 owners · 100 shares · 1 custody hop
POST /v1/reports/generate  → status: uuid_received
BZSt UUIDs — one per beneficial owner
dae09025-c8d3-56f7-8c4b-13225ef06015  Alpine Pension Fund (CH) · 60 sh
136619a3-bd69-51c4-89ea-24e81498ae97  John A. Investor (US)   · 40 sh
Generated MiKaDiv FM 1.02 — 5121 bytes, validates against the official BZSt XSD
<fmfach:Paymentline ISIN="DE0007164600" Zahlungstag="2026-05-14"
                    COAF="CA20260514SAP01" ArtDesWertpapieres="Aktie">
  <fmfach:AusschuettendeGesellschaft Bezeichnung="SAP SE"/>
  <fmfach:Kapitalertrag KontonummerGutschrift="CH-KONTO-60001"
                        GutschriftArt="Bargeld" Stueckzahl="60.0000"
                        KapitalertragBrutto="132.00" KapitalertragNetto="97.18">
    <fmfach:EinbehalteneSteuern Kapitalertragsteuer="33.00" Solz="1.82"
                               KapEStSteuersatz="25.00" SolzSteuersatz="5.50"
                               KapEStRechtsgrundlage="§ 43a Absatz 1 Nr. 1 EStG"/>
  </fmfach:Kapitalertrag>
  <fmfach:Stueckzahlen StueckzahlMehrAls5Tage="60.0000"
                       StueckzahlInnerhalbVon5Tagen="0.0000"
                       StueckzahlMitFinanzvereinbarung="0.0000"
                       StueckzahlOhneFinanzvereinbarung="60.0000"/>
</fmfach:Paymentline>

60 shares × €2.20 = €132.00 gross · 25 % Kapitalertragsteuer €33.00 · 5.5 % Solidaritätszuschlag €1.82 · €97.18 net. The §36a Stückzahl split and the § 43a legal basis are derived, not entered.

Every field above is supplied data or computed output — no placeholders. Where a mandatory field is not supplied, ChainPipe emits a clearly marked placeholder and the go-live preflight refuses to file for real until it is replaced.

Built for production

Everything a compliance pipeline needs

Designed for institutions that need auditability and correctness — not just a wrapper around a tax authority API.

⚙️
Durable saga workflow
State-machine persisted in PostgreSQL. Every step is idempotent and retryable. A mid-submission network failure does not lose state or double-submit to the tax authority.
validated
generating_xml
submitting_dip ← resuming after failure
awaiting_uuid
completed
27
EU member states
One transport adapter per country. Germany live today; every other EU authority plugs in without changing the pipeline or validation logic.
🔒
Fail-closed validation
BO completeness, omnibus reconciliation (Σ per-BO qty = omnibus position), eTRC validity on record date, and per-BO lot attribution consistency — all gated before any XML is generated. Unattributed §45b disaggregation is surfaced in the audit trail, never silently dropped.
Inline & queued modes
inline returns UUIDs synchronously — ideal for CI. queued returns 202 and finalises via Arq worker with DIP ack polling.
🔄
FASTER relief tracks
Relief-at-source, quick-refund, or standard reclaim per dividend event. Relief instructions exposed on a dedicated endpoint for downstream processing.
📋
Append-only audit trail
Every state transition is written to an immutable audit record — queryable and exportable for regulatory inspection at any time.
☁️
Cloud-native deploy
Docker Compose for dev. Helm (HPA + Arq worker) + Terraform for production. Prometheus metrics, OpenTelemetry tracing, EU data residency enforced.
🔎
Explainable validation & status
A read-only preflight shows, gate by gate, why a filing would pass or fail and how the custody chain reconciles — keyed on the event (POST /v1/reports/validate) or on a filed report (POST /v1/reports/{id}/validate). It also flags which officially-mandatory fields would go out as placeholders, which XSD validation alone cannot detect. GET /v1/reports/{id}/status returns the live saga state plus an audit timeline, and GET /v1/reports/{id}/xml downloads the rendered MiKaDiv payload.
📑
eTRC coverage & FASTER SLA
GET /v1/etrc/coverage reports per-beneficial-owner eTRC coverage for a dividend's record date. GET /v1/dividend-events/{id}/sla tracks the FASTER quick-refund deadline (Art 14: 60 days after the request period).
📊
Transparent pricing & analytics
Public subscription tiers (GET /v1/pricing) and a cost calculator (GET /v1/pricing/quote) — predictable cost, not contingency fees. GET /v1/usage/billing-summary projects a tenant's spend from metered usage, and GET /v1/analytics/summary quantifies recovery yield across reports and reclaims.
⚖️
§45b Stückzahl per-BO split
Acquisition lots on omnibus positions accept a per-lot beneficial_owner_id tag. The pipeline attributes MehrAls5Tage / InnerhalbVon5Tagen buckets accurately per creditor. Falls back to the safe all-MehrAls5Tage default and records unattributed BOs in the audit trail for resubmission.
🇩🇪
DE inland person variants
German-resident BOs are rendered via the correct §45b inland person type: NatInlandMitId (IdNr), NichtNatInlandMitWid (WIdNr), or NichtNatInlandMitStNr (Steuernr). Gracefully falls back to the foreign-resident variant when no usable German tax id is present.
🏦
GLEIF-enriched chain & Verwahrstelle accounts
Custody-chain nodes are enriched with real name, city, and country from GLEIF. Client-supplied depot_account_number + depot_account_type (A–G) per hop override the placeholder and are written into the MiKaDiv XML as ArtDesDepotkontos.
🚫
Art. 11 fast-track exclusions
Fail-closed exclusion engine: 5-day acquisition rule, unsettled financial arrangements, EUR 100k threshold (pension / UCITS / AIF carve-out), non-CFI chain gap. Excluded claims fall back to the standard refund track with persisted reasons. Registered-owner self-declarations (annual validity, KYC discrepancy blocking) gate both fast tracks.
🗓️
Annex II reporting & Art. 13/14 clocks
Jurisdiction-agnostic Annex II record assembly with a completeness gate and a deterministic draft-2026 XML renderer (/v1/annex2) — an explicit seam for the Commission's XSD. The SLA endpoint adds the Art. 13 reporting deadline and per-claim Art. 14(3) late-payment interest, closed at refunded_on via POST /v1/reclaims/{id}/refund.
🛡️
QESeal, CFI watch & liability
eIDAS QESeal verification seam for eTRCs — fail-closed on a positive invalid verdict. CFI registration tracking plus an hourly counterparty sweep raising cfi_alerts and webhooks. GET /v1/liability/exposure quantifies strict-liability exposure with risk flags and an exclusion-override invariant detector.

Country coverage

Germany live — EU rollout in progress

Each member state is a transport adapter. The pipeline, validation, and saga stay identical across every country.

🇩🇪
Germany
BZSt · MiKaDiv DIP
● Live
🇫🇷
France
DGFiP
◑ Planned
🇳🇱
Netherlands
Belastingdienst
◑ Planned
🇧🇪
Belgium
SPF Finances
○ Roadmap
🇦🇹
Austria
BMF
○ Roadmap
🇪🇸
Spain
AEAT
○ Roadmap
🇮🇹
Italy
Agenzia Entrate
○ Roadmap
🇸🇪
Sweden
Skatteverket
◑ Planned
🇩🇰
Denmark
Skattestyrelsen
○ Roadmap
🇵🇱
Poland
KAS
○ Roadmap
🇵🇹
Portugal
AT
○ Roadmap
🇪🇺
+16 more
All EU member states
○ FASTER 2030

Regulatory scope

Built for FASTER from day one

Not retrofitted. Data model and transport seam were designed around standardised FASTER reporting from the start.

🇪🇺
EU FASTER Directive
Relief-at-source, quick-refund, and standard reclaim tracks gated by the Art. 11 exclusion engine and registered-owner self-declarations. Annex II standardised reporting with an XSD-ready renderer. Art. 13 reporting deadline + Art. 14(3) late-payment interest. QESeal eTRC verification and CFI register monitoring seams. Third-country proof of residence for non-EU beneficial owners. Multi-member-state transport seam (DE live; FR/NL/SE seams). Terraform validates eu-* regions only.
🇩🇪
MiKaDiv — Germany
BZSt DIP submission with mTLS. ELMA ack polling for async UUID delivery. Omnibus reconciliation, eTRC validity, and per-BO §45b lot attribution before every submission. DE-resident BOs rendered via NatInlandMitId / NichtNatInlandMitWid / NichtNatInlandMitStNr. Verwahrstelle nodes enriched from GLEIF; client-supplied depot accounts accepted per hop. Client-provided COAF, security type, and credit kind carried through to the filing.
🏛️
Audit & Security
Append-only audit log on every transition. Egress NetworkPolicy scoped per authority endpoint. API keys per institution, shown once. Trivy image scanning in CI.

Technology

Modern async Python stack

FastAPI async REST
Pydantic v2 validation
PostgreSQL SQLAlchemy 2.0
Redis queue + cache
Arq worker
S3 XML payloads
Docker Compose
Helm HPA + worker
Terraform infra
Prometheus
OpenTelemetry
Python 3.11+

Get started

Up and running in minutes

Zero external services required — the unit suite runs in-process with a mock DIP client and no database container.

# install dev dependencies
pip install -r requirements-dev.txt

# 500+ unit tests — no external services required
pytest -q

500+ passed (integration tests need Postgres)
View on GitHub →

Ready to automate your WHT pipeline?

Clone the repo, run the quickstart, and have a report generating UUIDs in under ten minutes.

View on GitHub → API reference