Průvodce

Konvence

Formát požadavků, společná pole, dotazy na seznamy a filtry, chyby a limity požadavků společné všem endpointům.

Zobrazit jako Markdown

Tato stránka popisuje pravidla, kterými se řídí každý endpoint integračního API. Stránky endpointů zmiňují jen to, v čem se od nich endpoint liší.

Požadavky

API je RPC přes HTTP POST, ne REST. Endpointy jsou požadavky POST na cestu, která pojmenovává akci, například:

Cesta Akce
/api/v3/conversation/find výpis konverzací
/api/v3/conversation/get čtení jedné konverzace
/api/v3/conversation/delete smazání jedné konverzace

Nejsou zde žádné endpointy PUT, PATCH ani DELETE a v cestě nejsou id zdrojů; id záznamu je parametr. Každý endpoint přijímá POST. Dva endpointy jen pro čtení bez parametrů, zůstatek kreditu a verze, odpovídají kvůli kompatibilitě se staršími klienty i na GET; v novém kódu používejte POST.

Základní URL je:

text
https://ayeto.ai/api/v3

Hlavičky

Hlavička Povinná Popis
uni-api-key ano Váš API klíč, viz Autentizace.
Content-Type ano, s tělem application/json.
language ne Jazyk požadavku: EN, CZ nebo FR (na velikosti písmen nezáleží). Výchozí EN.
theme ne light nebo dark. Výchozí light. V chatu se předává modelu jako nápověda, kde se odpověď zobrazí.

Hlavička language sděluje modelu v chatu, jakým jazykem uživatel píše, a určuje jazyk přeložených textů, které některé endpointy vracejí (například názvy nástrojů v modelech a nástrojích). Chybové zprávy jsou vždy anglicky.

Hlavička platí jen pro daný požadavek. Nikdy nemění jazyk, který si uživatel zvolil v aplikaci AYETO a který AYETO používá pro jeho e-maily a naplánovanou práci.

Parametry

Parametry se posílají v těle JSON, pokud stránka endpointu neuvádí jinak. Endpointy, které pracují s jedním záznamem podle id (.../get, .../delete), přijímají id v těle jako {"id": "<uuid>"}:

bash
curl -X POST "https://ayeto.ai/api/v3/conversation/get" \
  -H "uni-api-key: $AYETO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"id": "0b8f3c2e-5d41-4a7e-9c1f-6e2d8a4b7c90"}'

Id přijímají i jako parametr dotazu entity_id, jak to vyžadovaly dřívější verze API; tělo pak lze vynechat nebo poslat {}. Tělo, které pošlete, musí být JSON s Content-Type: application/json, stejně jako u každého endpointu:

bash
curl -X POST "https://ayeto.ai/api/v3/conversation/get?entity_id=0b8f3c2e-5d41-4a7e-9c1f-6e2d8a4b7c90" \
  -H "uni-api-key: $AYETO_API_KEY"

Požadavek bez obojího, s oběma nastavenými na různá id nebo s id, které není UUID, se odmítne s 422.

Endpoint, jehož parametry jsou objekt JSON, potřebuje tělo, i když chcete všechny výchozí hodnoty: pošlete {}. Požadavek bez těla se odmítne s 422.

Hodnoty

  • Id jsou UUID zapsaná jako řetězce: "0b8f3c2e-5d41-4a7e-9c1f-6e2d8a4b7c90". Odpovědi vždy používají tvar s malými písmeny a pomlčkami.
  • Časová razítka jsou celá čísla: milisekundy od epochy Unixu (UTC), například 1790846045000 pro 2026-10-01 09:14:05 UTC. 0 znamená „nikdy“.

Odpovědi

Úspěšný požadavek vrací 200 s tělem JSON: objekt, pole objektů (endpointy find), číslo (endpointy count) nebo id dotčeného záznamu jako řetězec JSON (endpointy delete). Streamovací endpointy místo toho vracejí stream. Chyby jsou popsány v části Chyby.

