Des events signés HMAC-SHA256.
74 events temps réel sur 18 familles. Signature horodatée, renvois avec backoff exponentiel, file d'attente morte, debug intégré dans la console.
Anatomie d'un event
Chaque livraison est une requête POST HTTPS vers votre endpoint avec un corps JSON et trois en-têtes signés.
x-coffrify-signature: t=…,v1=… horodaté (pas de rejeu) et x-coffrify-id unique par livraison.type, created, data (l'objet concerné) et workspace_id.2xx en moins de 5 s. Tout statut hors 2xx déclenche un renvoi. Traitez en asynchrone si votre logique métier est longue.{ "id": "evt_8K2nQ9xLpVwR", "type": "transfer.downloaded", "created": "2026-06-04T10:21:00Z", "workspace_id": "ws_abc", "data": { "id": "tr_8f2a90" } }
Vérifier la signature HMAC
Coffrify signe chaque payload avec votre SIGNING_KEY (HMAC-SHA256). Vérifiez la signature avant de traiter l'event pour éviter les usurpations.
const crypto = require('crypto'); const SIGNING_KEY = process.env.COFFRIFY_SIGNING_KEY; function verify(req) { const sig = req.headers['x-coffrify-signature']; const [t, v1] = sig.split(','); const expected = crypto.createHmac('sha256', SIGNING_KEY) .update(t + '.' + JSON.stringify(req.body)).digest('hex'); return crypto.timingSafeEqual( Buffer.from(v1, 'hex'), Buffer.from(expected, 'hex')); }
Rejetez les payloads avec t trop ancien (5 min par défaut). Le timestamp empêche le rejeu d'un payload déjà livré.
Pendant une rotation, deux secrets coexistent jusqu'à 7 jours. x-coffrify-signature peut contenir v1=…,v1=…, validez si une des deux passe.
74 events sur 18 familles
Le catalogue complet. Cliquez une famille pour voir le nom de chaque event et sa description courte. Certains nécessitent un plan minimum, indiqué à droite.
transfer.createdA new transfer was created.transfer.downloadedRecipient successfully fetched download URLs.transfer.expiredTransfer reached expires_at.transfer.deletedOwner deleted the transfer or burn-after-read consumed it.transfer.clonedAn expired transfer was re-issued via clone.transfer.renamedTransfer title was updated by the owner.transfer.settings_changedPassword, expiry, or max_downloads settings were modified.transfer.scannedAntivirus scan job finished (neutral; use scan_clean/infected/quarantined for typed handlers).transfer.scan_cleanScan completed with no threats found.protransfer.scan_infectedScan detected malware. Files quarantined.protransfer.scan_quarantinedScan returned a suspicious verdict.protransfer.limit_reachedLast allowed download was consumed.transfer.password_failedAn incorrect password was submitted for a protected transfer.transfer.geo_blockedDownload blocked by geo policy.ultratransfer.preview_openedRecipient opened the preview modal for a file.transfer.email_sentOwner sent the transfer URL via the built-in email feature.transfer.e2e_createdA new E2E (zero-knowledge) transfer was created.
Chaque livraison a un identifiant unique
En cas de renvoi, le même x-coffrify-id revient. Stockez-le côté serveur pour ignorer les doublons et garantir un traitement strictement une-fois.
const id = req.headers['x-coffrify-id']; if (await alreadyProcessed(id)) return res.status(200).end(); await processEvent(req.body); await markProcessed(id, ttl: 7 * 24 * 3600); res.status(200).end();
Stratégie de renvoi
En cas d'échec (non-2xx ou timeout), Coffrify réessaie avec un backoff exponentiel avant de placer la livraison en file morte (DLQ) rejouable depuis la console.