Transferts·Intermédiaire·10 min

Implémenter un workflow d'approbation de transfert

Apprenez à mettre en place un circuit de validation complet pour vos transferts Coffrify : ajout d'approbateurs, décision approuvé/rejeté et propagation automatique du statut.

Télécharger en PDF

Certains transferts sensibles exigent qu'un collaborateur (ou une équipe) valide explicitement leur mise à disposition avant que les destinataires puissent télécharger les fichiers. L'API Coffrify expose trois endpoints complémentaires pour couvrir ce besoin : ajout d'approbateurs sur un transfert existant, décision directe (approuvé ou rejeté) sur le transfert lui-même, et gouvernance unifiée via la table coffrify_approval_requests qui applique le four-eyes principle et tient un journal d'audit signé. Ce guide parcourt le flux de bout en bout, des prérequis jusqu'à la gestion des cas d'erreur.

GET/v1/transfers/{id}/approversListe les approbateurs enregistrés pour un transfert donné.POST/v1/transfers/{id}/approversAjoute un approbateur au transfert et déclenche l'envoi d'un e-mail de notification avec des liens de décision en un clic.POST/v1/transfers/{id}/approveApprouve ou rejette directement un transfert dont approval_required est true. Met à jour approval_status, approved_at et notifie le propriétaire du transfert.
POST/v1/approvalsCrée une demande d'approbation gouvernée (four-eyes, owner-exempt, audit). Retourne la demande existante si un doublon pending existe déjà pour le même triplet (workspace, type, resource_id).
PATCH/v1/approvals/{id}/decideTranche une demande pending (approve ou reject) avec vérification four-eyes, enregistrement d'audit et propagation automatique sur le transfert associé.

Authentification et scopes requis

Les endpoints /v1/transfers/{id}/approvers et /v1/transfers/{id}/approve requièrent le scope transfers:manage. Les endpoints /v1/approvals (GET, POST) et /v1/approvals/{id}/decide requièrent le scope workspace:manage. Transmettez votre clé dans l'en-tête Authorization: Bearer <clé>. En sandbox utilisez un préfixe cof_test_…, en production cof_live_….

Corps des requêtes

POST /v1/transfers/{id}/approvers : ajout d'un approbateur.

ChampTypeRequisDescription
approver_emailstringConditionnelAdresse e-mail de l'approbateur. Au moins ce champ ou approver_user_id est obligatoire.
approver_user_idstring (uuid)ConditionnelIdentifiant Coffrify de l'approbateur. Si seul ce champ est fourni, l'e-mail est résolu automatiquement depuis le profil.

POST /v1/transfers/{id}/approve : décision sur le transfert.

ChampTypeRequisDescription
decisionstringOuiValeur acceptée : approved ou rejected.
notestringNonMessage facultatif transmis au propriétaire du transfert et consigné dans approval_note.

POST /v1/approvals : création d'une demande gouvernée.

