Zum Hauptinhalt springen

Finanzen

Sechs Bereiche, bewusst getrennt: Eine Vereinswebsite, die Zuwendungsbestätigungen ausstellt, hat nichts in den Kontoauszügen zu suchen – deshalb ist spenden kein Teil von bank.

Alle Pfade sind relativ zu https://<domain>/api/v1.


Bank

Bereich bank. Konten, Buchungen, Belege und Kostenstellen.

MethodePfadBereichBeschreibung
GET/bankbank:readKonten (Liste)
GET/bank/{accountId}bank:readEin Konto
GET/bank/{accountId}/buchungenbank:readBuchungen (Liste)
POST/bank/{accountId}/buchungenbank:writeManuelle Buchung erfassen
GET/bank/{accountId}/buchungen/{txId}bank:readEine Buchung
PUT/bank/{accountId}/buchungen/{txId}bank:writeZuordnung nachziehen
GET/bank/belegebank:readBelege (Liste)
POST/bank/belegebank:writeBeleg anlegen
GET/bank/belege/{id}bank:readEin Beleg samt Aufteilung
PUT/bank/belege/{id}bank:writeBeleg ändern
DELETE/bank/belege/{id}bank:writeBeleg löschen
GET/bank/belege/{id}/inhaltbank:readDie Belegdatei
PUT/bank/belege/{id}/inhaltbank:writeBelegdatei nachreichen
GET/bank/kostenstellenbank:readKostenstellen (Liste)
GET/bank/kategorienbank:readBuchungskategorien (Liste)
Zwei bewusste Grenzen

Kontoauszüge werden nicht über die Schnittstelle importiert. Der CAMT-Import hat Dubletten-Erkennung, Saldo-Abgleich und Fehlerprotokoll; ein Dateiupload würde die halbe Mechanik umgehen.

Konten anlegen und das Regelwerk ändern bleibt der Anwendung vorbehalten. Beides ändert, wie alle künftigen Buchungen zugeordnet werden – das gehört nicht in ein Skript.

Buchungen

Filter: q (Zweck und Beteiligte), von, bis (Buchungsdatum), kategorie, kostenstelle. Sortierbar: booking_date (Standard), value_date, amount.

Manuelle Buchung anlegen (Barkasse, Nachtrag):

FeldTypAnmerkung
booking_dateJJJJ-MM-TTPflicht
value_dateJJJJ-MM-TTWertstellung
amountZahlPflicht; negativ = Ausgabe
currency3 Zeichen
purposeTextVerwendungszweck
counterparty_iban, debtor_name, creditor_nameTextGegenseite
category, cost_centerText
noteText

Beim Ändern einer Buchung sind nur die App-Felder erlaubt: category, cost_center, note, receipt_ref, reviewed. Betrag und Datum sind das, was die Bank gemeldet hat, und werden nicht nachträglich über die Schnittstelle verändert.

Belege

Filter: q (Bezeichnung, Belegnummer), von, bis (Belegdatum). Sortierbar: receipt_date (Standard), amount, created_at.

FeldTypAnmerkung
descriptionTextPflicht – die Bezeichnung des Belegs
receipt_dateJJJJ-MM-TTPflicht
amountZahlPflicht
directionincome | expense
category, cost_centerText
submitter_noteTextNotiz der einreichenden Person
Die Feldnamen sind die der Datenbank

title, vendor oder project gibt es an einem Beleg nicht – unter solchen Namen geschickte Werte würden stillschweigend verschwinden.

Ein GET /bank/belege/{id} liefert den Beleg ohne die Datei: Belege enthalten oft Adressen und Kontodaten Dritter. Die Datei kommt einzeln über /inhalt – und lässt sich dort auch nachreichen, etwa aus einem Scan-Ordner:

curl -X PUT -H "Authorization: Bearer $KEY" \
-H "Content-Type: application/pdf" --data-binary @quittung.pdf \
"$BASIS/bank/belege/<id>/inhalt?name=quittung.pdf"

