{"auth":{"ApiKeyAuth":"X-API-Key: pk_live_… (browser key, Origin must be an allowed domain)","BearerAuth":"Authorization: Bearer sk_live_… (server key)"},"base_url":"https://ai.smartbee.az/api","executor":"For a tool call: take routes[name]; substitute path_params into url ({name}); send query_params as the query string; send input.body as the JSON body; add the auth header. Non-2xx → read the JSON `message` field.","format":"anthropic","guide":"https://ai.smartbee.az/llms-full.txt","routes":{"get_health":{"auth":null,"body":false,"method":"GET","path_params":[],"query_params":[],"url":"https://ai.smartbee.az/api/health"},"get_health_services":{"auth":null,"body":false,"method":"GET","path_params":[],"query_params":[],"url":"https://ai.smartbee.az/api/health/services"},"get_v1_articles_external_id_audio":{"auth":["ApiKeyAuth","BearerAuth"],"body":false,"method":"GET","path_params":["external_id"],"query_params":[],"url":"https://ai.smartbee.az/api/v1/articles/{external_id}/audio"},"get_v1_audio_file":{"auth":null,"body":false,"method":"GET","path_params":["file"],"query_params":[],"url":"https://ai.smartbee.az/api/v1/audio/{file}"},"get_v1_translations_id":{"auth":["ApiKeyAuth","BearerAuth"],"body":false,"method":"GET","path_params":["id"],"query_params":[],"url":"https://ai.smartbee.az/api/v1/translations/{id}"},"get_v1_webhook":{"auth":["BearerAuth"],"body":false,"method":"GET","path_params":[],"query_params":[],"url":"https://ai.smartbee.az/api/v1/webhook"},"post_v1_articles":{"auth":["ApiKeyAuth","BearerAuth"],"body":true,"method":"POST","path_params":[],"query_params":["wait"],"url":"https://ai.smartbee.az/api/v1/articles"},"post_v1_articles_external_id_invalidate":{"auth":["BearerAuth"],"body":false,"method":"POST","path_params":["external_id"],"query_params":[],"url":"https://ai.smartbee.az/api/v1/articles/{external_id}/invalidate"},"post_v1_articles_external_id_translate":{"auth":["ApiKeyAuth","BearerAuth"],"body":true,"method":"POST","path_params":["external_id"],"query_params":["wait"],"url":"https://ai.smartbee.az/api/v1/articles/{external_id}/translate"},"post_v1_translations":{"auth":["BearerAuth"],"body":true,"method":"POST","path_params":[],"query_params":["wait"],"url":"https://ai.smartbee.az/api/v1/translations"},"put_v1_webhook":{"auth":["BearerAuth"],"body":true,"method":"PUT","path_params":[],"query_params":[],"url":"https://ai.smartbee.az/api/v1/webhook"}},"tools":[{"description":"Sağlamlıq yoxlaması. k8s startup/readiness/liveness probe-ları üçün. Auth tələb etmir, asılılıqları yoxlamır. Unauthenticated liveness check. Use it to verify the base URL before other calls.","input_schema":{"properties":{},"type":"object"},"name":"get_health"},{"description":"Asılılıqların vəziyyəti. PostgreSQL, Redis və AI provayderlərinin (token konfiq olunubmu) vəziyyəti. Landing səhifəsindəki \"Status\" bloku bunu oxuyur.","input_schema":{"properties":{},"type":"object"},"name":"get_health_services"},{"description":"Məqaləni səsləndirməyə göndər. Məqalə mətnini qəbul edir və səsləndirmə növbəsinə qoyur (lazy generasiya). Mətn təmizlənir (HTML atılır, boşluqlar normallaşır), `content_hash` = sha256(provayder + səs + mətn) hesablanır:\n- eyni məzmun artıq hazırdırsa → **200** `{status:\"ready\", audio_url, duration_sec}` (yeni sintez və ödəniş yoxdur; eyni tenant-ın başqa `external_id`-sindəki eyni mətn də təkrar istifadə olunur);\n- növbədə / səsləndirilirsə → **202** `{status:\"pending\"|\"processing\", job_id}` — sonra `GET /v1/articles/{external_id}/audio` ilə 2–6 s aralıqla sorğulayın;\n- əvvəlki cəhd uğursuz olubsa və soyuma müddəti keçibsə avtomatik yenidən növbəyə qoyulur (202), keçməyibsə 200 `{status:\"failed\", error}`.\n\n**wait:** `wait` (saniyə, 0…MAX_WAIT_SECONDS, default tavan 60; pk açarı üçün maks. 30) verilsə server nəticəni həmin müddət gözləyir — vaxtında hazır olsa **200** + `audio_url`, olmas","input_schema":{"properties":{"body":{"description":"JSON sorğu gövdəsi (Content-Type: application/json)","properties":{"callback_url":{"description":"Yalnız sk açarı: hazır / uğursuz olanda bu URL-ə imzalı POST (tenant webhook-unu əvəz edir). https, ictimai host.","example":"https://sfera.az/hooks/smartbee","type":"string"},"external_id":{"description":"Saytın məqalə id-si (1–200 simvol). GET …/{external_id}/audio bununla sorğulanır.","example":"387561","type":"string"},"html":{"description":"Alternativ: məqalənin HTML-i (skript/stil atılır, abzaslar saxlanır). text varsa nəzərə alınmır.","example":"\u003cp\u003eBakıda yeni metro stansiyası açıldı.\u003c/p\u003e","type":"string"},"lang":{"description":"Dil: az | en | ru (default az).","example":"az","type":"string"},"text":{"description":"Səsləndiriləcək mətn (düz mətn və ya HTML — teqlər atılır). text və ya html məcburidir.","example":"Bakıda yeni metro stansiyası açıldı. Stansiya gündə 40 min sərnişinə xidmət edəcək.","type":"string"},"title":{"description":"Başlıq (yalnız saxlanır — səsləndirilmir; başlıq oxunmalıdırsa text-in əvvəlinə yazın).","example":"Bakıda yeni metro stansiyası açıldı","type":"string"},"url":{"description":"Kanonik URL (audit; pk açarında host icazəli domen deyilsə saxlanmır).","example":"https://sfera.az/xeber/387561-iqtisadiyyat","type":"string"},"voice":{"description":"Səs: provayder voice_id-si və ya adı (məs. \"xeber\"). Tanınmasa tenant-ın default səsi işlədilir.","example":"xeber","type":"string"},"wait":{"description":"Nəticəni bu qədər saniyə gözlə (0…MAX_WAIT_SECONDS, default 60; pk açarı üçün maks. 30). Hazır olsa 200 + audio_url,\nvaxt bitsə 202 + poll_url. 0 (default) — dərhal 202. Query-də `?wait=` də olar. Webhook hər halda göndərilir.","example":30,"type":"integer"}},"title":"articles.SubmitRequest","type":"object"},"wait":{"description":"Nəticəni gözləmə müddəti, saniyə (body-dəki wait ilə eyni) (query)","type":"integer"}},"required":["body"],"type":"object"},"name":"post_v1_articles"},{"description":"Məqalənin audio vəziyyəti. `external_id`-nin cari versiyasının vəziyyəti: `pending` | `processing` → bir neçə saniyə sonra yenidən sorğulayın; `ready` → `audio_url` (MP3, immutable CDN) və `duration_sec`; `failed` → `error`. Heç göndərilməyibsə **404** — onda `POST /v1/articles` ilə mətni göndərin.\nYeni versiya uğursuz olub, köhnə hazır versiya varsa köhnəsi qaytarılır. Uğursuz versiya soyuma müddətindən (ARTICLE_RETRY_FAILED_AFTER) sonra sorğulananda avtomatik yenidən növbəyə qoyulur (`pending`). `external_id`-də `/` varsa URL-kodlayın (`news%2F123`). Read the audio status. status=pending|processing → wait and retry with back-off; ready → use `audio_url` (immutable, cacheable) and `duration_sec`; failed → read `error` and do NOT loop — after a cool-down a later GET re-queues it automatically; resubmit only if the text changed. 404 → the article was never submitted: call `POST /v1/articles` first.","input_schema":{"properties":{"external_id":{"description":"Saytın məqalə id-si (path)","type":"string"}},"required":["external_id"],"type":"object"},"name":"get_v1_articles_external_id_audio"},{"description":"Məqalənin audiosunu köhnəlmiş say (məzmun dəyişib). `external_id`-nin bütün versiyalarını cari olmaqdan çıxarır: növbəti `GET …/audio` 404 qaytarır və pleyer/sayt yeni mətni göndərir (yeni sintez = yeni ödəniş). Eyni mətn yenidən gəlsə köhnə audio təkrar istifadə olunur. **Yalnız sk açarı.** Secret key only. Call when the article text was edited after it had been voiced; then submit the new text with `POST /v1/articles`. A new synthesis is billed.","input_schema":{"properties":{"external_id":{"description":"Saytın məqalə id-si (path)","type":"string"}},"required":["external_id"],"type":"object"},"name":"post_v1_articles_external_id_invalidate"},{"description":"Məqaləni tərcümə et. Artıq göndərilmiş məqalənin (`POST /v1/articles`) cari versiyasının başlıq və mətnini `target_lang` dilinə tərcümə edir — mətn serverdən götürülür, sorğuda göndərilmir (pk açarı ilə də işləyir). Mənbə dil məqalənin `lang`-ıdır (yoxdursa `az`).\n**Növbə ilə işləyir:** iş növbəyə qoyulur. `wait` (saniyə, 0…MAX_WAIT_SECONDS; pk üçün maks. 30) verilsə nəticə həmin müddət gözlənilir — vaxtında bitsə **200** + `text`, bitməsə **202** `{status:\"pending\"|\"processing\", id, poll_url}`. `wait` yoxdursa dərhal **202** — sonra `GET /v1/translations/{id}` (2–5 s aralıqla) və ya webhook (`translation.ready` / `translation.failed`).\nEyni məzmun bu dilə əvvəl tərcümə olunubsa dərhal **200** (`cached: true`, ödəniş yoxdur); eyni məzmun hələ işdədirsə həmin işin id-si qaytarılır (ikinci dəfə ödənmir). Ödəniş vahidi — mənbə simvolu (başlıq + mətn).\n**Webhook:** hazır/uğu","input_schema":{"properties":{"body":{"description":"JSON sorğu gövdəsi (Content-Type: application/json)","properties":{"callback_url":{"description":"Yalnız sk açarı: hazır / uğursuz olanda bu URL-ə imzalı POST (tenant webhook-unu əvəz edir). https, ictimai host.","example":"https://sfera.az/hooks/smartbee","type":"string"},"target_lang":{"description":"az | en | ru | tr | de | fr | ar | fa | uk | ka","example":"en","type":"string"},"wait":{"description":"Nəticəni bu qədər saniyə gözlə (0…MAX_WAIT_SECONDS, pk üçün maks. 30). Hazır olsa 200 + text, vaxt bitsə 202 + poll_url.\n0 (default) — dərhal 202 (artıq hazırdırsa 200). Query-də `?wait=` də olar.","example":30,"type":"integer"}},"title":"translations.TranslateArticleRequest","type":"object"},"external_id":{"description":"Saytın məqalə id-si (path)","type":"string"},"wait":{"description":"Nəticəni gözləmə müddəti, saniyə (body-dəki wait ilə eyni) (query)","type":"integer"}},"required":["body","external_id"],"type":"object"},"name":"post_v1_articles_external_id_translate"},{"description":"Hazır audio faylı. Səsləndirilmiş məqalənin audiosu (S3 konfiq olunmayanda PostgreSQL fallback-ından). `audio_url` bu ünvana işarə edir — əl ilə qurmaq lazım deyil. Public (auth yoxdur, id 128 bitlik məzmun hash-idir), `Cache-Control: public, max-age=31536000, immutable`, `Range` (seek) və `If-None-Match` dəstəklənir.","input_schema":{"properties":{"file":{"description":"{id}.mp3 (path)","type":"string"}},"required":["file"],"type":"object"},"name":"get_v1_audio_file"},{"description":"Mətni tərcümə et. İxtiyari mətni (və istəyə görə başlığı) `source_lang`-dan (default `az`) `target_lang`-a tərcümə edir. HTML gəlsə teqlər atılır, abzaslar saxlanılır. **Yalnız sk açarı** (pk ilə ixtiyari mətn xərc riskidir — brauzerdən `POST /v1/articles/{external_id}/translate` işlədin).\n**Növbə ilə işləyir** (uzun mətn də): `wait` (saniyə, 0…MAX_WAIT_SECONDS) verilsə nəticə gözlənilir — vaxtında bitsə **200** + `text`, bitməsə **202** + `poll_url`; `wait` yoxdursa dərhal **202**. Nəticə `GET /v1/translations/{id}` və ya webhook ilə gəlir: `callback_url` (bu sorğu üçün) və ya tenant webhook-u — `translation.ready` / `translation.failed`, body `{\"id\":\"evt_…\",\"type\":…,\"data\":{id, external_id, status, source_lang, target_lang, title, text, chars, error, error_code}}`, imza `X-SmartBee-Signature` (article.* ilə eyni). `wait` ilə 200 alsanız da webhook göndərilir (idempotent emal edin).\nEyni mətn eyni dilə ə","input_schema":{"properties":{"body":{"description":"JSON sorğu gövdəsi (Content-Type: application/json)","properties":{"callback_url":{"description":"Hazır / uğursuz olanda bu URL-ə imzalı POST (tenant webhook-unu əvəz edir). https, ictimai host.","example":"https://sfera.az/hooks/smartbee","type":"string"},"external_id":{"description":"istəyə görə: saytın məqalə id-si (yalnız etiket)","example":"387561","type":"string"},"source_lang":{"description":"boş = az","example":"az","type":"string"},"target_lang":{"example":"en","type":"string"},"text":{"description":"düz mətn və ya HTML (teqlər atılır)","example":"Bakıda sabah hava küləkli olacaq.","type":"string"},"title":{"example":"Hava proqnozu","type":"string"},"wait":{"description":"Nəticəni bu qədər saniyə gözlə (0…MAX_WAIT_SECONDS). Hazır olsa 200 + text, vaxt bitsə 202 + poll_url. 0 — dərhal 202.","example":60,"type":"integer"}},"title":"translations.TranslateRequest","type":"object"},"wait":{"description":"Nəticəni gözləmə müddəti, saniyə (body-dəki wait ilə eyni) (query)","type":"integer"}},"required":["body"],"type":"object"},"name":"post_v1_translations"},{"description":"Tərcümə işinin vəziyyəti / nəticəsi. İctimai `id` ilə (yalnız öz saytınızın): `pending` | `processing` → bir neçə saniyə sonra yenidən sorğulayın; `ready` → `text` (və `title`); `failed` → `error`, `error_code`. Uğursuz iş soyuma müddətindən (ARTICLE_RETRY_FAILED_AFTER) sonra sorğulananda avtomatik yenidən növbəyə düşür (`pending`). Ödəniş yoxdur. Status / result of a translation job by its `id` (only your own site's): pending|processing → retry with back-off; ready → `text`; failed → `error`/`error_code`, do NOT loop (after a cool-down a later GET re-queues it automatically). Free.","input_schema":{"properties":{"id":{"description":"Tərcümə id-si (uuid) (path)","type":"string"}},"required":["id"],"type":"object"},"name":"get_v1_translations_id"},{"description":"Webhook ayarları və imza sirri. Tenant səviyyəli callback URL-i və `X-SmartBee-Signature` imzasının sirri (whsec_…). Sirr yoxdursa bu sorğu onu yaradır. **Yalnız sk açarı** (`Authorization: Bearer sk_live_…`).\n\nCallback body-si: `{\"id\":\"evt_…\",\"type\":\"article.ready|article.failed\",\"created_at\":\"…\",\"data\":{external_id, job_id, status, audio_url, duration_sec, chars, error}}`.\nİmza: `X-SmartBee-Signature: t=\u003cunix\u003e,v1=\u003chex\u003e`, `v1 = HMAC-SHA256(secret, \"\u003ct\u003e.\" + raw_body)`. Alıcı xam body baytları ilə HMAC-ı hesablayır, sabit-vaxtlı müqayisə edir və |now − t| ≤ 300 s yoxlayır. 2xx = çatdırıldı; əks halda 10s, 30s, 2m, 10m, 30m, 1h, 2h, 4h gecikmə ilə təkrar (WEBHOOK_MAX_ATTEMPTS). Dublikat ola bilər — `id` ilə idempotent emal edin. Secret key only. Read the tenant-level callback URL and whether a signing secret exists.","input_schema":{"properties":{},"type":"object"},"name":"get_v1_webhook"},{"description":"Webhook URL-ini dəyiş / sirri yenilə. `url`: tenant səviyyəli callback (https, ictimai host; daxili/private IP-lər rədd olunur). `\"\"` = sil, göndərilməsə dəyişmir. `rotate_secret: true` → yeni sirr. Sorğu başına `callback_url` (POST /v1/articles) bu URL-dən üstündür. **Yalnız sk açarı.** Secret key only. Set the HTTPS callback URL for article.ready / article.failed events (`rotate_secret: true` returns a new `whsec_…` secret once — store it). Verify every callback: header `X-SmartBee-Signature: t=\u003cunix\u003e,v1=\u003chex\u003e` where v1 = hex(HMAC-SHA256(secret, t + \".\" + raw_body)); reject if |now − t| \u003e 300 s; process idempotently by event `id`; reply 2xx quickly.","input_schema":{"properties":{"body":{"description":"JSON sorğu gövdəsi (Content-Type: application/json)","properties":{"rotate_secret":{"description":"RotateSecret true → yeni whsec_… yaradılır (köhnə imzalar dərhal etibarsız olur).","example":false,"type":"boolean"},"url":{"description":"URL tenant səviyyəli callback (https, ictimai IP). null = dəyişmə, \"\" = sil.","example":"https://sfera.az/hooks/smartbee","type":"string"}},"title":"webhooks.SettingsRequest","type":"object"}},"required":["body"],"type":"object"},"name":"put_v1_webhook"}]}
