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:
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>"}:
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:
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
1790846045000pro 2026-10-01 09:14:05 UTC.0znamená „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. |
{
"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_frommusí být0nebo víc alimit_tomusí být větší nežlimit_from. Zápornélimit_fromnebolimit_tonižší nežlimit_fromse odmítne s422. Když se obě hodnoty rovnají, žádná horní mez se nepoužije a vrátí se všechny záznamy odlimit_fromdál.limit_tobezlimit_fromse 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.
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á:
[
{
"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:
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č.
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}'
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):
["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:
regexnikdy 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 polenullnebo 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.
{"OR": [["model", "==", "gpt-5-mini"], ["model", "==", "gpt-5"]]}
{"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
{
"filters": [
["assistant_id", "==", "c4e2a9b1-7f3d-4e6a-8b5c-1d9f0a2e3b47"],
["created.timestamp", ">=", 1788220800000],
["name", "regex", "^draft"]
]
}
{
"filters": [
["id", "in", [
"0b8f3c2e-5d41-4a7e-9c1f-6e2d8a4b7c90",
"9e7a5c3b-1d2f-4b6a-8e0c-4f3d2a1b9c87"
]]
]
}
{
"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:
["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 <,
>, " a '. 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:
{"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:
{
"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/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-Aftersekund; nikdy neopakujte429v 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í.