Společná pole

Každý uložený záznam, který API vrací (konverzace, asistent, workflow, běh workflow, ...), nese své id a tři objekty metadat:

Pole Typ Popis
id UUID Id záznamu.
created objekt Kdy a kdo záznam vytvořil.
updated objekt Kdy a kdo ho naposledy změnil. timestamp je 0, pokud se nikdy nezměnil.
accessed objekt Kdy a kdo do něj naposledy zapsal nebo ho otevřel. Čtení některých záznamů (například konverzace přes conversation/get) ho aktualizuje, nejvýše zhruba jednou za minutu.

Každý objekt metadat má stejný tvar:

Pole Typ Popis
timestamp časové razítko Čas události, 0, pokud nenastala.
user_id UUID nebo null Uživatel, který ji způsobil; null, když ji provedl systém.
json
{
  "id": "0b8f3c2e-5d41-4a7e-9c1f-6e2d8a4b7c90",
  "created": { "timestamp": 1790846045000, "user_id": "5a1d7e3c-9b2f-4c8e-a6d0-3f7b1e9c2a54" },
  "updated": { "timestamp": 1790846052000, "user_id": "5a1d7e3c-9b2f-4c8e-a6d0-3f7b1e9c2a54" },
  "accessed": { "timestamp": 1790846052000, "user_id": "5a1d7e3c-9b2f-4c8e-a6d0-3f7b1e9c2a54" }
}

Většina endpointů vrací veřejný pohled na záznam: tato pole plus pole uvedená na stránce endpointu. Endpointy, které vracejí celý záznam (například workflow a běhy workflow), obsahují navíc tato obecná pole:

Pole Typ Popis
owner UUID nebo null Obecný odkaz, obvykle null.
parent UUID nebo null Obecný odkaz, obvykle null.
source UUID nebo null Záznam, ke kterému tento patří, pokud nějaký má.
seq celé číslo Pořadové číslo záznamu v rámci jeho typu.
enabled boolean Obvykle true.
note řetězec Volná textová poznámka, obvykle prázdná.
owner_group UUID nebo null Skupina, která záznam vlastní (například administrátoři organizace); null, když ho vlastní uživatel, který ho vytvořil.
permissions objekt Příznaky přístupu group, all a other, každý { "read": boolean, "write": boolean }.
joined_collections null V tomto API vždy null.

created, updated, accessed, permissions a owner_group spravuje server. Hodnoty, které pro ně pošlete v požadavcích na vytvoření nebo úpravu, se ignorují.

Dotazy na seznamy

Endpointy, které záznamy vypisují (.../find) a počítají (.../count), přijímají jako tělo stejný objekt dotazu. Průběžným příkladem je POST /api/v3/conversation/find.

Pole Typ Povinné Popis
filters pole ne Podmínky, které musí záznamy splnit, viz Filtry. Musí platit všechny podmínky v poli.
sort_key řetězec ne Pole, podle kterého se řadí, například "name" nebo "updated.timestamp" (tečková notace pro vnořená pole). Musí to být pole záznamu; neznámé pole se odmítne s 422.
sort_order celé číslo ne 0 = vzestupně (výchozí, když je nastaveno sort_key), 1 = sestupně. Bez sort_key se ignoruje.
limit_from celé číslo ne Index prvního vraceného záznamu, počítáno od 0. Stránkování se použije, jen když je toto pole nastaveno.
limit_to celé číslo ne Index za posledním vraceným záznamem. Je to absolutní pozice, ne velikost stránky: limit_from: 20, limit_to: 40 vrátí záznamy 20 až 39. null nebo 0 znamená „až do konce“.
fetch_dict boolean ne Nemá vliv na vrácená data; můžete ho vynechat.
join pole ne Integrační API ho nepodporuje; ignoruje se.

Bez sort_key se záznamy vracejí od nejnovějších (podle created.timestamp, sestupně). Bez limit_from se všechny odpovídající záznamy vrátí v jedné odpovědi.

