Aller au contenu

Enveloppes et destinataires

Une enveloppe est un contrat en route vers sa signature : une version de modèle générée avec vos variables, les destinataires qui interviennent dessus et la preuve de tout ce qui se passe. Créez-en une avec POST /v1/envelopes.

Champ Type Remarques
template tpl_… Obligatoire
version nombre ou "latest" latest par défaut ; résolue et figée à la création. Doit être publiée
variables objet Validées par rapport au JSON Schema de la version
recipients tableau Un par rôle (role, name, email ; facultatifs : externalUserId, verification, fields pour préremplir par identifiant de champ, order pour modifier l’ordre de signature)
subject, message chaîne Utilisés dans les e-mails de signature et affichés sur la page de signature
delivery email · embedded · none email par défaut
expiresAt RFC 3339 Doit être dans le futur ; l’enveloppe expire à cette date, et les liens de signature et d’observateur cessent de fonctionner
cc tableau Destinataires en copie supplémentaires (name, email) en plus des rôles en copie du modèle ; jusqu’à 50
viewers tableau Personnes qui suivent l’enveloppe sans signer (name, email, notifyOnSignature facultatif) ; nombre limité par enveloppe selon le forfait
viewerDocumentAccess booléen Permet aux observateurs d’ouvrir le document sur leur page de suivi. false par défaut (état uniquement) ; forfait Team et supérieurs
reminders objet { "enabled": false } désactive les relances ; { "enabled": true, "intervalHours": 24 } modifie l’intervalle (de 1 à 720)
externalId chaîne Votre propre identifiant, jusqu’à 200 caractères
dedupeOn "external_id" Renvoie l’enveloppe existante portant cet externalId au lieu d’en créer une autre
metadata objet de chaînes Jusqu’à 500 caractères par valeur ; renvoyées avec l’enveloppe et dans les webhooks

Chaque destinataire doit correspondre à un rôle de la version ; chaque rôle hors copie doit avoir exactement un destinataire. Les erreurs sont signalées ensemble, avec des pointeurs tels que /recipients/1/role ou /recipients/0/fields/start_date.

Réponses : 201 avec l’enveloppe et un en-tête Location ; 200 avec l’enveloppe existante et x-deduplicated: true lorsque dedupeOn a trouvé une correspondance ; 200 avec un résumé de simulation pour ?dry_run=true ; 402 lorsqu’un espace de travail Free a épuisé ses enveloppes incluses ; 403 plan-upgrade-required lorsque les observateurs dépassent le quota du forfait ou que viewerDocumentAccess n’est pas inclus dans le forfait (Forfaits et limites). Les simulations vérifient aussi les limites du forfait.

Tous les champs ajoutés après la première version sont facultatifs : une requête qui ne les contient pas se comporte exactement comme avant.

Le modèle définit qui signe et dans quel ordre. Pour une enveloppe donnée, vous pouvez modifier cela sans toucher au modèle :

{
"template": "tpl_9fK2mQ7xLp",
"variables": { "client": { "name": "Jane Doe" } },
"recipients": [
{ "role": "client", "name": "Jane Doe", "email": "jane@acme.dev", "order": 2 },
{ "role": "company", "name": "Sam Lee", "email": "sam@bonafide.dev", "order": 1 },
{ "role": "witness", "name": "Kim Park", "email": "kim@acme.dev", "order": 1 }
],
"cc": [{ "name": "Legal", "email": "legal@acme.dev" }],
"viewers": [{ "name": "Alex Chen", "email": "alex@acme.dev", "notifyOnSignature": true }],
"reminders": { "enabled": true, "intervalHours": 48 },
"expiresAt": "2026-11-30T23:59:59Z"
}
  • Ordre : recipients[].order est l’étape à laquelle le destinataire signe ; les destinataires portant le même numéro signent en même temps. À défaut, c’est l’order du rôle défini dans le modèle qui s’applique. Les ordres sont des entiers positifs ; les rôles en copie ne peuvent pas être ordonnés ; chaque rôle doit toujours avoir son destinataire (pour que les champs du modèle conservent leur signataire) ; au moins un destinataire doit signer. L’événement envelope.created enregistre routingOverridden: true.
  • Copie : les destinataires en copie supplémentaires reçoivent l’e-mail contenant le document finalisé et ne signent jamais. Ils apparaissent dans recipients avec kind: "cc" et le rôle _cc.
  • Relances : la personne dont c’est le tour est relancée toutes les intervalHours heures (par défaut : la valeur REMINDER_INTERVAL_HOURS du déploiement, soit 72), trois fois au maximum ; enabled: false n’en envoie aucune. Les relances s’appliquent à la remise par email.
  • L’authentification du signataire se définit par destinataire : verification remplace la méthode du rôle. Sont disponibles aujourd’hui none (le lien de signature unique seul, valeur par défaut des rôles qui n’en définissent pas) et email_otp (le lien plus un code envoyé par e-mail) ; passkey et id_check sont refusés car pas encore disponibles. Consultez Vérification du signataire.
  • Langue : locale sur un destinataire, une copie ou un observateur (ou sur l’enveloppe, pour tous ceux qui n’en ont pas) définit la langue de sa page de signature et de ses e-mails, parmi les 50 langues de signature. À défaut, la page de signature suit le navigateur et les e-mails sont en anglais.

