Search
Find documents in your business's files by their words and by their meaning. Words match inside compounds too, so "Stuhl" finds "Bürostuhl". Meaning crosses languages, so "office chairs" finds "Bürostühle". Search finds documents. It answers no questions and changes nothing.
Search
Call GET /public/v1/search with your words in q. The key needs the scope search:read.
curl -sS -G https://api.ocost.io/public/v1/search \
-H "Authorization: Bearer $OCOST_KEY" \
--data-urlencode "q=Wartungsvertrag Aufzug" \
--data-urlencode "kind=contract"found = requests.get(
f"{API}/search",
headers=auth,
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"])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);The answer lists one result per document, best first:
{
"results": [
{
"document_id": "01a1b08c-7aa1-7b52-9d4e-2f1f1c0c4f11",
"file_id": "01a1b08c-6e3a-7562-8f4a-7924722667b1",
"file_name": "invoice.pdf",
"kind": "invoice",
"number": "RE-2026-1187",
"seller": "Musterbüro Lieferant GmbH",
"buyer": "Beispiel Handel GmbH",
"issue_date": "2026-11-03",
"gross": "1270.92",
"currency": "EUR",
"pages": [1],
"passages": [
{ "page": 1, "text": "4 Bürostuhl ErgoPlus schwarz à 189,00 €", "highlights": [[2, 11]], "found_by": "both" }
],
"facts": [],
"file_url": "/public/v1/files/01a1b08c-6e3a-7562-8f4a-7924722667b1",
"document_url": "/public/v1/documents/01a1b08c-7aa1-7b52-9d4e-2f1f1c0c4f11"
}
],
"total": 1,
"truncated": false,
"meaning": "available"
}Narrow it down
Every parameter but q is optional. Repeat kind for several kinds.
| Parameter | Meaning |
|---|---|
q | Required, 1 to 200 characters. |
match | hybrid uses words and meaning, and is the default. keywords uses words only, meaning meaning only. exact finds only documents holding q as written, ignoring case, accents and spacing. |
kind | A kind such as invoice, credit_note, delivery_note or contract. |
since, until | The issue date, ISO 8601, inclusive. |
due_since, due_until | An invoice's due date, ISO 8601, inclusive. |
party | Any party's name as read. Case, umlauts and legal forms don't matter, so "Müller Sanitär GmbH" finds "MUELLER SANITAER G.m.b.H.". |
vat_id | A party's VAT ID as read, ignoring spaces and case. |
gross_min, gross_max | The gross in your business's currency, converted at the ECB's rate, inclusive. |
direction | incoming from suppliers, or outgoing to customers. |
status | An invoice's: open (unpaid) or paid. |
category | An ECLASS code of any level, eight digits such as 24000000. It finds documents with a line in that class or under it. |
limit, offset | limit 1 to 50, 20 by default. offset up to 250. |
Read the results
Each result names its document and file, with the fields shown above. A file without a document comes as itself, with document_id set to null.
passagesholds up to five passages of about 300 characters each, best first.highlightsmarks the matched words in a passage'stextas[start, end)ranges.found_bysays whether a passage matched bywords, bymeaningor byboth.factslists the facts on a document's card that hold your words.file_urlanddocument_urllead to the file and the document in this API.
total counts the matches. Ocost ranks the best 300, and truncated says there were more. Deleted files never show up.
When meaning is unavailable, search by meaning is building or unreachable. The words still answer.