# Filtern und Paginieren (https://developer.bimetrics.de/filtern)

Suchanfragen für Belege, Kontakte, Bankkonten, Umsätze und Buchungen.

Listen fragst du mit `POST` an eine Filterroute ab, zum Beispiel [`POST /api/document/filter`](https://developer.bimetrics.de/referenz/belege/filter-documents.md). Der Body ist JSON und enthält einen Filterausdruck, die Sortierung und die Seite.

Beispiel für `POST /api/document/filter`:

```json
{
  "kind": "and",
  "children": [
    {
      "kind": "range",
      "attribute": "invoiceDate",
      "lower": "2026-01-01",
      "upper": "2026-12-31"
    }
  ],
  "limit": 50,
  "offset": 0,
  "sort": [
    "invoiceDate"
  ],
  "direction": [
    "desc"
  ]
}
```

Welche Attribute es je Route gibt, steht [weiter unten](#attribute-je-route), jeweils mit einem Beispiel.

## Filterausdruck

Ein Ausdruck hat eine Art (`kind`). Ausdrücke mit `and`, `or` und `not` enthalten weitere Ausdrücke in `children` und lassen sich verschachteln.

| Art (`kind`) | Bedeutung |
| --- | --- |
| `and` | Alle Teilausdrücke in `children` treffen zu. Ein leeres `children` liefert alle Einträge. |
| `or` | Mindestens ein Teilausdruck in `children` trifft zu. |
| `eq` | `attribute` hat genau den Wert `value`. |
| `not` | Verneint den Teilausdruck in `children`. Verwende genau einen Teilausdruck. |
| `in` | `attribute` enthält den Text `value`. Groß- und Kleinschreibung spielen keine Rolle. |
| `range` | `attribute` liegt zwischen `lower` und `upper`, beide Grenzen inklusive. Eine Grenze genügt. |
| `oneof` | `attribute` hat einen der Werte im Array `value`. |

* Werte sind Strings, Zahlen oder Wahrheitswerte. Datumswerte schreibst du als String, `JJJJ-MM-TT` oder mit Uhrzeit nach RFC 3339.
* `{ "kind": "and", "children": [] }` liefert alle Einträge.
* `not` braucht mindestens einen Ausdruck in `children`. Mehrere verneint es gemeinsam, wie ein `not` um ein `and`.
* Eine unbekannte Art (`kind`) oder ein unbekanntes Attribut ergibt `400`.
* Ein Wert, der nicht zum Typ des Attributs passt, ergibt ebenfalls `400`, zum Beispiel Text für eine Ganzzahl oder eine UUID, eine Zahl mit Nachkommastellen für eine Ganzzahl oder ein Datum in anderer Schreibweise.

## Sortieren

`sort` enthält ein oder mehrere Attribute, `direction` die Richtung je Attribut: `asc` (Standard) oder `desc`. Beide Felder nehmen auch einen einzelnen String an.

Für `sort` sind nur die Attribute dokumentiert, die [weiter unten](#attribute-je-route) als sortierbar markiert sind. Ein Attribut, das dort als nicht sortierbar markiert ist, etwa `uploadDocument.ocrStatus` bei Belegen, ergibt in `sort` den Status `400`.

Ohne `sort` ist die Reihenfolge nicht festgelegt. Sortiere immer, wenn du mehrere Seiten abrufst.

## Seitenweise abrufen

| Feld     | Bedeutung                                                                                                           |
| -------- | ------------------------------------------------------------------------------------------------------------------- |
| `limit`  | Treffer je Seite, höchstens 1.000. Größere Werte werden auf den Höchstwert gesetzt. Ohne `limit` gilt der Höchstwert. |
| `offset` | Anzahl der Treffer, die übersprungen werden, höchstens 1.000.000. Größere oder negative Werte ergeben `400`.              |

Die Antwort nennt die Gesamtzahl und die gelieferte Seite:

```json
{
  "total": 1234,
  "limit": 100,
  "offset": 0,
  "items": []
}
```

Für die nächste Seite erhöhst du `offset` um `limit`, bis `offset` die Zahl `total` erreicht. Wenn sich die Daten zwischen zwei Abrufen ändern, können sich Seiten verschieben. Für einen vollständigen Abgleich grenzt du deshalb am besten über ein Datumsattribut ein, sortierst danach und rufst die Seiten zügig nacheinander ab.

## Attribute je Route

Dokumentiert sind nur die hier aufgeführten Attribute, in `sort` nur die als sortierbar markierten. Andere Attribute können funktionieren, gehören aber nicht zum dokumentierten Umfang (siehe [Stabilität und Änderungen](/stabilitaet)) und können sich ohne Ankündigung ändern.

### Buchungen suchen

`POST /api/accounting/booking/filter` (Referenz: https://developer.bimetrics.de/referenz/buchhaltung/filter-bookings)

| Attribut | Typ | Sortierbar | Beschreibung |
| --- | --- | --- | --- |
| `bookingDate` | date | ja | Buchungsdatum. |
| `account` | integer | ja | Konto. |
| `accountContra` | integer | ja | Gegenkonto. |
| `amount` | decimal | ja | Betrag. |
| `refDocumentId` | uuid | ja | ID des gebuchten Belegs. |
| `refBankTransactionId` | uuid | ja | ID des gebuchten Umsatzes. |
| `finalized` | date-time | ja | Zeitpunkt der Festschreibung; `null` bei nicht festgeschriebenen Buchungen. |
| `updatedAt` | date-time | ja | Zeitpunkt der letzten Änderung. |

```json
{
  "kind": "and",
  "children": [
    {
      "kind": "range",
      "attribute": "bookingDate",
      "lower": "2026-01-01",
      "upper": "2026-12-31"
    }
  ],
  "limit": 50,
  "offset": 0,
  "sort": [
    "bookingDate"
  ],
  "direction": [
    "desc"
  ]
}
```

### Bankkonten suchen

`POST /api/bankaccount/filter` (Referenz: https://developer.bimetrics.de/referenz/bankkonten/filter-bank-accounts)

| Attribut | Typ | Sortierbar | Beschreibung |
| --- | --- | --- | --- |
| `iban` | string | ja | IBAN des Kontos. |
| `bankName` | string | ja | Name der Bank. |
| `ownerName` | string | ja | Name des Kontoinhabers laut Bank. |
| `currency` | string | ja | Kontowährung (ISO 4217). |
| `disabled` | boolean | ja | Konto ist deaktiviert. |
| `updatedAt` | date-time | ja | Zeitpunkt der letzten Änderung. |

```json
{
  "kind": "and",
  "children": [
    {
      "kind": "range",
      "attribute": "updatedAt",
      "lower": "2026-01-01T00:00:00Z",
      "upper": "2026-12-31T23:59:59Z"
    }
  ],
  "limit": 50,
  "offset": 0,
  "sort": [
    "updatedAt"
  ],
  "direction": [
    "desc"
  ]
}
```

### Umsätze suchen

`POST /api/banktransaction/filter` (Referenz: https://developer.bimetrics.de/referenz/umsaetze/filter-bank-transactions)

| Attribut | Typ | Sortierbar | Beschreibung |
| --- | --- | --- | --- |
| `bankAccountId` | uuid | ja | ID des Bankkontos. |
| `bookingDate` | date | ja | Buchungstag. |
| `valueDate` | date | ja | Wertstellung. |
| `transactionAmount` | integer | ja | Betrag in Cent, negativ bei Ausgängen. |
| `otherPartyName` | string | ja | Name der Gegenseite. |
| `remittanceInformation` | string | ja | Verwendungszweck. |
| `status` | string | ja | `booked` (gebucht) oder `pending` (vorgemerkt). |
| `updatedAt` | date-time | ja | Zeitpunkt der letzten Änderung. |

```json
{
  "kind": "and",
  "children": [
    {
      "kind": "range",
      "attribute": "bookingDate",
      "lower": "2026-01-01",
      "upper": "2026-12-31"
    }
  ],
  "limit": 50,
  "offset": 0,
  "sort": [
    "bookingDate"
  ],
  "direction": [
    "desc"
  ]
}
```

### Kontakte suchen

`POST /api/contact/filter` (Referenz: https://developer.bimetrics.de/referenz/kontakte/filter-contacts)

| Attribut | Typ | Sortierbar | Beschreibung |
| --- | --- | --- | --- |
| `companyName` | string | ja | Name des Kontakts. |
| `customerNumber` | integer | ja | Kunden- bzw. Lieferantennummer. |
| `type` | string | ja | Art: `customer` (Kunde), `supplier` (Lieferant) oder `partner`. |
| `customerKind` | string | ja | Steuerlich: `business` (Unternehmen) oder `private` (Privatperson); leer, wenn unbekannt. |
| `contactInfo.email` | string | ja | E-Mail-Adresse. |
| `paymentInfo.iban` | string | ja | IBAN. |
| `paymentInfo.vatId` | string | ja | USt-IdNr. |
| `updatedAt` | date-time | ja | Zeitpunkt der letzten Änderung. |

```json
{
  "kind": "and",
  "children": [
    {
      "kind": "range",
      "attribute": "updatedAt",
      "lower": "2026-01-01T00:00:00Z",
      "upper": "2026-12-31T23:59:59Z"
    }
  ],
  "limit": 50,
  "offset": 0,
  "sort": [
    "updatedAt"
  ],
  "direction": [
    "desc"
  ]
}
```

### Belege suchen

`POST /api/document/filter` (Referenz: https://developer.bimetrics.de/referenz/belege/filter-documents)

| Attribut | Typ | Sortierbar | Beschreibung |
| --- | --- | --- | --- |
| `kind` | string | ja | Belegart: `invoice` (Ausgangsrechnung) oder `receipt` (Eingangsbeleg). |
| `invoiceDate` | date | ja | Rechnungsdatum. |
| `invoiceNumber` | string | ja | Rechnungsnummer. |
| `issuer.name` | string | ja | Name des Ausstellers. |
| `recipient.name` | string | ja | Name des Empfängers. |
| `uploadDocument.ocrStatus` | string | nein | Stand der Erkennung: `pending`, `processing`, `success`, `failed` oder `quota_paused`. |
| `createdAt` | date-time | ja | Zeitpunkt der Anlage in bimetrics. |
| `updatedAt` | date-time | ja | Zeitpunkt der letzten Änderung. Für Abgleiche per Polling: `range` mit `lower` = Zeitpunkt des letzten Abrufs. |

```json
{
  "kind": "and",
  "children": [
    {
      "kind": "range",
      "attribute": "invoiceDate",
      "lower": "2026-01-01",
      "upper": "2026-12-31"
    }
  ],
  "limit": 50,
  "offset": 0,
  "sort": [
    "invoiceDate"
  ],
  "direction": [
    "desc"
  ]
}
```
