# Idempotence

> Envoyez un en-tête Idempotency-Key avec les requêtes POST pour qu’une nouvelle tentative ne lance ni ne facture jamais deux fois une vérification. Comportement, réponses rejouées et conflits.

Source : https://fileverity.com/fr/docs/idempotency

Une panne réseau peut vous laisser sans savoir si une requête POST est bien arrivée. Si vous la renvoyez simplement, une vérification peut être exécutée et facturée deux fois. Envoyez un en-tête `Idempotency-Key` : la nouvelle tentative renvoie alors la première réponse.

## Utiliser l’en-tête

**Requête idempotente: cURL**

```bash
curl https://api.fileverity.com/v1/analyses \
  -H "Authorization: Bearer $FILEVERITY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 0e5f6a64-52c2-4b36-9d0d-6f3d2f4c9a10" \
  -d '{"model": "fvimg-2", "file": "file_8Hk2pQ4vN9sL1xR7cW3mY6zB"}'
```

**Requête idempotente: JavaScript**

```javascript
async function createAnalysis(body) {
  const key = crypto.randomUUID();
  let lastError;
  for (let attempt = 0; attempt < 3; attempt++) {
    try {
      return await fetch("https://api.fileverity.com/v1/analyses", {
        method: "POST",
        headers: { Authorization: "Bearer " + process.env.FILEVERITY_API_KEY, "Content-Type": "application/json", "Idempotency-Key": key },
        body: JSON.stringify(body),
      });
    } catch (error) {
      lastError = error;
    }
  }
  throw lastError;
}
```

**Requête idempotente: Python**

```python
import uuid

def create_analysis(body):
    key = str(uuid.uuid4())
    last_error = None
    for attempt in range(3):
        try:
            return requests.post("https://api.fileverity.com/v1/analyses", headers={**headers, "Idempotency-Key": key}, json=body, timeout=90)
        except requests.ConnectionError as error:
            last_error = error
    raise last_error
```

- Envoyez n’importe quelle chaîne unique de 1 à 255 caractères. Un UUID aléatoire est un bon choix. Utilisez une nouvelle clé pour chaque requête distincte, et ne réutilisez la même clé que pour réessayer la même requête.
- L’en-tête fonctionne sur tous les points d’accès POST : `/text/detections`, `/files`, `/analyses` et `/analyses/{id}/cancel`.
- Les clés sont propres à votre espace de travail, au mode (Live ou Test) et au point d’accès, et conservées 24 heures. La même clé utilisée avec une clé Live et avec une clé de test ne crée pas de conflit.

## Ce que vous recevez en retour

| Situation | Résultat |
| --- | --- |
| Première requête avec une clé | Traitée normalement. Les réponses réussies (statut inférieur à 400) sont enregistrées. |
| Même clé et même corps dans les 24 heures | La réponse enregistrée, avec le même statut, plus l’en-tête `idempotent-replayed: true`. Rien n’est relancé ni refacturé. |
| Même clé, corps différent | `409` `idempotency_mismatch`. |
| Même clé alors que la première requête est encore en cours | `409` `idempotency_in_progress`. Réessayez dans un instant. |
| Même clé après une réponse d’erreur | La clé est libérée. Une erreur n’est pas enregistrée : réessayer relance donc la requête. |

Une réponse rejouée conserve le `x-request-id` de la nouvelle requête, et non celui de l’originale. Les téléversements multipart sont comparés d’après leurs champs de formulaire et le contenu des fichiers.

> **Remarque.** L’idempotence évite le travail en double. Elle ne fait pas réussir une requête échouée : après `service_unavailable` ou `internal_error`, attendez le nombre de secondes indiqué par `retry-after` si la réponse contient cet en-tête, puis réessayez avec la même clé.

Voir aussi [Erreurs](https://fileverity.com/fr/docs/errors.md) et [Limites de débit et en-têtes](https://fileverity.com/fr/docs/rate-limits.md).