L’écran d’envoi du tableau de bord propose les mêmes options : avancer ou reculer des étapes, cocher Signer en même temps, ajouter des copies et des observateurs, choisir l’authentification de chaque signataire (Lien par e-mail uniquement ou Lien par e-mail + code) et sa langue, et définir une date d’expiration et un calendrier de relances.

  • email : chaque destinataire reçoit par e-mail un lien vers la page de signature hébergée quand vient son tour. Les destinataires qui n’ont pas signé sont relancés tous les quelques jours (trois fois au maximum), et tout le monde reçoit un e-mail lorsque l’enveloppe est finalisée.
  • embedded : aucun e-mail aux signataires. Créez une session de signature lorsque le signataire se trouve dans votre produit. Les observateurs reçoivent toujours leur lien de suivi par e-mail.
  • none : aucun e-mail (observateurs compris) ; à utiliser lorsque vous remettez vous-même les liens (sessions hébergées).

POST /v1/envelopes/{id}/recipients/{recipient}/resend envoie par e-mail un nouveau lien au destinataire dont c’est le tour (au maximum une fois par minute).

┌──────────── declined (a signer declined)
│
sent ─────┼──────────── voided (POST /v1/envelopes/{id}/void)
│
├──────────── expired (expiresAt passed)
│
└──────────── completed ──► seal: pending ──► sealed
status Signification
rendering En préparation
sent En cours : les destinataires signent dans l’ordre d’acheminement
completed Tous les destinataires ont terminé. Le scellement commence
declined Un destinataire a refusé ; l’enveloppe prend fin
voided Vous l’avez annulée ({ "reason": "…" }) ; les sessions de signature ouvertes cessent de fonctionner
expired expiresAt est dépassé avant la finalisation

seal suit l’état du PDF scellé : not_started, pending (finalisée, en cours de scellement), sealed ou failed. Le scellement ne bloque jamais la finalisation : l’enveloppe est d’abord finalisée, puis scellée juste après.

{
"id": "rcp_5Jw0pLs9Xe",
"role": "client",
"name": "Jane Doe",
"email": "jane@acme.dev",
"order": 1,
"status": "viewed",
"verification": "email_otp",
"completedAt": null
}

Le status d’un destinataire vaut pending (ce n’est pas encore son tour), sent, viewed, completed ou declined, et kind correspond au type du rôle : signer, approver, form_filler ou cc. L’acheminement suit l’order (celui du rôle, ou celui défini par les options d’envoi) : tous les destinataires du plus petit ordre non terminé agissent en parallèle, et le groupe suivant commence lorsqu’ils ont terminé. Les destinataires en copie ne bloquent jamais l’acheminement.

