# Suche

`GET /public/v1/search` (Berechtigung `search:read`) findet Belege in den Dateien Ihres Unternehmens nach Wörtern, auch in Komposita („Stuhl“ findet „Bürostuhl“), und nach Bedeutung („Bürostühle“ findet „office chairs“). Gelöschte Dateien bleiben außen vor. Die Suche findet Belege; sie beantwortet keine Fragen und schreibt nichts.

## Parameter

| Parameter | Bedeutung |
| --- | --- |
| `q` | Pflicht, 1 bis 200 Zeichen. |
| `kind` | Eine öffentliche Art (`invoice`, `credit_note`, `delivery_note`, `contract`, …); für mehrere wiederholen. |
| `since`, `until` | Belegdatum, ISO 8601, einschließlich. |
| `party` | Der Name einer beliebigen Partei, wie gelesen; Schreibweise, Umlaute und Rechtsform spielen keine Rolle („Müller Sanitär GmbH“ findet „MUELLER SANITAER G.m.b.H.“). |
| `vat_id` | Die USt-IdNr. einer Partei, wie gelesen, ohne Rücksicht auf Leerzeichen und Schreibweise. |
| `match` | `hybrid` (Standard): Wörter und Bedeutung; `keywords`: nur Wörter; `meaning`: nur Bedeutung; `exact`: nur Belege, die `q` wörtlich enthalten (Schreibweise, Akzente und Leerzeichen außen vor), nie einer, der nur dasselbe meint. |
| `due_since`, `due_until` | Fälligkeit einer Rechnung, ISO 8601, einschließlich. |
| `gross_min`, `gross_max` | Der Bruttobetrag in der Währung Ihres Unternehmens (zum EZB-Kurs umgerechnet), einschließlich. |
| `direction` | `incoming` (von Lieferanten) oder `outgoing` (an Kunden). |
| `status` | Einer Rechnung: `open` (unbezahlt) oder `paid`. |
| `category` | Ein ECLASS-Code beliebiger Ebene, acht Ziffern (`24000000`): Belege mit einer Position darin oder darunter. |
| `limit`, `offset` | 1 bis 50, Standard 20; `offset` bis 250. |

## Ergebnisse

Eins je Beleg, das beste zuerst; eine Datei ohne Beleg erscheint als eigener Treffer.

- `document_id`, `file_id`, `file_name`, `kind`, `number`, `seller`, `buyer`, `issue_date`, `gross`, `currency`, `pages`
- `passages[]`, bis zu 5: `page`, `text` (etwa 300 Zeichen), `highlights` (`[start, end)`-Bereiche der Treffer in `text`, zum Markieren), `found_by` (`words`, `meaning`, `both`)
- `facts[]`: Fakten der Karte, die die Wörter enthalten
- `file_url`, `document_url`: Datei und Beleg in dieser API

`total` zählt die Treffer (Ocost ordnet die besten 300), `truncated` sagt, ob es mehr gab. `meaning: "unavailable"`: Die Suche nach Bedeutung wird aufgebaut oder ist nicht erreichbar; die Wörter antworten trotzdem.

## Beispiele

```bash
curl -sS -G https://api.ocost.io/public/v1/search \
  -H "Authorization: Bearer $OCOST_KEY" \
  --data-urlencode "q=Wartungsvertrag Aufzug" \
  --data-urlencode "kind=contract" \
  --data-urlencode "since=2025-01-01"
```

```python
found = session.get(
    f"{API}/search",
    params={"q": "Bürostuhl", "party": "Musterbüro Lieferant", "limit": 10},
    timeout=15,
).json()
for r in found["results"]:
    first = r["passages"][0] if r["passages"] else None
    print(r["number"], r["seller"], r["issue_date"], first and first["page"])
```

```javascript
const params = new URLSearchParams({ q: 'Skonto', kind: 'invoice' });
const found = await fetch(`${API}/search?${params}`, { headers: auth }).then((r) => r.json());
for (const r of found.results) console.log(r.number, r.file_url);
```