Stránkování

Pro čtení stránky n (počítáno od 0) o velikosti s pošlete limit_from: n * s a limit_to: (n + 1) * s. Pravidla:

  • limit_from musí být 0 nebo víc a limit_to musí být větší než limit_from. Záporné limit_from nebo limit_to nižší než limit_from se odmítne s 422. Když se obě hodnoty rovnají, žádná horní mez se nepoužije a vrátí se všechny záznamy od limit_from dál.
  • limit_to bez limit_from se ignoruje: vrátí se celý výsledek.
  • Na straně serveru neexistuje maximální velikost stránky. Udržujte stránky rozumně malé (nanejvýš několik set záznamů); velké záznamy, jako konverzace s dlouhou historií, dávají velké odpovědi.
bash
curl -X POST "https://ayeto.ai/api/v3/conversation/find" \
  -H "uni-api-key: $AYETO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filters": [["updated.timestamp", ">=", 1790812800000]],
    "sort_key": "updated.timestamp",
    "sort_order": 1,
    "limit_from": 0,
    "limit_to": 20
  }'

Odpovědí je pole záznamů; prázdné pole, když nic neodpovídá:

json
[
  {
    "id": "0b8f3c2e-5d41-4a7e-9c1f-6e2d8a4b7c90",
    "name": "Quarterly report outline",
    "model": "gpt-5-mini",
    "summary": "",
    "organization_id": null,
    "assistant_id": "c4e2a9b1-7f3d-4e6a-8b5c-1d9f0a2e3b47",
    "task_id": null,
    "task_execution_id": null,
    "workflow_id": null,
    "workflow_run_id": null,
    "messages": [
      {
        "id": "7d3a1f9e-2b4c-4e8a-9f6d-0c5b8e1a2d36",
        "timestamp": 1790846045000,
        "role": "user",
        "content": "Draft an outline for the Q3 report.",
        "reasoning_content": null,
        "model": null,
        "attachments": [],
        "tool_runs": {}
      },
      {
        "id": "e1b9c7a3-5d2f-4a6e-8c0b-9f4d3e2a1b58",
        "timestamp": 1790846052000,
        "role": "assistant",
        "content": "1. Summary\n2. Revenue\n3. Costs\n4. Outlook",
        "reasoning_content": null,
        "model": "gpt-5-mini",
        "attachments": [],
        "tool_runs": {}
      }
    ],
    "public_sharing": false,
    "created": { "timestamp": 1790846045000, "user_id": "5a1d7e3c-9b2f-4c8e-a6d0-3f7b1e9c2a54" },
    "updated": { "timestamp": 1790846052000, "user_id": "5a1d7e3c-9b2f-4c8e-a6d0-3f7b1e9c2a54" },
    "accessed": { "timestamp": 1790846052000, "user_id": "5a1d7e3c-9b2f-4c8e-a6d0-3f7b1e9c2a54" }
  }
]

Chcete-li přečíst všechno, žádejte o stránky, dokud nepřijde stránka kratší, než je velikost stránky. Řaďte vzestupně podle created.timestamp, aby se záznamy vytvořené během stránkování přidaly na konec, místo aby posunuly stránky, které jste ještě nepřečetli:

python
import os
import requests

BASE = "https://ayeto.ai/api/v3"
HEADERS = {"uni-api-key": os.environ["AYETO_API_KEY"]}
PAGE = 50

start = 0
while True:
    r = requests.post(f"{BASE}/conversation/find", headers=HEADERS, json={
        "sort_key": "created.timestamp",
        "sort_order": 0,
        "limit_from": start,
        "limit_to": start + PAGE,
    })
    r.raise_for_status()
    page = r.json()
    for conversation in page:
        print(conversation["id"], conversation["name"])
    if len(page) < PAGE:
        break
    start += PAGE

Počítání

