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/jsonTTL 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');
}