Coffrifydocs
⌘K
Getting Started

Gestion des erreurs

Format JSON unifié, codes HTTP, idempotence et stratégie de retry.

Toutes les erreurs de l'API Coffrify suivent le même format JSON. La propriété `error.code` est machine-readable et stable entre versions.

Format d'erreur

{
  "error": {
    "code": "transfer_not_found",
    "message": "No transfer with id tr_abc123 exists in this workspace.",
    "param": "id",
    "doc_url": "https://docs.coffrify.com/errors#transfer_not_found"
  }
}

Codes HTTP

  • **200 OK** - Succès
  • **201 Created** - Ressource créée
  • **204 No Content** - Suppression réussie
  • **400 Bad Request** - Paramètre invalide (voir `error.param`)
  • **401 Unauthorized** - Clé API absente, invalide ou expirée
  • **403 Forbidden** - Scope insuffisant pour cette action
  • **404 Not Found** - Ressource introuvable dans ce workspace
  • **409 Conflict** - Conflit d'idempotence (payload différent pour même clé)
  • **422 Unprocessable Entity** - Validation métier échouée
  • **429 Too Many Requests** - Rate limit dépassé (voir header `Retry-After`)
  • **500 Internal Server Error** - Erreur Coffrify, réessayez avec backoff exponential

Idempotence

Les requêtes `POST` acceptent un header `Idempotency-Key` (UUID v4 recommandé). Une même clé retourne la réponse initiale sans créer de doublon - utile après un timeout réseau.

POST /v1/transfers
Authorization: Bearer cof_live_sk_...
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
Content-Type: application/json
TTL des clés d'idempotence

Les clés d'idempotence sont conservées **24 heures**. Au-delà, la même clé crée une nouvelle ressource.

Stratégie de retry

Réessayez uniquement sur **429** et **5xx**. Ne réessayez pas sur 4xx (erreurs client permanentes).

retry.tstypescript
async function withRetry<T>(fn: () => Promise<T>, maxAttempts = 3): Promise<T> {
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    try {
      return await fn();
    } catch (err) {
      const status = err?.status ?? 0;
      if (attempt === maxAttempts || (status >= 400 && status < 500 && status !== 429)) throw err;
      await new Promise(r => setTimeout(r, 2 ** attempt * 100)); // 200ms, 400ms, 800ms
    }
  }
  throw new Error('unreachable');
}