Endpointy .../count přijímají stejné tělo a vracejí počet záznamů, které odpovídají filters, jako prosté celé číslo. Ignorují limit_from, limit_to a pole pro řazení, takže můžete poslat stejné tělo jako pro zobrazovanou stránku a dostat celkový počet pro stránkovač.

bash
curl -X POST "https://ayeto.ai/api/v3/workflow/count" \
  -H "uni-api-key: $AYETO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"filters": [["name", "regex", "invoice"]], "limit_from": 0, "limit_to": 20}'
json
42

Ne každý seznam má endpoint pro počítání; stránky endpointů uvádějí ty, které existují.

Filtry

filters je pole. Každý prvek je podmínka nebo skupina podmínek a záznam se vrátí, jen když odpovídá všem prvkům.

Podmínky

Podmínka je pole [field, operator, value] s volitelným čtvrtým prvkem (viz Převod UUID):

json
["model", "==", "gpt-5-mini"]

field je název pole záznamu. Pro vnořená pole použijte tečkovou notaci (created.timestamp, created.user_id). Cesta do seznamu objektů odpovídá, když odpovídá kterýkoli prvek seznamu (messages.role). id je id záznamu.

Operátor Odpovídá, když pole... Hodnota
== se rovná hodnotě jakákoli povolená hodnota
!= se nerovná hodnotě jakákoli povolená hodnota
< je menší než hodnota číslo nebo řetězec
> je větší než hodnota číslo nebo řetězec
<= je menší nebo rovno hodnotě číslo nebo řetězec
>= je větší nebo rovno hodnotě číslo nebo řetězec
regex obsahuje shodu s regulárním výrazem bez ohledu na velikost písmen řetězec
in se rovná kterékoli z hodnot neprázdné pole, nejvýše 100 hodnot

Poznámky:

  • regex nikdy nerozlišuje velikost písmen a není ukotvený: "invoice" odpovídá "Invoices 2026". K ukotvení použijte ve vzoru ^ a $ a znaky regulárních výrazů (., *, +, ?, (, ), [, ], \) escapujte, pokud se mají shodovat doslova.
  • Řetězce se porovnávají abecedně (podle kódu znaku), čísla číselně. Časová razítka porovnávejte jako čísla.
  • ["field", "==", null] odpovídá záznamům, kde je pole null nebo chybí.

Skupiny

Skupina je objekt s právě jedním klíčem, AND nebo OR, jehož hodnotou je neprázdné pole podmínek nebo dalších skupin. Skupiny lze vnořovat.

json
{"OR": [["model", "==", "gpt-5-mini"], ["model", "==", "gpt-5"]]}
json
{"AND": [
  ["updated.timestamp", ">=", 1788220800000],
  {"OR": [["name", "regex", "report"], ["summary", "regex", "report"]]}
]}

Klíč musí být napsán velkými písmeny. Objekt s jakýmkoli jiným klíčem (například "or") se ignoruje a odpovídá každému záznamu, takže překlep tiše vypne danou část filtru. Objekt bez klíče nebo s více než jedním klíčem a skupina, jejíž hodnota není neprázdné pole, se odmítnou s 422. Skupiny lze vnořovat až do 32 úrovní.

Příklady

json
{
  "filters": [
    ["assistant_id", "==", "c4e2a9b1-7f3d-4e6a-8b5c-1d9f0a2e3b47"],
    ["created.timestamp", ">=", 1788220800000],
    ["name", "regex", "^draft"]
  ]
}
json
{
  "filters": [
    ["id", "in", [
      "0b8f3c2e-5d41-4a7e-9c1f-6e2d8a4b7c90",
      "9e7a5c3b-1d2f-4b6a-8e0c-4f3d2a1b9c87"
    ]]
  ]
}
json
{
  "filters": [
    {"OR": [["organization_id", "==", null], ["organization_id", "==", "2f9c4b7e-8a1d-4e3c-b6f0-5d7a9e2c1b34"]]}
  ]
}