Obergrenze 20 MB (Belege liegen in der Datenbank), darüber 413 too_large.


Beiträge

Bereich beitraege. Eine Sammlung ist ein Anlass („Mitgliedsbeitrag 2026“), eine Forderung eine einzelne Zahlungspflicht daraus.

MethodePfadBereichBeschreibung
GET/beitraegebeitraege:readForderungen (Liste)
POST/beitraegebeitraege:writeForderungen anlegen (Stapel)
GET/beitraege/{id}beitraege:readEine Forderung
PUT/beitraege/{id}beitraege:writeForderung ändern
DELETE/beitraege/{id}beitraege:writeForderung löschen
POST/beitraege/{id}/statusbeitraege:writeStatus setzen
GET/beitraege/mitglied/{contactId}beitraege:readForderungen einer Person
GET/beitraege/sammlungenbeitraege:readSammlungen (Liste)
GET/beitraege/sammlungen/{id}beitraege:readEine Sammlung
PUT/beitraege/sammlungen/{id}beitraege:writeSammlung umbenennen

Filter: q, sammlung_id, status, kostenstelle, zahlweg. Sortierbar: created_at (Standard), due_date, amount, status.

Forderungen entstehen als Stapel, weil sie in der Praxis so entstehen („allen Wölflingen den Jahresbeitrag stellen“):

{
"sammlung": { "mode": "new", "name": "Mitgliedsbeitrag 2026", "kind": "membership" },
"defaults": { "description": "Jahresbeitrag", "due_date": "2026-03-01", "cost_center": "Verein" },
"forderungen": [
{ "contact_id": "<uuid>", "amount": 42 },
{ "payer_name": "Familie Beispiel", "amount": 84, "description": "zwei Kinder" }
]
}

sammlung.mode ist existing (dann id) oder new (dann name, optional kind: manual, membership, event). defaults gilt für alle Zeilen, die nichts Eigenes mitbringen.

Status setzen: {"status":"paid","paid_at":"2026-03-04","payment_method":"lastschrift"}. Erlaubt sind open, paid, cancelled. Eigener Endpunkt, weil daran Zahldatum und Zahlweg hängen – ein direktes Schreiben der Spalte hinterließe eine bezahlte Forderung ohne Zahldatum.

Die SEPA-Lastschriftdatei entsteht nur in der Anwendung

Damit wird Geld eingezogen; das bleibt ein bewusster Vorgang mit der dortigen Vorschau samt Liste der übersprungenen Mandate.


Spenden

Bereich spenden. Zuwendungsbestätigungen samt PDF.

MethodePfadBereichBeschreibung
GET/spendenspenden:readBestätigungen (Liste)
POST/spendenspenden:writeBestätigung ausstellen
GET/spenden/{id}spenden:readEine Bestätigung
PUT/spenden/{id}spenden:writeNur die interne Notiz ändern
POST/spenden/{id}/stornospenden:writeStornieren (Grund erforderlich)
GET/spenden/{id}/pdfspenden:readDie Bestätigung als PDF
POST/spenden/{id}/als-belegspenden:write + bank:writeAls Beleg in die Buchhaltung
GET/spenden/einstellungenspenden:readAussteller-Angaben (nur lesend)
GET/spenden/kandidatenspenden:readBuchungen, die sich noch bescheinigen lassen

Filter: q (Name, Nummer), jahr, art (money, goods, waiver), inkl_storniert. Sortierbar: issued_on (Standard), receipt_number, amount, donation_date.

FeldTypAnmerkung
kindmoney | goods | waiverGeld, Sache, Aufwandsverzicht; Standard money
donor_nameTextPflicht
donor_contact_idUUIDwenn die Person im Bestand steht
donor_addressText
amountZahl oder TextPflicht
donation_dateJJJJ-MM-TTbei Einzelzuwendungen
is_collective, period_from, period_toSammelbestätigung über einen Zeitraum
goods_description, goods_origin, goods_value_basisbei Sachzuwendungengoods_origin: business, private, unknown
transaction_idUUIDzugrunde liegende Buchung
issued_onJJJJ-MM-TT
notesTextinterne Notiz
Ausstellen ist unwiderruflich