ChampTypeRequisDescription
typestringOuiType de la demande. Valeurs pour les transferts : transfer ou transfer_approval. Autres valeurs acceptées : capability_grant, workspace_delete, workspace_transfer, account_deletion, custom_domain, api_key_creation, data_export, data_purge, custom.
resource_idstringOuiIdentifiant de la ressource concernée (ex. : l'id du transfert).
reasonstringNonMotif de la demande, affiché aux approbateurs.
sensitivitystringNonNiveau de sensibilité : low, medium (défaut), high ou critical.
expires_atstring (ISO 8601)NonDate d'expiration de la demande. Sans valeur, la demande reste ouverte indéfiniment.
metadataobjectNonDonnées contextuelles libres annexées à la demande.

PATCH /v1/approvals/{id}/decide : décision sur une demande gouvernée.

ChampTypeRequisDescription
decisionstringOuiValeur acceptée : approve ou reject.
decision_reasonstringConditionnelObligatoire lorsque decision vaut reject. Motif du refus consigné dans decision_note.
notestringNonAlias legacy de decision_reason, accepté en parallèle pour la rétrocompatibilité.

Flux complet : ajout d'approbateur puis décision

# 1. Ajouter un approbateur au transfert
curl -X POST https://api.coffrify.com/v1/transfers/tr_01J9XKZ.../approvers \
-H "Authorization: Bearer cof_live_..." \
-H "Content-Type: application/json" \
-d '{"approver_email": "responsable@exemple.fr"}'
 
# 2. Décider directement sur le transfert (scope transfers:manage)
curl -X POST https://api.coffrify.com/v1/transfers/tr_01J9XKZ.../approve \
-H "Authorization: Bearer cof_live_..." \
-H "Content-Type: application/json" \
-d '{"decision": "approved", "note": "Validé après vérification des pièces jointes."}'
 
# 3. (Alternatif) Créer une demande gouvernée, puis la trancher
curl -X POST https://api.coffrify.com/v1/approvals \
-H "Authorization: Bearer cof_live_..." \
-H "Content-Type: application/json" \
-d '{"type": "transfer_approval", "resource_id": "tr_01J9XKZ...", "sensitivity": "high", "reason": "Transfert M&A confidentiel"}'
 
curl -X PATCH https://api.coffrify.com/v1/approvals/apr_01JA.../decide \
-H "Authorization: Bearer cof_live_..." \
-H "Content-Type: application/json" \
-d '{"decision": "approve", "decision_reason": "Conforme au protocole M&A."}'

Réponses types

Réponse de POST /v1/transfers/{id}/approvers (HTTP 200) : objet approbateur créé avec decision pending.

{
"id": "apv_01JA7MN...",
"transfer_id": "tr_01J9XKZ...",
"workspace_id": "ws_01J8...",
"approver_user_id": null,
"approver_email": "responsable@exemple.fr",
"decision": "pending",
"decided_at": null,
"note": null,
"notified_at": "2026-06-06T09:12:00.000Z",
"created_at": "2026-06-06T09:12:00.000Z"
}

Réponse de POST /v1/transfers/{id}/approve (HTTP 200) : objet transfert complet avec les champs d'approbation mis à jour.

{
"id": "tr_01J9XKZ...",
"short_code": "abc12",
"transfer_title": "Dossier M&A Q2 2026",
"workspace_id": "ws_01J8...",
"approval_required": true,
"approval_status": "approved",
"approved_at": "2026-06-06T09:15:22.000Z",
"approved_by": "usr_01J7...",
"approval_note": "Validé après relecture."
}

Réponse de POST /v1/approvals (HTTP 201) ou PATCH /v1/approvals/{id}/decide (HTTP 200) : objet ApprovalRecord.

{
"id": "apr_01JA8PQ...",
"workspace_id": "ws_01J8...",
"type": "transfer_approval",
"resource_id": "tr_01J9XKZ...",
"requested_by": "usr_01J6...",
"decided_by": "usr_01J7...",
"status": "approved",
"sensitivity": "high",
"reason": "Transfert M&A confidentiel",
"decision_note": "Conforme au protocole.",
"requested_at": "2026-06-06T09:00:00.000Z",
"decided_at": "2026-06-06T09:20:00.000Z",
"expires_at": null,
"metadata": {},
"created_at": "2026-06-06T09:00:00.000Z"
}

Erreurs

Code HTTPCode APIQuandRésolution
400validation_errordecision absent ou invalide (approved/rejected attendu sur /approve, approve/reject attendu sur /decide)Vérifiez la valeur exacte du champ decision.
400validation_errorni approver_email ni approver_user_id fourni sur POST /approversPassez au moins l'un des deux champs.
400validation_errortype ou resource_id manquant sur POST /approvalsLes deux champs sont obligatoires.
400validation_errorsensitivity hors de la liste (low, medium, high, critical)Utilisez l'une des quatre valeurs autorisées.
400validation_errorClé API sans contexte utilisateur pour POST /approvals ou /decideUtilisez une clé associée à un utilisateur (OAuth ou session).
403forbiddenself_approval_forbidden : le demandeur tente d'approuver sa propre demande (four-eyes principle)Faites appel à un autre utilisateur du workspace pour la décision.
403forbiddenowner_exempt : la demande a été émise par le propriétaire du workspaceLe propriétaire est souverain, aucune approbation tierce n'est requise.
404not_foundTransfer ou demande introuvable dans le workspace courantVérifiez l'identifiant et que la clé appartient au bon workspace.
409conflictalready_decided : la demande a déjà un statut différent de pendingConsultez l'objet retourné pour connaître la décision déjà enregistrée.
409conflictduplicate_pending : une demande pending existe déjà pour le même triplet (workspace, type, resource_id)L'API retourne la demande existante de façon idempotente.
422validation_errorLe transfert ne possède pas approval_required = true sur POST /approveActivez l'option d'approbation sur le transfert avant d'appeler cet endpoint.
500internal_errorErreur de base de données inattendueRéessayez après quelques secondes. Contactez le support si le problème persiste.

Voir aussi

  • Créer et envoyer un transfert
  • Lister et filtrer les transferts
  • Gérer les membres et permissions d'un workspace
  • Référence : POST /v1/transfers/{id}/approve
  • Référence : POST /v1/transfers/{id}/approvers
  • Référence : POST /v1/approvals
  • Référence : PATCH /v1/approvals/{id}/decide
Continuer

Autres tutoriels à suivre