# Authentification

Tout appel qui exécute un modèle ou lit vos requêtes nécessite une clé API. Le catalogue (`GET /models`, `GET /categories`), `POST /quote` et le document OpenAPI sont publics.

## Clés API

Créez et révoquez des clés à l’adresse [https://doitong.com/developers/dashboard#keys](https://doitong.com/developers/dashboard#keys). Une clé ressemble à `doitong_` suivi de 64 caractères hexadécimaux et n’est affichée qu’une seule fois, lors de sa création. Envoyez-la dans l’en-tête `Authorization` :

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

`X-API-Key: <key>` fonctionne également.

> [!WARNING]
> Conservez les clés sur votre serveur : toute personne qui possède une clé peut dépenser les crédits API qu’elle est autorisée à dépenser. Si une clé est exposée, révoquez-la et créez-en une nouvelle.

Une requête sans clé reçoit `401` avec le code `missing_api_key`; une clé inconnue, révoquée ou expirée reçoit également `401`.

## Portées

Chaque clé possède des portées. L’API des modèles vérifie les suivantes :

| Action | Portée requise |
|---|---|
| Exécuter un modèle, annuler une requête, supprimer les fichiers d’une requête, modifier le paramètre de stockage | `models:run` (les clés avec l’ancienne portée `images:create` ou `videos:create` fonctionnent également) |
| Créer une URL d’envoi | `models:run` ou `media:upload` |
| Lire les requêtes et le compte | `models:read` (une clé qui peut exécuter des modèles peut également les lire) |

Les nouvelles clés reçoivent `models:read` et `models:run` par défaut. Un appel sans la portée appropriée reçoit `403` avec le code `insufficient_scope`.

## Budgets de crédits

Une clé peut avoir son propre budget en crédits API (1 000 crédits API = 1 $), défini par le propriétaire du compte : un budget total, un budget quotidien (les dernières 24 heures), ou les deux. Avant de facturer une exécution, le coût est comparé à ce que la clé a déjà dépensé par l’intermédiaire de cette API (après déduction des remboursements). Une exécution qui le dépasserait est refusée avec `402 budget_exceeded` et rien n’est facturé.

> [!IMPORTANT]
> Un refus lié au budget est définitif : une nouvelle tentative ne changera rien tant que le propriétaire n’aura pas augmenté le budget.

 Une clé sans budget peut dépenser jusqu’à concurrence du solde API. Par ailleurs, une exécution que le solde API ne peut pas couvrir reçoit `402 insufficient_credits` avec un `top_up_url`.

`GET https://api.doitong.com/v1/account` affiche le solde API et le budget restant de la clé (tous deux en crédits API) :

```json 200 OK · account
{
  "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` vaut `null` lorsque la clé n’a pas de budget propre.

## Limites de débit

Chaque clé peut effectuer 3600 requêtes par heure, sauf si sa limite a été définie autrement. Chaque réponse authentifiée contient l’état actuel :

| En-tête | Signification |
|---|---|
| `X-RateLimit-Limit` | Requêtes autorisées pendant la fenêtre actuelle |
| `X-RateLimit-Remaining` | Requêtes restantes pendant la fenêtre actuelle |
| `X-RateLimit-Reset` | Heure Unix de réinitialisation de la fenêtre |

Au-delà de la limite, vous recevez `429` avec un en-tête `Retry-After` (secondes). L’interrogation longue avec `?wait=` compte comme une requête par appel; attendre coûte donc moins cher qu’interroger rapidement.

Il existe également une limite de 10 requêtes en cours (`queued` ou `running`) par compte. Le démarrage d’une requête supplémentaire renvoie `429 too_many_inflight`; démarrez-la de nouveau lorsqu’une autre est terminée.
