API
Cez API čítate konverzácie, kontakty, reklamácie a štatistiky, zapisujete katalóg a znalosti a robíte to, čo tlačidlá v paneli.
API kľúč
V paneli otvorte Nastavenia, časť Prepojenia, riadok API a kliknite na Vygenerovať nový kľúč. Kľúč posielajte v každej požiadavke v hlavičke Authorization: Bearer <kľúč>.

API a webhooky sú súčasťou plánu Na mieru. Zápis katalógu cez API funguje na každom pláne.
Prvá požiadavka
curl https://ottoai.sk/api/v1/me \
-H "Authorization: Bearer $OTTO_API_KEY"const r = await fetch("https://ottoai.sk/api/v1/conversations?status=human&limit=20", {
headers: { Authorization: "Bearer " + process.env.OTTO_API_KEY },
});
if (!r.ok) throw new Error((await r.json()).errcode);
const { conversations, nextBefore } = await r.json();$ch = curl_init("https://ottoai.sk/api/v1/leads?since=2026-10-01T00:00:00Z");
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ["Authorization: Bearer " . getenv("OTTO_API_KEY")],
CURLOPT_RETURNTRANSFER => true,
]);
$kontakty = json_decode(curl_exec($ch), true)["leads"];Formát
- Všetky odpovede sú JSON v UTF-8.
- Časy sú ISO 8601 v UTC, napríklad
2026-10-10T08:00:00.000Z. - Id konverzácií a kontaktov sú UUID, id reklamácií a neistých otázok sú čísla v reťazci.
- Celá špecifikácia je v OpenAPI 3.1, načítate ju do Postmanu, Insomnie aj do generátora klienta. Prehľad adries je v časti Referencia API.
Stránkovanie
Zoznamy vracajú nextBefore. Pošlite ho späť ako before=, kým nie je null. Je to nepriehľadný reťazec, neskladajte ho sami. Počet riadkov na strane vám koniec nepovie.
let pred = null;
do {
const r = await fetch("https://ottoai.sk/api/v1/leads?limit=100" + (pred ? "&before=" + pred : ""), { headers });
const d = await r.json();
for (const kontakt of d.leads) spracuj(kontakt);
pred = d.nextBefore;
} while (pred);Filtre
sinceauntilobmedzia čas vzniku (od, do bez neho),updatedSincečas poslednej zmeny. Berú ISO 8601, zlý čas vráti 400.- Konverzácie:
status(bot,human,resolved),outcomealang. - Reklamácie:
status(new,approved,rejected,resolved) akind(claim,withdrawal). limitje pri konverzáciách, kontaktoch, reklamáciách a otázkach najviac 100 (predvolene 50), pri produktoch a znalostiach 200 (predvolene 100).
Chyby
Každá chyba má { error, errcode, requestId }. errcode je stabilný a po anglicky, podľa neho sa rozhodujte v kóde. error je veta pre človeka. Pri zlom parametri pribudne errors s presnou cestou.
{
"error": "Neplatný parameter.",
"errcode": "invalid_param",
"errors": [{ "path": "status", "message": "Použite bot, human alebo resolved." }],
"requestId": "1f0c6a7e-3b9a-4f0e-9c1d-2a7b8e5d4c3f"
}| Kód | Význam |
|---|---|
400 | Chybná požiadavka, errors povie čo presne. |
401 | Neplatný alebo chýbajúci kľúč. |
403 | Funkcia nie je vo vašom pláne (api_not_in_plan, webhooks_not_in_plan). |
404 | Záznam neexistuje alebo nie je váš. Cudzie záznamy vracajú 404, nie 403. |
409 | Akcia v tomto stave nejde, napríklad prevziať vyriešenú konverzáciu (conv_resolved). |
429 | Priveľa požiadaviek, hlavička Retry-After povie, o koľko sekúnd skúsiť znova. |
Každá odpoveď má hlavičku x-request-id. Keď pošlete vlastnú, vrátime ju a uvidíme ju aj my v záznamoch.
Limity
Limit je 120 požiadaviek za minútu na firmu. Hlavičky RateLimit-Limit, RateLimit-Remaining a RateLimit-Reset v každej odpovedi povedia, koľko ostáva a za koľko sekúnd sa limit uvoľní. Celý katalóg cez snapshot pošlete najviac 12× za hodinu.
Akcie
To, čo robia tlačidlá v paneli, vie aj API. Akcie posielajú tie isté udalosti webhookov ako panel.
| Adresa | Čo robí |
|---|---|
POST /conversations/<id>/messages | Odpovie zákazníkovi ako kolega. Otto v konverzácii zmĺkne, zákazník mimo webu dostane odpoveď e-mailom. |
POST /conversations/<id>/notes | Interná poznámka, zákazník ju nevidí. |
POST /conversations/<id>/takeover | Prevezme konverzáciu. Bez operatorId ostane doterajšie priradenie. |
POST /conversations/<id>/release | Vráti konverzáciu Ottovi. |
POST /conversations/<id>/resolve, /reopen | Vyrieši konverzáciu, prípadne ju otvorí znova. |
PATCH /leads/<id> | Označí kontakt ako vybavený: { "handled": true }. |
PATCH /returns/<id> | Rozhodne o reklamácii, notify: true pošle zákazníkovi e-mail. |
POST /unanswered/<id>/dismiss | Skryje neistú otázku zo zoznamu. |
curl -X POST https://ottoai.sk/api/v1/conversations/$ID/messages \
-H "Authorization: Bearer $OTTO_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "text": "Dobrý deň, objednávka odišla dnes ráno.", "operatorId": "$OPERATOR" }'Id kolegov nájdete v GET /api/v1/operators. Bez operatorId sa ako autor v paneli ukáže API.
Výsledok konverzácie a štatistiky
Každá konverzácia má outcome:
resolved_by_otto: Otto ju vybavil sám.unanswered: Otto sám, ale s neistou odpoveďou.handed_off: odpísal kolega.missed: zákazník chcel človeka a nikto mu neodpísal.
GET /api/v1/stats vráti počty za obdobie aj rad po dňoch, týždňoch alebo mesiacoch v zvolenej časovej zóne:
{
"conversationsTotal": 1824,
"conversationsMonth": 212,
"products": 236,
"range": {
"since": "2026-10-01T00:00:00.000Z",
"until": "2026-10-10T16:00:00.000Z",
"interval": "week",
"timezone": "Europe/Bratislava",
"totals": { "conversations": 64, "resolvedByOtto": 49, "unanswered": 6, "handedOff": 8, "missed": 1,
"ratingUp": 11, "ratingDown": 1, "leads": 7, "returns": 2 },
"series": [
{ "date": "2026-09-28", "conversations": 31, "resolvedByOtto": 24, "unanswered": 3, "handedOff": 4, "missed": 0, "ratingUp": 6, "ratingDown": 0 },
{ "date": "2026-10-05", "conversations": 33, "resolvedByOtto": 25, "unanswered": 3, "handedOff": 4, "missed": 1, "ratingUp": 5, "ratingDown": 1 }
]
}
}