Eine Bestätigung bekommt eine fortlaufende Nummer und geht an das Finanzamt. Es gibt kein DELETE, sondern nur den Storno mit Begründung – wie in der Anwendung. Und PUT ändert ausschließlich notes: alles andere steht auf dem Dokument.

Fehlen die Aussteller-Angaben, bricht das Ausstellen mit 400 ab und nennt sie in details.missing. Was fehlt, sagt vorab auch GET /spenden/einstellungen in meta.missing – ein Werkzeug soll nicht reihenweise Dokumente erzeugen, die das Finanzamt zurückweist.

Kandidaten (von, bis, kategorien kommagetrennt, mitglied_id) sind Buchungen ohne gültige Bestätigung – die Arbeitsliste für ein Spendentool.


Fahrtkosten

Bereich fahrtkosten. Der Weg ist derselbe wie in der Anwendung: offen → eingereicht → freigegeben → ausgezahlt.

MethodePfadBereichBeschreibung
GET/fahrtkostenfahrtkosten:readAbrechnungen (Liste)
POST/fahrtkostenfahrtkosten:writeAbrechnung anlegen
GET/fahrtkosten/{id}fahrtkosten:readEine Abrechnung
PUT/fahrtkosten/{id}fahrtkosten:writeÄndern
DELETE/fahrtkosten/{id}fahrtkosten:writeLöschen
POST/fahrtkosten/{id}/statusfahrtkosten:writeStatuswechsel
GET/fahrtkosten/{id}/pdffahrtkosten:readDas ausgefüllte Formular als PDF
POST/fahrtkosten/{id}/als-belegfahrtkosten:write + bank:writeAls Auslage in die Buchhaltung
GET/fahrtkosten/einstellungenfahrtkosten:readKilometersatz und Formularangaben

Filter: q (Name, Nummer, Anlass), status, veranstaltung_id, jahr. Sortierbar: created_at (Standard), claim_number, total_amount, total_km, status.

FeldTypAnmerkung
person_nameTextPflicht
person_contact_id, person_address
ibanTextwird geprüft, wenn angegeben (Barerstattung braucht keine)
license_plateText
event_idUUIDBezug zur Veranstaltung
purposeTextAnlass
cost_center, categoryText
rate_centsZahlabweichender Kilometersatz
received_on, received_fromEingang der Abrechnung
notesText
tripsListedie Fahrten

Eine Fahrt: trip_date, start_address, end_address, reason, km, round_trip, km_source (manual oder auto).

Der Betrag wird gerechnet, nicht übernommen

Kilometer × hinterlegter Satz. Ein mitgeschickter Betrag wird ignoriert. Den geltenden Satz liefert GET /fahrtkosten/einstellungen – nur lesend, denn daran hängt, was der Verein tatsächlich auszahlt.

Statuswechsel: {"status":"paid","ausgezahlt_am":"2026-08-01"} – erlaubt sind open, submitted, approved, paid; ausgezahlt_am gilt nur beim Wechsel auf paid.

Als Beleg ablegen erzeugt eine Auslage samt PDF in der Buchhaltung. Zweimal geht das nicht (409 conflict), und ohne Fahrten gibt es nichts zu erstatten.

Die Entfernungsberechnung gibt es hier nicht

Sie ruft einen fremden Kartendienst auf Kosten des Vereins auf; ein Skript in einer Schleife hätte das Tageskontingent verbraucht, bevor es jemand merkt. Kilometer lassen sich angeben.


Abrechnung

Bereich abrechnung. Eine Abrechnung bündelt Belege (aus dem Belege-Bereich der Bankbuchhaltung) und Einnahmen zu einer Veranstaltung oder einem Zeitraum.

