# Ribos

> Užklausų ir importų ribos, ribų antraštės ir kaip elgtis gavus 429.

Šaltinis: https://diko.app/api-docs/ribos

## Kaip veikia ribos

Ribos apsaugo API ir kitus naudotojus nuo netyčia įsisiautėjusio kliento. Kiekviena politika yra žetonų kibiras. **Talpa** (angl. *burst*) nurodo, kiek užklausų galite išsiųsti iš karto. **Papildymas** nurodo, kiek jų atsinaujina per laiką. Pavyzdžiui, politika `read` leidžia iš karto išsiųsti 10 skaitymo užklausų, o tada vidutiniškai 5 per sekundę.

| Politika | Taikoma | Talpa | Papildymas |
|---|---|---|---|
| `read` | API raktui | 10 | 5 / s |
| `write` | API raktui | 5 | 1 / s |
| `imports` | API raktui | 5 | 30 / min. |
| `account` | mokėtojui: komandos plane – mokančiai komandai, kitu atveju – naudotojui (visiems raktams ir nariams kartu) | 20 | 10 / s |
| `export` (`format=text`, `srt`, `vtt`) | mokėtojui, kaip `account` | 10 | 1 / s |
| `me` (tik `GET /me`) | API raktui | 5 | 1 / s |
| `auth_failures` | patikimam IP (IPv6 – /64 tinklui) | 20 | 20 / min. |

*Mokėtojas* yra komanda, kuri moka už planą, jei naudojate komandos planą. Kitu atveju tai esate jūs. Todėl komandos plane `account` ir `export` kibirai bendri visų komandos narių raktams. Daugiau raktų ar daugiau narių papildomos talpos neduoda. Politikos `read`, `write`, `imports` ir `me` lieka kiekvienam raktui atskiros.

Politika `export` skaičiuojama prieš skaitant transkriptą, todėl užklausa, kuri baigiasi 404, taip pat sunaudoja vieną jos žetoną.