Un observateur suit une enveloppe sans signer : un responsable, un juriste, le gestionnaire du compte côté client. Les observateurs ne sont pas des destinataires. Ils n’ont ni rôle ni tour, ne bloquent ni ne finalisent jamais rien et n’apparaissent jamais dans la liste des signataires du certificat.

  • Lorsque l’enveloppe est envoyée (ou lorsque vous les ajoutez plus tard avec POST /v1/envelopes/{id}/viewers), chaque observateur reçoit un e-mail à vos couleurs avec un lien vers une page de suivi en lecture seule : le titre de l’enveloppe, l’expéditeur, chaque étape avec le nom, le rôle, l’état et les horodatages de ses destinataires, mis à jour en direct au fil des signatures. Les adresses e-mail des destinataires ne sont pas affichées.
  • Les observateurs reçoivent un nouvel e-mail lorsque l’enveloppe est finalisée, refusée ou annulée, ainsi qu’après chaque signature si notifyOnSignature vaut true (désactivé par défaut).
  • Le document ne figure sur la page que si vous définissez viewerDocumentAccess: true (forfait Team et supérieurs) : l’original pendant le processus, le PDF scellé une fois scellé. Sinon, les observateurs ne voient que l’état.
  • DELETE /v1/envelopes/{id}/viewers/{viewer} révoque un observateur : tous les liens qui lui ont été envoyés cessent immédiatement de fonctionner.
  • Les liens sont des URL de capacité personnelles. Seul un SHA-256 de chaque jeton de lien est stocké. Un lien fonctionne jusqu’à l’expiration de l’enveloppe (90 jours au maximum), pendant 30 jours après la fin de l’enveloppe, et plus jamais une fois l’observateur révoqué.
  • L’ajout, l’ouverture (première consultation de la page et du document) et la révocation sont consignés dans la piste d’audit sous viewer.added, viewer.viewed, viewer.document_viewed et viewer.revoked, et donc sur le certificat.

Les réponses portant sur une seule enveloppe (création, lecture, annulation) les listent :

{
"viewers": [
{
"id": "vwr_2Hc8sQ1nVt",
"name": "Alex Chen",
"email": "alex@acme.dev",
"notifyOnSignature": true,
"status": "active",
"invitedAt": "2026-10-13T13:58:04.512Z",
"firstViewedAt": "2026-10-13T14:05:41.090Z",
"lastViewedAt": "2026-10-13T15:12:09.337Z",
"revokedAt": null,
"createdAt": "2026-10-13T13:58:04.512Z"
}
],
"viewerDocumentAccess": false
}

Le nombre d’observateurs par enveloppe dépend du forfait (Free 1, Pay-as-you-go 2, Team 5, Business 20, Platform illimité) ; les destinataires en copie ne sont pas comptés. Un observateur révoqué libère sa place.

GET /v1/envelopes/{id}/document?version=… télécharge un PDF, avec son SHA-256 dans x-document-sha256 :

version Fichier
original (par défaut) Le document généré, tel qu’envoyé pour signature
sealed Le PDF final : valeurs aplaties, certificat de finalisation ajouté, horodatage de document. Après envelope.sealed
certificate Le certificat de finalisation seul

Le documentHash de l’enveloppe est le SHA-256 de l’original et sealedDocumentHash celui du fichier scellé ; ce sont ces valeurs que la vérification recherche.

Chaque action est un événement d’une chaîne de hachage propre à l’enveloppe : hash = SHA-256(prevHash ‖ canonical JSON of the event), le premier prevHash étant composé de 64 zéros. GET /v1/envelopes/{id}/events renvoie les événements et vérifie la chaîne :

{
"data": [
{
"id": "evt_…",
"envelope": "env_8Gm2kQ4rT1",
"seq": 1,
"type": "envelope.created",
"createdAt": "2026-10-13T13:58:04.512Z",
"recipient": null,
"actor": { "kind": "api_key", "id": "…", "name": null, "email": null },
"ip": "203.0.113.7",
"userAgent": null,
"data": { "template": "tpl_…", "templateVersion": 3, "documentHash": "9f2c…" },
"hash": "4b1d…",
"prevHash": "0000000000000000000000000000000000000000000000000000000000000000"
}
],
"chain": { "valid": true, "brokenAt": null }
}

Outre les types d’événements de webhook, la piste comporte des entrées propres à l’audit, comme session.created, recipient.verified, recipient.reminded et les événements des observateurs (type d’acteur viewer lorsqu’un observateur ouvre sa page).

Pour afficher l’état en direct dans une interface, GET /v1/envelopes/{id}/events/stream est un flux d’événements envoyés par le serveur (SSE) : le nom d’événement de chaque trame est le type de l’événement et son identifiant le seq ; reconnectez-vous avec Last-Event-ID pour reprendre.

GET /v1/envelopes filtre par status, seal, template et q (texte libre portant sur les noms et adresses e-mail des destinataires, l’externalId et l’identifiant de l’enveloppe). Comme toutes les listes, elle est paginée par curseur :

{ "data": [ … ], "hasMore": true, "nextCursor": "…" }

Renvoyez nextCursor dans cursor ; limit va de 1 à 100 (20 par défaut).