# Ключ и лимиты

> Как передать ключ, пределы тарифов, заголовки остатка и как экономить запросы.

> Оглавление документации для агентов: https://kinodata.space/ru/llms.txt — вся документация одним файлом: https://kinodata.space/ru/llms-full.txt

Каждый запрос передаёт ключ в заголовке `X-API-Key`. Считаются два предела: запросы в секунду и запросы в сутки. На этой странице — как передать ключ, как следить за остатком и как не тратить запросы впустую.

## Передайте ключ

Ключ идёт в заголовке `X-API-Key` каждого запроса. Во всех примерах документации он берётся из переменной окружения `KINODATA_KEY`:

```bash
curl -H "X-API-Key: $KINODATA_KEY" \
  "https://api.kinodata.space/v1.3/ids/kp/447301"
```

Ответ `200`:

```json
{
  "imdb_id": "tt1375666",
  "kp_id": "447301",
  "tmdb_id": "27205",
  "tmdb_tv_id": null,
  "kinorium_id": "472809"
}
```

Без ключа или с неверным ключом API отвечает `401`. Тот же запрос без заголовка:

```bash
curl -s "https://api.kinodata.space/v1.3/ids/kp/447301"
```

Ответ `401`:

```json
{
  "error": {
    "code": "unauthorized",
    "message": "missing api key"
  }
}
```

Без ключа отвечает только `https://api.kinodata.space/health` — проверка, что API работает.

## Пределы тарифов

| тариф | запросов в секунду | запросов в сутки |
|---|---|---|
| Free | 10 | 500 |
| Basic | 20 | 5 000 |
| Business | 40 | без предела при добросовестном использовании |

На Basic и Business можно выпустить два ключа. Пределы при этом — на аккаунт, а не на ключ: два ключа Basic делят одни 20 запросов в секунду и 5 000 в сутки, а не получают столько каждый.

Сутки считаются по UTC: квота обновляется в полночь по UTC, а не через 24 часа после первого запроса. Тарифы и цены — на странице [Тарифы](https://kinodata.space/ru/pricing).

## Следите за остатком

С каждым ответом приходят заголовки с текущим остатком:

| заголовок | что это |
|---|---|
| `X-RateLimit-Limit` | Сколько запросов разрешено в секунду. |
| `X-RateLimit-Remaining` | Сколько осталось в текущей секунде. |
| `X-RateLimit-Reset` | Когда начнётся следующая секунда, Unix-время. |
| `X-Quota-Limit` | Сколько запросов разрешено в сутки. |
| `X-Quota-Remaining` | Сколько осталось на сегодня. |
| `X-Quota-Reset` | Когда квота обновится, Unix-время: ближайшая полночь по UTC. |
| `Retry-After` | Только в ответе `429`: через сколько секунд повторить запрос. |

Так выглядят заголовки ключа Basic:

```text
X-RateLimit-Limit: 20
X-RateLimit-Remaining: 19
X-RateLimit-Reset: 1791566201
X-Quota-Limit: 5000
X-Quota-Remaining: 4812
X-Quota-Reset: 1791590400
```

У ключа без предела соответствующих заголовков нет. Из браузера они тоже видны: API открывает их в `Access-Control-Expose-Headers`.

## Если упёрлись в предел

API отвечает `429`. Текст ошибки говорит, какой предел сработал:

```json
{ "error": { "code": "rate_limited", "message": "quota limit exceeded" } }
```

- `rate limit exceeded` — запросов в этой секунде больше, чем разрешено. Подождите `Retry-After` секунд и разнесите запросы во времени: очередь или пауза между запросами помогут лучше повторов.
- `quota limit exceeded` — квота на сутки закончилась. `Retry-After` покажет, сколько секунд до полуночи по UTC. Если квоты не хватает регулярно, посмотрите [тарифы](https://kinodata.space/ru/pricing).

Запрос, отклонённый пределом в секунду, квоту на сутки не тратит.

## Экономьте запросы

### Берите только нужные блоки

Карточка тайтла целиком весит около 26 КБ. Если нужны название и оценки, попросите только их: `fields=title,ratings`. Ответ станет меньше, а запрос — дешевле для вашей сети. Подробнее — в разделе [Списки и пагинация](https://kinodata.space/ru/docs/lists.md#только-нужные-поля).

### Кэшируйте ответы

Ответ можно хранить пять минут: API присылает `Cache-Control: private, max-age=300`. Хранить его может ваш сервер или браузер, но не общий кэш вроде CDN: ответ принадлежит ключу.

Чтобы проверить, изменились ли данные, не скачивая их заново, используйте условный запрос.

1. Сохраните заголовок `ETag` из ответа — здесь в переменную `ETAG`:

```bash
ETAG=$(curl -sI -H "X-API-Key: $KINODATA_KEY" "https://api.kinodata.space/v1.3/titles/tmdb/27205" | grep -i '^etag:' | cut -d' ' -f2 | tr -d '\r')
```

2. В следующем запросе к тому же адресу передайте его в `If-None-Match` как есть, вместе с кавычками:

```bash
curl -s -o /dev/null -w '%{http_code}\n' -H "X-API-Key: $KINODATA_KEY" -H "If-None-Match: $ETAG" "https://api.kinodata.space/v1.3/titles/tmdb/27205"
```

Если данные не изменились, придёт `304` без тела — значит, сохранённый ответ ещё верен. Ответ `304` не тратит квоту: проверять свежесть данных так можно сколько угодно часто.

### Включите сжатие

С заголовком `Accept-Encoding: gzip` карточка «Начала» весит 8 КБ вместо 26 КБ. Большинство HTTP-клиентов просят сжатие сами. curl — только с флагом `--compressed`.

## Храните ключ на сервере

API отвечает на запросы из браузера с любого сайта, но ключ в коде страницы или мобильного приложения увидит любой, кто откроет инструменты разработчика. Отправляйте запросы со своего сервера, а в браузер отдавайте готовые данные.

## Если что-то не так

С каждым ответом приходят два служебных заголовка:

| заголовок | что это |
|---|---|
| `X-Request-Id` | ID запроса. Приложите его к обращению — по нему мы найдём запрос. |
| `X-API-Version` | Версия API, которая ответила: `1.3`. |

## Дальше

- [Ошибки](https://kinodata.space/ru/docs/errors.md) — все коды и что с ними делать.
- [Списки и пагинация](https://kinodata.space/ru/docs/lists.md) — как листать длинные ответы.