MethodePfadBereichBeschreibung
GET/abrechnungabrechnung:readListe
POST/abrechnungabrechnung:writeAnlegen
GET/abrechnung/{id}abrechnung:readVollständig, mit Belegen, Einnahmen und Kategorien
PUT/abrechnung/{id}abrechnung:writeÄndern
DELETE/abrechnung/{id}abrechnung:writeLöschen
GET/abrechnung/{id}/belegeabrechnung:readBeleg-Auswahl (Liste)
PUT/abrechnung/{id}/belegeabrechnung:writeBeleg-Auswahl vollständig setzen
GET/abrechnung/{id}/einnahmenabrechnung:readEinnahmen (Liste)
POST/abrechnung/{id}/einnahmenabrechnung:writeEinnahme ohne Bankbezug erfassen
DELETE/abrechnung/{id}/einnahmen/{einnahmeId}abrechnung:writeEinnahme entfernen
FeldTypAnmerkung
titleTextPflicht
descriptionText
event_idUUIDBezug zur Veranstaltung
period_from, period_toJJJJ-MM-TT
responsible_nameText
statusopen | closed

Beleg-Auswahl setzen: {"beleg_ids":["<uuid>","<uuid>"]}. Der Aufruf ersetzt die Zuordnung vollständig und nummeriert anschließend neu durch – die Nummern auf dem Beleg-Stempel müssen zur Reihenfolge in der Mappe passen.

Einnahme ohne Bankbezug (Barzahlung, Zuschuss per Scheck): description (Pflicht), amount (Pflicht), booking_date, note.

Belege werden hier nicht erfunden

Sie kommen aus dem Belege-Bereich, Einnahmen aus den Buchungen. Über die Schnittstelle lässt sich die Auswahl setzen, nicht ein Beleg erzeugen – das wäre eine zweite Belegquelle mit eigener Nummernfolge.


Kalkulation

Bereich kalkulation. Budgetplanung für Lager: Szenarien („knapp“, „realistisch“), Parameter (Teilnehmerzahl, Tage) und Positionen (Verpflegung, Fahrt).

MethodePfadBereichBeschreibung
GET/kalkulationkalkulation:readListe
POST/kalkulationkalkulation:writeAnlegen
GET/kalkulation/{id}kalkulation:readEinzeln lesen
PUT/kalkulation/{id}kalkulation:writeÄndern
DELETE/kalkulation/{id}kalkulation:writeLöschen
POST/kalkulation/{id}/positionenkalkulation:writePosition anlegen
PUT/kalkulation/{id}/positionen/{positionId}kalkulation:writePosition ändern
DELETE/kalkulation/{id}/positionen/{positionId}kalkulation:writePosition entfernen
POST/kalkulation/{id}/parameterkalkulation:writeParameter anlegen
PUT/kalkulation/{id}/parameter/{parameterId}kalkulation:writeParameter ändern
DELETE/kalkulation/{id}/parameter/{parameterId}kalkulation:writeParameter entfernen
PUT/kalkulation/{id}/wertekalkulation:writeWerte je Szenario setzen
FeldTypAnmerkung
titleTextPflicht
descriptionText
event_idUUID
fee_round_stepZahl ≥ 0Rundungsschritt des Teilnehmerbeitrags
fee_round_modeceil | floor | round
statusdraft | final
templateWahrheitswertnur beim Anlegen: false erzeugt eine leere Kalkulation

Ohne template: false kommt die übliche Vorlage mit – damit ein Aufruf ohne weitere Angaben dasselbe Ergebnis liefert wie der Knopf in der Anwendung.

Position: bezeichnung (Pflicht), szenario_id, gruppe, art, formel, note, sort_order. Parameter: schluessel (Pflicht), bezeichnung, einheit, note, sort_order.

Werte setzen geht in einem einzigen Aufruf für parameter und positionen zusammen:

{ "parameter": [ { "…": "…" } ], "positionen": [ { "…": "…" } ] }

Einzeln geschrieben stünde die Kalkulation zwischendurch auf halbem Weg – Parameter- und Positionswerte ergeben zusammen eine Rechnung.

Hat dies deine Frage beantwortet?