Server každou podmínku před spuštěním dotazu zkontroluje a normalizuje. Většina překvapivě prázdných výsledků pochází z některého z pravidel níže.

Převod UUID

Řetězcová hodnota, která je platným UUID, se před porovnáním převede na UUID. Pole, která obsahují id (id, assistant_id, created.user_id, ...), se ukládají jako UUID, takže u nich je to přesně to, co chcete. Pole, které obsahuje text, jenž náhodou vypadá jako UUID (včetně 32 šestnáctkových číslic bez pomlček), po převodu neodpovídá. Přidejte true jako čtvrtý prvek, aby se hodnota porovnala jako prostý text:

json
["external_ref", "==", "0b8f3c2e5d414a7e9c1f6e2d8a4b7c90", true]

U in platí čtvrtý prvek pro každou hodnotu v seznamu. Hodnoty uvnitř pole použitého s == nebo != se nikdy nepřevádějí.

Escapování HTML

V řetězcových hodnotách se <, >, " a ' před porovnáním nahradí za &lt;, &gt;, &quot; a &#x27;. Filtr na text, který tyto znaky obsahuje, proto neodpovídá záznamům uloženým s prostými znaky; filtrujte na část textu bez nich, například pomocí regex.

Limity hodnot

Hodnota Pravidlo
řetězec Nejvýše 1 000 znaků. Nesmí začínat na $. Nulové znaky se odstraní.
pole Nejvýše 100 prvků (i pro in). Každý prvek musí být povolená hodnota. in potřebuje aspoň jeden prvek.
povolené typy řetězec, číslo, boolean, null, pole. Objekt jako hodnota se odmítne.

Názvy polí

Název pole musí začínat písmenem a obsahovat jen písmena, číslice, _ a . (nejvýše 128 znaků). Jiné názvy se odmítnou s 422.

Názvy polí ve filtrech se proti záznamu nekontrolují: pole s překlepem neodpovídá ničemu s == a všemu s !=. (sort_key se naopak kontroluje.)

Chybně utvořené podmínky

Podmínka s méně než třemi nebo více než čtyřmi prvky nebo prvek filters (nebo skupiny), který není pole ani objekt, se odmítne s 422. detail říká, co je špatně, například A filter condition must be [field, operator, value] with an optional fourth element, got 2 elements.

Chyby

Chyby používají standardní stavové kódy HTTP a tělo JSON s polem detail:

json
{"detail": "entity not found, id: 0b8f3c2e-5d41-4a7e-9c1f-6e2d8a4b7c90"}

detail je anglická zpráva čitelná pro člověka. Neparsujte ji, s výjimkou případů, kdy stránka endpointu dokumentuje konkrétní zprávu.

Když samotný požadavek neodpovídá schématu endpointu (chybějící pole nebo pole špatného typu, neplatné UUID, chybějící hlavička, žádné tělo), stav je 422 a detail je seznam, který ukazuje na každý problém:

json
{
  "detail": [
    {
      "loc": ["body", "sort_order"],
      "msg": "value is not a valid enumeration member; permitted: 0, 1",
      "type": "type_error.enum",
      "ctx": {"enum_values": [0, 1]}
    }
  ]
}

loc je umístění problému: body, query nebo header, následované cestou k poli.

Jedna odpověď se od tohoto tvaru liší: neočekávané selhání serveru může vrátit 500 s textovým tělem Internal Server Error.

Čtěte nejprve stavový kód a tělo berte jako nepovinnou informaci.

