# Uwierzytelnianie

Każde wywołanie, które uruchamia model lub odczytuje żądania, wymaga klucza API. Katalog (`GET /models`,
`GET /categories`), `POST /quote` i dokument OpenAPI są publiczne.

## Klucze API

Twórz i unieważniaj klucze na stronie [https://doitong.com/developers/dashboard#keys](https://doitong.com/developers/dashboard#keys). Klucz ma postać
`doitong_` po którym następuje 64 znaków szesnastkowych, i jest wyświetlany tylko raz — podczas tworzenia. Wysyłaj go w
nagłówku `Authorization`:

```bash
curl https://api.doitong.com/v1/account -H "Authorization: Bearer $DOITONG_API_KEY"
```

`X-API-Key: <key>` również działa.

> [!WARNING]
> Przechowuj klucze na swoim serwerze: każdy, kto ma klucz, może wydać dozwolone dla niego kredyty API. Jeśli klucz wycieknie,
> unieważnij go i utwórz nowy.

Żądanie bez klucza otrzymuje `401` z kodem `missing_api_key`; nieznany, unieważniony lub wygasły klucz również otrzymuje `401`.

## Zakresy

Każdy klucz ma przypisane zakresy. API modeli sprawdza następujące zakresy:

| Działanie | Wymagany zakres |
|---|---|
| Uruchomienie modelu, anulowanie żądania, usunięcie plików żądania, zmiana ustawienia przestrzeni dyskowej | `models:run` (działają również klucze ze starszymi zakresami `images:create` lub `videos:create`) |
| Utworzenie URL przesyłania | `models:run` lub `media:upload` |
| Odczyt żądań i konta | `models:read` (klucz, który może uruchamiać modele, również może je odczytywać) |

Nowe klucze domyślnie otrzymują `models:read` i `models:run`. Wywołanie bez odpowiedniego zakresu otrzymuje `403` z kodem
`insufficient_scope`.

## Budżety kredytów

Klucz może mieć własny budżet w kredytach API (1000 kredytów API = 1 $), ustawiony przez właściciela konta: łączny budżet, budżet
na dzień (ostatnie 24 godziny) albo oba. Przed naliczeniem opłaty za uruchomienie koszt jest porównywany z kwotą, którą klucz już
wydał za pośrednictwem tego API (po uwzględnieniu zwrotów). Uruchomienie, które przekroczyłoby limit, zostaje odrzucone z komunikatem
`402 budget_exceeded`, a opłata nie jest naliczana.

> [!IMPORTANT]
> Odrzucenie z powodu budżetu jest ostateczne: ponowienie nie pomoże, dopóki właściciel nie zwiększy budżetu.

 Klucz bez budżetu może
wydać maksymalnie saldo API. Niezależnie od tego uruchomienie, którego nie można pokryć z salda API, otrzymuje `402 insufficient_credits`
z `top_up_url`.

`GET https://api.doitong.com/v1/account` pokazuje saldo API i pozostały budżet klucza (oba w kredytach API):

```json 200 OK · konto
{
  "object": "account",
  "credits": 125000,
  "balance": { "credits": 125000, "usd": "125.00" },
  "top_up_url": "https://doitong.com/developers/dashboard#balance",
  "key": {
    "name": "Production server",
    "prefix": "doitong_3fa9c1e...",
    "scopes": ["models:read", "models:run"],
    "budget_remaining": 50000,
    "rate_limit": 3600,
    "rate_limit_remaining": 3571
  },
  "webhook_signing_secret": "whsec_..."
}
```

`budget_remaining` ma wartość `null`, gdy klucz nie ma własnego budżetu.

## Limity szybkości

Każdy klucz może wykonywać 3600 żądań na godzinę, chyba że ustawiono dla niego inny limit. Każda uwierzytelniona odpowiedź zawiera
bieżący stan:

| Nagłówek | Znaczenie |
|---|---|
| `X-RateLimit-Limit` | Liczba żądań dozwolonych w bieżącym oknie |
| `X-RateLimit-Remaining` | Liczba żądań pozostałych w bieżącym oknie |
| `X-RateLimit-Reset` | Czas uniksowy resetowania okna |

Po przekroczeniu limitu otrzymasz `429` z nagłówkiem `Retry-After` (sekundy). Długie odpytywanie z `?wait=` jest liczone jako jedno żądanie
na wywołanie, więc oczekiwanie jest tańsze niż szybkie odpytywanie.

Obowiązuje również limit 10 żądań przetwarzanych jednocześnie (`queued` lub `running`) na konto. Rozpoczęcie kolejnego zwraca
`429 too_many_inflight`; uruchom je ponownie po zakończeniu jednego z nich.