Viena užklausa gali priklausyti kelioms politikoms. Pavyzdžiui, skaitymas skaičiuojamas ir pagal `read`, ir pagal `account`; `GET /me` – pagal `read`, `account` ir `me`; `POST /library/imports` – pagal `write`, `imports` ir `account`. Kiekvieno endpointo politikos nurodytos [API žinyne](https://diko.app/api-docs/zinynas.md).

Papildomai:

- iki **2 lygiagrečių užklausų** vienam naudotojui (visiems jo raktams kartu); komandos plane visa komanda dalijasi **3 lygiagrečiomis užklausomis**; viršijus grąžinama 429 [`rate_limit_exceeded`](https://diko.app/api-docs/klaidos.md#rate_limit_exceeded) su `details.policy = concurrency`;
- `GET /me` turi savo ribą (politika `me`): 5 užklausų pradinė talpa, toliau **1 užklausa per sekundę**;
- duomenų bazės užklausoms taikomas bendras apkrovos ribotuvas, todėl apkrovos metu API gali grąžinti 503 [`service_unavailable`](https://diko.app/api-docs/klaidos.md#service_unavailable) su `Retry-After: 2`. Tai ne jūsų klaida, tiesiog pakartokite.

`GET /me` atsakymo lauke `limits.rate` išvardytos raktui taikomos politikos (`read`, `write`, `imports`, `account`, `me` ir `export`) su jų pradine talpa ir papildymu. Skaičiai visiems raktams vienodi, o kieno kibirą jie riboja, nurodyta lentelėje aukščiau. Politika `auth_failures` ir lygiagretumo riba yra tos, kurios nurodytos lentelėje ir sąraše aukščiau.

## Ribų antraštės

Kiekvienas atsakymas į autentifikuotą užklausą, pasiekusią ribotuvą, pateikia ribų būseną dviem būdais. Vienas būdas atitinka IETF `RateLimit` juodraštį, kitas naudoja plačiai paplitusias `X-RateLimit-*` antraštes. Atsakymai, atmesti dar prieš taikant ribas, ribų antraščių neturi. Tai trūkstamas ar netinkamas raktas, neleidžiamas IP, nežinomas kelias, netinkamas metodas bei per didelis, netinkamo tipo ar per lėtai gautas užklausos turinys:

```http
RateLimit-Policy: "read";q=10;w=2, "account";q=20;w=2
RateLimit: "read";r=7;t=1
X-RateLimit-Limit: 10
X-RateLimit-Remaining: 7
X-RateLimit-Reset: 1
```

| Antraštė | Reikšmė |
|---|---|
| `RateLimit-Policy` | taikomos politikos: `q` – talpa, `w` – langas sekundėmis |
| `RateLimit` | **labiausiai ribojanti** dabar taikoma politika: `r` – liko užklausų, `t` – sekundės iki kito žetono |
| `X-RateLimit-Limit` | tos politikos talpa |
| `X-RateLimit-Remaining` | liko užklausų |
| `X-RateLimit-Reset` | sekundės iki kito žetono |

## Gavus 429

Viršijus ribą API grąžina 429 [`rate_limit_exceeded`](https://diko.app/api-docs/klaidos.md#rate_limit_exceeded) su antrašte `Retry-After` (sveikos sekundės, ne mažiau kaip 1, iki kito žetono). `error.details.policy` nurodo, kuri politika viršyta (pavyzdys su `Accept-Language: lt`):

```json
{
  "type": "error",
  "error": {
    "type": "rate_limit_error",
    "code": "rate_limit_exceeded",
    "message": "Per daug užklausų. Sulėtinkite ir bandykite po Retry-After nurodyto laiko.",
    "doc_url": "https://diko.app/api-docs/klaidos#rate_limit_exceeded",
    "details": { "policy": "read", "retry_after": 1 }
  },
  "request_id": "req_QBPIQ5QTIWAUYTMDNCLD7CMKBE"
}
```

Ką daryti:

1. Palaukite `Retry-After` sekundžių ir pridėkite nedidelę atsitiktinę paklaidą, kad keli klientai nesikartotų vienu metu.
2. Vienu metu vykdykite ne daugiau kaip 2 užklausas visai paskyrai: riba skaičiuojama visiems jūsų raktams kartu, o komandos plane – ir visų narių raktams.
3. Sąrašus skaitykite dideliais puslapiais (`limit=100`) ir sekite `has_more`, o ne kvieskite po vieną elementą.
4. Vietoj nuolatinio tikrinimo naudokite [webhooks](https://diko.app/api-docs/webhooks.md) arba `GET /events`.

Pakartojimo pagalbinį kodą rasite puslapyje [Klaidos](https://diko.app/api-docs/klaidos.md#pakartojimo-pavyzdys).

## Importų talpa

Importai turi papildomą apsaugą, nes jie naudoja kreditus ir apdorojimo eilę. Kiekvienas sprendimas priimamas kuriant importą:

| Riba | Reikšmė |
|---|---|
| Aktyvūs naudotojo importai (`queued`, `processing`, `canceling`) | iki 10 |
| Aktyvūs importai visiems naudotojams | iki 200 |
| Naudotojo importai per parą (pastarąsias 24 valandas) | iki 500 |

Paros riba skaičiuoja **visus** per pastarąsias 24 valandas sukurtus importus, įskaitant tuos, į kuriuos atsakyta iš jūsų bibliotekos ar bendros Diko talpyklos (`reused: true`). Jie kreditų nekainuoja, bet vis tiek yra importai.

Viršijus bet kurią ribą API grąžina 429 [`queue_limit_exceeded`](https://diko.app/api-docs/klaidos.md#queue_limit_exceeded) su `Retry-After: 60`. `error.details.limit` nurodo, kuri riba pasiekta: `user_active_imports`, `capacity` (visiems naudotojams) arba `user_daily_imports`. Palaukite, kol dalis importų baigsis, o ne siųskite daugiau užklausų.

```json
{
  "type": "error",
  "error": {
    "type": "rate_limit_error",
    "code": "queue_limit_exceeded",
    "message": "Per daug importų eilėje ar vykdomų. Bandykite vėliau.",
    "doc_url": "https://diko.app/api-docs/klaidos#queue_limit_exceeded",
    "details": { "limit": "user_active_imports", "retry_after": 60 }
  },
  "request_id": "req_QBPIQ5QTIWAUYTMDNCLD7CMKBE"
}
```

> **Pastaba:**
> Importo kūrimas niekada nelaukia atsisiuntimo, todėl užklausa grįžta greitai. Jei vidinė apdorojimo eilė užimta, importas lieka `queued` ir bus bandomas vėliau. Jis nevirsta klaida. Vaizdo įrašas be subtitrų transkribuojamas kalbos atpažinimu bendroje Diko eilėje. Tie darbai naudoja tas pačias naudotojo transkripcijų vietas kaip jūsų įkėlimai programėlėje. Jie niekada neužima paskutinės laisvos vietos, todėl API klientas neužblokuos jūsų įkėlimų ir įrašų.

## Autentifikacijos klaidų riba

Politika `auth_failures` riboja bandymus su blogais raktais iš to paties patikimo IP. Nematytų raktų tikrinimui taikomas ir bendras biudžetas. Todėl bandymai spėlioti raktus gauna `invalid_api_key` be papildomos informacijos. Pakartotinai siųsti tą patį blogą raktą beprasmiška.