Stav Význam Co dělat
401 API klíč je prázdný, neznámý, smazaný, vypnutý nebo mu chybí rozsah, který endpoint vyžaduje. detail je API key not provided nebo API key is invalid. Zkontrolujte klíč a jeho rozsahy. Neopakujte beze změny.
403 Klíč je platný, ale jeho uživatel tohle dělat nesmí: záznam patří někomu jinému, nebo účtu chybí oprávnění. detail je obvykle permission denied. Neopakujte.
404 Záznam neexistuje (nebo byl smazán). Neopakujte.
422 Požadavek je neplatný: chyby schématu (detail jako seznam, viz výše), odmítnutý filtr nebo klíč řazení, nebo obchodní pravidlo. Nedostatek kreditů je také 422, s detail not enough user credit nebo not enough organization credit. Opravte požadavek, nebo doplňte kredity.
423 Zdroj je zamčený jinou operací (například záznam booster databáze). Zkuste to znovu po krátké pauze.
429 Překročen limit požadavků, viz Limity požadavků. Počkejte Retry-After sekund.
500 Chyba serveru. Zkuste to později znovu s odstupem (backoff); pokud chyba přetrvává, nahlaste ji.
502, 503, 504, 529 Poskytovatel AI nebo jiná navazující služba selhala nebo je přetížená. Zkuste to později znovu s odstupem (backoff).

API nepoužívá 402; chyby kreditu jsou 422, jak je popsáno výše. Chybějící hlavička uni-api-key (na rozdíl od prázdné nebo chybné hodnoty) je chyba schématu a vrací 422, ne 401.

Odpovědi na neúspěšné kontroly API klíče (401) a na požadavky omezené limitem (429) se záměrně zpožďují zhruba o jednu sekundu, aby se zpomalilo hádání klíčů. Počítejte s tím v časových limitech a nepovažujte zpoždění za problém serveru.

Chyby, které nastanou po zahájení streamu, se hlásí uvnitř streamu, ne jako stav HTTP.

Limity požadavků

Požadavky jsou omezeny podle IP adresy klienta a podle endpointu: každá cesta endpointu má vlastní čítače a všechny požadavky z jedné IP adresy na daný endpoint se počítají dohromady bez ohledu na to, jaký API klíč používají. Požadavky se počítají i tehdy, když selžou, včetně požadavků odmítnutých kvůli špatnému API klíči.

Každý endpoint má tři limity kontrolované současně: za minutu, za hodinu a za den. Jsou to klouzavá okna: požadavek se do okna započítává po celou délku okna od chvíle, kdy byl odeslán, takže kapacita se uvolňuje postupně, ne na začátku celé minuty nebo hodiny. Každá stránka endpointu uvádí jeho úroveň:

Úroveň Za minutu Za hodinu Za den
low 10 100 1 000
default 60 2 000 20 000
high 120 4 000 40 000
static 1 200 30 000 300 000
webhook 6 000 120 000 1 500 000

Úroveň webhook platí jen pro veřejný webhook workflow, který navíc omezuje každý spouštěč zvlášť. Úroveň static je ochrana proti zahlcení u endpointů, které se často dotazují v pravidelných intervalech, jako je verze serveru.

Při překročení limitu API vrátí 429 s hlavičkou Retry-After: počet celých sekund, než bude mít okno místo pro další požadavek.

http
HTTP/1.1 429 Too Many Requests
Retry-After: 17
Content-Type: application/json

{"detail": "Too many requests"}

Úspěšné odpovědi nenesou žádné hlavičky limitů požadavků, takže si rychlost svých požadavků hlídejte sami. Jak se vejít do limitů:

  • Před opakováním počkejte aspoň Retry-After sekund; nikdy neopakujte 429 v těsné smyčce.
  • Při opakovaných selháních (429, 5xx) prodlužujte odstup exponenciálně s náhodným rozptylem (jitter).
  • Dávkovou práci rozložte v čase, místo abyste ji posílali v nárazech, a seznamy, které čtete často, si ukládejte do cache, místo abyste je stahovali při každém použití.
  • Více workerů za jednou IP adresou sdílí limity; počítejte se všemi.

Streamování

Chat a některé endpointy workflow mohou svůj výstup streamovat: odpověď se posílá po částech (chuncích) už během generování, místo jednoho těla JSON na konci. Formát chunků, signál konce streamu a způsob hlášení chyb uprostřed streamu popisuje stránka Streamování.