Preskočiť na obsah
Pre vývojárov

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ľúč>.

Karta API v nastaveniach panela Otta
API kľúč v Nastaveniach, časť Prepojenia.
Kľúč je tajný: kto ho má, číta vaše dáta a koná za vás. Patrí len na váš server, nikdy nie do kódu webu ani mobilnej aplikácie. Keď unikne, dajte Vygenerovať nový kľúč, starý ihneď prestane platiť.

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
curl https://ottoai.sk/api/v1/me \
  -H "Authorization: Bearer $OTTO_API_KEY"
Node.js
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();
PHP
$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

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

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ódVýznam
400Chybná požiadavka, errors povie čo presne.
401Neplatný alebo chýbajúci kľúč.
403Funkcia nie je vo vašom pláne (api_not_in_plan, webhooks_not_in_plan).
404Záznam neexistuje alebo nie je váš. Cudzie záznamy vracajú 404, nie 403.
409Akcia v tomto stave nejde, napríklad prevziať vyriešenú konverzáciu (conv_resolved).
429Priveľ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>/messagesOdpovie zákazníkovi ako kolega. Otto v konverzácii zmĺkne, zákazník mimo webu dostane odpoveď e-mailom.
POST /conversations/<id>/notesInterná poznámka, zákazník ju nevidí.
POST /conversations/<id>/takeoverPrevezme konverzáciu. Bez operatorId ostane doterajšie priradenie.
POST /conversations/<id>/releaseVráti konverzáciu Ottovi.
POST /conversations/<id>/resolve, /reopenVyrieš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>/dismissSkryje 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:

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:

GET /api/v1/stats?since=2026-10-01T00:00:00Z&interval=week
{
  "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 }
    ]
  }
}