# Schnellstart

Von null zur gelesenen Rechnung. Sie brauchen ein Ocost-Konto, in dem Sie Inhaber oder Buchhaltung sind; die Beispiele nutzen `$OCOST_KEY` für Ihren Schlüssel.

## 1. Registrieren

Registrieren Sie sich unter `https://app.ocost.io/auth/sign-up` oder melden Sie sich an. Geschickte Dateien stehen wie jeder Upload unter **Dateien**, und Ocost legt sie ab, bucht und gleicht sie ab.

## 2. Einen Schlüssel erstellen

1. Öffnen Sie **[Einstellungen › API](/settings/api)**.
2. Wählen Sie **Schlüssel erstellen**, benennen Sie ihn nach seinem Nutzer („Odoo Produktion“), lassen Sie alle drei Berechtigungen angehakt und wählen Sie **Schlüssel erstellen**.
3. Wählen Sie **Schlüssel kopieren**. Er beginnt mit `ocost_sk_` und erscheint nur einmal.

```bash
export OCOST_KEY="ocost_sk_…"
```

## 3. Ein PDF schicken

`POST /public/v1/files` nimmt die Datei als `multipart/form-data` im Feld `file`; `external_ref` ist Ihre eigene Kennung und kommt zurück.

```bash
curl -sS https://api.ocost.io/public/v1/files \
  -H "Authorization: Bearer $OCOST_KEY" \
  -F "file=@rechnung.pdf" \
  -F "external_ref=account.move,42"
```

```python
import os

import requests

API = "https://api.ocost.io/public/v1"
auth = {"Authorization": f"Bearer {os.environ['OCOST_KEY']}"}

with open("rechnung.pdf", "rb") as f:
    sent = requests.post(
        f"{API}/files",
        headers=auth,
        files={"file": ("rechnung.pdf", f, "application/pdf")},
        data={"external_ref": "account.move,42"},
        timeout=30,
    )
sent.raise_for_status()
file = sent.json()
```

```javascript
import { readFile } from 'node:fs/promises';

const API = 'https://api.ocost.io/public/v1';
const auth = { Authorization: `Bearer ${process.env.OCOST_KEY}` };

const form = new FormData();
form.append(
  'file',
  new Blob([await readFile('rechnung.pdf')], { type: 'application/pdf' }),
  'rechnung.pdf',
);
form.append('external_ref', 'account.move,42');
const sent = await fetch(`${API}/files`, { method: 'POST', headers: auth, body: form });
let file = await sent.json();
```

Die Antwort ist `202 Accepted`:

```json
{
  "id": "01a1b08c-6e3a-7562-8f4a-7924722667b1",
  "name": "rechnung.pdf",
  "status": "received",
  "reason": null,
  "external_ref": "account.move,42",
  "documents": [],
  "sha256": "0edd5593…"
}
```

Dieselben Bytes noch einmal ergeben `200 OK` mit derselben Datei, einmal gezählt. `X-Ocost-Documents-Left` sagt, was Ihr Tarif in diesem Monat noch hat.

## 4. Abfragen, bis sie gelesen ist

`GET /public/v1/files/{file_id}` liefert die Datei, wie sie gerade ist. Fragen Sie alle paar Sekunden, solange `status` `received` oder `reading` ist (die meisten PDFs brauchen unter einer Minute), dann seltener.

```bash
curl -sS https://api.ocost.io/public/v1/files/$FILE_ID \
  -H "Authorization: Bearer $OCOST_KEY"
```

```python
import time

for wait in [2, 2, 3, 5, 5, 10, 10, 15, 30, 30]:
    file = requests.get(f"{API}/files/{file['id']}", headers=auth, timeout=15).json()
    if file["status"] not in ("received", "reading"):
        break
    time.sleep(wait)
```

```javascript
while (file.status === 'received' || file.status === 'reading') {
  await new Promise((done) => setTimeout(done, 3000));
  file = await (await fetch(`${API}/files/${file.id}`, { headers: auth })).json();
}
```

Danach listet `documents`, was sie enthält; `not_read` und `failed` tragen einen `reason` ([Dateien und Status](https://app.ocost.io/developers/de/files.md)).

## 5. Den Beleg lesen

`GET /public/v1/files/{file_id}/document` liefert ihren ersten Beleg als `ocost.document.v1`, jeden Wert mit Fundstelle und wie sicher Ocost ist ([Das Belegschema](https://app.ocost.io/developers/de/document.md)). `GET /public/v1/documents/{document_id}` liefert jeden weiteren.

```bash
curl -sS https://api.ocost.io/public/v1/files/$FILE_ID/document \
  -H "Authorization: Bearer $OCOST_KEY"
```

```python
document = requests.get(
    f"{API}/files/{file['id']}/document", headers=auth, timeout=15
).json()
print(document["number"], document["totals"]["gross"], document["currency"])
```

```javascript
const document = await (
  await fetch(`${API}/files/${file.id}/document`, { headers: auth })
).json();
console.log(document.number, document.totals.gross, document.currency);
```

## 6. Suchen

`GET /public/v1/search` findet Belege nach Wörtern und nach Bedeutung.

```bash
curl -sS -G https://api.ocost.io/public/v1/search \
  -H "Authorization: Bearer $OCOST_KEY" \
  --data-urlencode "q=Bürostühle" \
  --data-urlencode "kind=invoice"
```

```python
found = requests.get(
    f"{API}/search", headers=auth, params={"q": "Bürostühle", "kind": "invoice"}, timeout=15
).json()
for r in found["results"]:
    print(r["number"], r["seller"], r["issue_date"])
```

```javascript
const params = new URLSearchParams({ q: 'Bürostühle', kind: 'invoice' });
const found = await (await fetch(`${API}/search?${params}`, { headers: auth })).json();
for (const r of found.results) console.log(r.number, r.seller, r.issue_date);
```

## Weiter

- Status und Gründe: [Dateien und Status](https://app.ocost.io/developers/de/files.md)
- Jedes Feld: [Das Belegschema](https://app.ocost.io/developers/de/document.md)
- Eingangsrechnungen in Odoo: [Odoo anbinden](https://app.ocost.io/developers/de/odoo.md)
- Jede Route: [API-Referenz](https://app.ocost.io/developers/openapi.json)
