# Datentypen (https://developer.bimetrics.de/data-types)

Wie Datumswerte, Zeitpunkte, Beträge, Prozentsätze, IDs und feste Werte in Antworten und Filtern aussehen.

## Überblick

| Art            | In Antworten                        | In Filtern                        | Beispiele                                                                      |
| -------------- | ----------------------------------- | --------------------------------- | ------------------------------------------------------------------------------ |
| Kalenderdatum  | Objekt `{ "year", "month", "day" }` | String `JJJJ-MM-TT`               | `invoiceDate`, `dueDate`, `bookingDate`, `valueDate`                           |
| Zeitpunkt      | String nach RFC 3339 mit Zeitzone   | String nach RFC 3339 mit Zeitzone | `createdAt`, `updatedAt`, `finalized`                                          |
| Betrag in Cent | Ganzzahl                            | Zahl                              | `transactionAmount`, `balance`, `invoicePositions[].total`, `match.amountOpen` |
| Betrag in Euro | Dezimalzahl als String              | String, siehe [Beträge](#beträge) | `amount` bei Buchungen                                                         |
| Prozentsatz    | Dezimalzahl als String              | –                                 | `invoicePositions[].vatPercentage`, `cashDiscount.percent`                     |
| ID             | UUID als String                     | UUID als String                   | `id`, `bankAccountId`, `refDocumentId`                                         |
| Fester Wert    | String aus einer festen Liste       | String                            | `kind`, `status`, `uploadDocument.ocrStatus`                                   |

Welche Attribute sich filtern lassen und welchen Typ sie haben, steht unter [Filtern und Paginieren](/filtering#attribute-je-route).

## Kalenderdaten

Rechnungsdatum, Fälligkeit, Buchungstag und ähnliche Angaben sind Kalenderdaten ohne Uhrzeit und ohne Zeitzone. In Antworten kommen sie als Objekt:

```json
{ "invoiceDate": { "year": 2026, "month": 9, "day": 30 } }
```

Fehlt ein Datum, etwa solange ein Beleg noch nicht erkannt ist, ist der Wert `null`.

In Filtern schreibst du ein Kalenderdatum als String im Format `JJJJ-MM-TT`, mit führenden Nullen und ohne Uhrzeit:

```json
{ "kind": "range", "attribute": "invoiceDate", "lower": "2026-09-01", "upper": "2026-09-30" }
```

* `range` schließt beide Grenzen ein. Das Beispiel trifft alle Belege mit einem Rechnungsdatum im September 2026.
* Die API vergleicht Kalenderdaten Zeichen für Zeichen in diesem Format. Andere Schreibweisen lehnt sie hier nicht ab, sie liefern aber falsche Treffer. So schließt `2026-09-01T00:00:00Z` als Untergrenze den 1. September aus.
* Eine Zeitzone spielt keine Rolle: Ein Filter auf `invoiceDate` trifft das Datum, das auf dem Beleg steht.

### Welches Datum was bedeutet

| Ressource | Attribut      | Bedeutung                                                                                                                                    |
| --------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| Belege    | `invoiceDate` | Rechnungsdatum laut Beleg                                                                                                                    |
| Belege    | `createdAt`   | Zeitpunkt, zu dem der Beleg in bimetrics angelegt wurde                                                                                      |
| Umsätze   | `bookingDate` | Buchungstag laut Bank                                                                                                                        |
| Umsätze   | `valueDate`   | Wertstellung laut Bank                                                                                                                       |
| Buchungen | `bookingDate` | Buchungsdatum: bei Buchungen zu einem Beleg in der Regel das Rechnungsdatum, bei Buchungen zu einem Umsatz dessen Wertstellung (`valueDate`) |

Erstreckt sich der Leistungszeitraum eines Belegs über mehrere Monate, verteilt bimetrics den Betrag auf diese Monate. Die Buchungen tragen den jeweiligen Zeitraum dann in `performanceFrom` und `performanceTo`.

## Zeitpunkte

`createdAt`, `updatedAt`, `finalized` und ähnliche Angaben sind Zeitpunkte. Sie kommen als String nach RFC 3339 mit Zeitzone, auf Mikrosekunden genau:

```json
{ "updatedAt": "2026-09-27T08:15:42.123456Z" }
```

In Filtern schreibst du Zeitpunkte ebenfalls nach RFC 3339, zum Beispiel `2026-09-01T00:00:00Z` oder `2026-09-01T00:00:00+02:00`.

* Gib die Zeitzone immer mit an. Einen Wert ohne Zeitzone oder ohne Uhrzeit, etwa `2026-09-01`, liest die Datenbank in ihrer eigenen Zeitzone. Darauf solltest du dich nicht verlassen.
* Einen Zeitpunkt aus einer Antwort kannst du unverändert als Filterwert verwenden. Das nutzt der [Delta-Sync](/recipes/delta-sync).
* Die API nimmt auch die übrigen Formen nach ISO 8601 an: ein Leerzeichen statt `T`, eine Uhrzeit ohne Sekunden, einen Wert ohne Zeitzone oder nur ein Datum, etwa `2026-09-01 08:15`. Andere Schreibweisen, etwa `01.09.2026`, ergeben `400`.

## Beträge

### Beträge in Cent

Die meisten Beträge sind Ganzzahlen in Cent: `11900` steht für 119,00 €.

| Feld                                                          | Bedeutung                                                           | Vorzeichen                                   |
| ------------------------------------------------------------- | ------------------------------------------------------------------- | -------------------------------------------- |
| `transactionAmount` (Umsätze)                                 | Betrag des Umsatzes                                                 | positiv bei Eingängen, negativ bei Ausgängen |
| `balance` (Bankkonten)                                        | Saldo zum Zeitpunkt `balanceDate`                                   |                                              |
| `invoicePositions[].total` (Belege)                           | Bruttobetrag der Position                                           |                                              |
| `match.amountOpen` (Belege, Umsätze)                          | offener Betrag der Zuordnung, `0`, wenn Belege und Umsätze aufgehen |                                              |
| `cashDiscount.basisAmount`, `discountAmount`, `payableAmount` | Skonto: Grundlage, Abzug und Zahlbetrag                             |                                              |

Den Bruttobetrag eines Belegs erhältst du als Summe von `total` über alle `invoicePositions`. Die Währung steht bei Umsätzen in `transactionCurrency` und bei Bankkonten in `currency`.

In Filtern gibst du Cent-Beträge als Zahl an, etwa `{ "kind": "range", "attribute": "transactionAmount", "upper": -10000 }` für Ausgänge ab 100,00 €.

### Beträge von Buchungen

Das Feld `amount` einer Buchung ist ein Betrag in Euro als Dezimalzahl im String, zum Beispiel `"119"`, `"-19.5"` oder `"1234.56"`.

* Das Vorzeichen bezieht sich auf das Konto in `account`: größer als 0 ist Soll, kleiner als 0 ist Haben. Das Gegenkonto `accountContra` hat die umgekehrte Seite.
* Die Zahl hat keine feste Anzahl an Nachkommastellen. 119,00 € kommt als `"119"`, 19,50 € als `"19.5"`.
* Lies den Wert als Dezimalzahl, nicht als Gleitkommazahl, damit keine Rundungsfehler entstehen.

> **Beträge von Buchungen in Filtern:** Die API vergleicht `amount` in Filtern und beim Sortieren als Text. Ein Filterwert muss deshalb ein String in genau der Schreibweise aus den Antworten sein, also `"119"` und nicht `"119.00"` oder `119`. `range` und `sort` nach `amount` ergeben keine Reihenfolge nach Betrag. Filtere und sortiere Beträge von Buchungen deshalb in deiner Anwendung.

## Prozentsätze

Prozentsätze sind Dezimalzahlen im String und bedeuten Prozent, nicht Anteile: `"19"` steht für 19 %, `"5.5"` für 5,5 %. Das gilt für den Steuersatz einer Position (`vatPercentage`) und den Skontosatz (`cashDiscount.percent`).

## IDs

Alle IDs sind UUIDs als String, zum Beispiel `"0b5c2f4e-8a1d-4c3e-9f6a-2d7b1e8c4a90"`.

* Eine ID im Pfad, die keine UUID ist, ergibt `400`.
* Eine ID, die zu einer anderen Firma gehört, ergibt `401` mit dem Code `Unauthorized` (siehe [Fehler](/errors)).
* In Filtern schreibst du UUIDs als String. Ein Wert, der keine UUID ist, ergibt `400`.

## Feste Werte

Felder mit einer festen Liste von Werten sind Strings, zum Beispiel:

| Feld                                | Werte                                                                                                                      |
| ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `kind` (Belege)                     | `invoice` (Ausgangsrechnung), `receipt` (Eingangsbeleg)                                                                    |
| `uploadDocument.ocrStatus` (Belege) | `pending`, `processing`, `success`, `failed`, `quota_paused`, siehe [Beleg-Upload](/document-upload#verarbeitung-abfragen) |
| `status` (Umsätze)                  | `booked` (gebucht), `pending` (vorgemerkt)                                                                                 |
| `type` (Kontakte)                   | `customer`, `supplier`, `partner`                                                                                          |
| `match.category`                    | `payment`, `invoice_cancellation`, `money_transfer`, siehe [Glossar](/glossary#zuordnung)                                  |

Die Werte je Feld stehen in der [Referenz](/reference). Plane in deiner Anwendung einen Standardfall für Werte ein, die du nicht kennst.

## Leere Werte

* Felder, die in der Referenz als „kann null sein“ markiert sind, kommen als `null`, wenn es keinen Wert gibt.
* Einige Felder fehlen ganz, statt `null` zu sein, zum Beispiel `duplicate` beim Upload oder `cashDiscount` ohne Skonto. Die Beschreibung des Felds nennt das.
* Mit `{ "kind": "eq", "attribute": "…", "value": null }` findest du Einträge ohne Wert.
