Aller au contenu

Enveloppes et destinataires

Une enveloppe est un contrat en voie d’être signé : une version de modèle générée avec vos variables, les destinataires qui doivent y agir et les preuves 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 fixée à la création. Doit être publiée
variables objet Validé selon le 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 courriels 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 à ce moment, et les liens de signature et d’observateur cessent de fonctionner
cc tableau Destinataires en copie conforme supplémentaires (name, email), en plus des rôles CC 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 d’état. false par défaut (état seulement); forfait Team et supérieurs
reminders objet { "enabled": false } désactive les rappels; { "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 qui porte cet externalId au lieu d’en créer une autre
metadata objet de chaînes Jusqu’à 500 caractères par valeur; renvoyé avec l’enveloppe et dans les webhooks

Chaque destinataire doit correspondre à un rôle de la version; chaque rôle autre que CC doit avoir exactement un destinataire. Les erreurs sont signalées toutes ensemble, avec des pointeurs comme /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 quand dedupeOn a trouvé une correspondance; 200 avec un résumé de simulation pour ?dry_run=true; 402 quand un espace de travail Free a utilisé ses enveloppes incluses; 403 plan-upgrade-required quand le nombre d’observateurs dépasse ce que permet le 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 qui ont le même numéro signent en même temps. Sans cette valeur, l’order du rôle défini dans le modèle s’applique. Les ordres sont des entiers positifs; les rôles CC ne peuvent pas être ordonnés; chaque rôle a toujours besoin de son destinataire (pour que les champs du modèle gardent leur signataire); au moins un destinataire doit signer. L’événement envelope.created enregistre routingOverridden: true.
  • CC : les destinataires en copie conforme supplémentaires reçoivent le courriel du document finalisé et ne signent jamais. Ils figurent dans recipients avec kind: "cc" et le rôle _cc.
  • Rappels : la personne dont c’est le tour reçoit un rappel toutes les intervalHours heures (par défaut : la valeur REMINDER_INTERVAL_HOURS du déploiement, soit 72), au plus trois fois; enabled: false n’en envoie aucun. Les rappels s’appliquent à la livraison email.
  • L’authentification du signataire se définit par destinataire : verification remplace la méthode du rôle. none (le lien de signature unique seul, la valeur par défaut des rôles qui n’en définissent pas) et email_otp (le lien plus un code envoyé par courriel) sont offerts dès maintenant; passkey et id_check sont refusés, car ils ne sont pas encore offerts. Consultez la section sur la vérification du signataire.
  • Langue : locale sur un destinataire, une copie conforme ou un observateur (ou sur l’enveloppe, pour tous ceux qui n’ont pas la leur) définit la langue de leur page de signature et de leurs courriels, parmi les 50 langues de signature. Sans cette valeur, la page de signature suit la langue du navigateur et les courriels sont en anglais.

L’écran d’envoi du tableau de bord offre les mêmes options : avancer ou reculer des étapes, cocher Signer en même temps, ajouter des copies conformes et des observateurs, choisir l’authentification (Lien par courriel seulement ou Lien par courriel + code) et la langue de chaque signataire, et définir une date d’expiration et un calendrier de rappels.

  • email : chaque destinataire reçoit par courriel un lien vers la page de signature hébergée quand vient son tour. Les destinataires qui n’ont pas signé reçoivent un rappel tous les quelques jours (jusqu’à trois), et tout le monde reçoit un courriel quand l’enveloppe est finalisée.
  • embedded : aucun courriel aux signataires. Créez une session de signature quand le signataire se trouve dans votre produit. Les observateurs reçoivent quand même leur lien d’état par courriel.
  • none : aucun courriel du tout (y compris aux observateurs); utilisez ce mode quand vous livrez les liens vous-même (sessions hébergées).

POST /v1/envelopes/{id}/recipients/{recipient}/resend envoie par courriel un nouveau lien au destinataire dont c’est le tour (au plus 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 selon 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 La date expiresAt est passée 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 immédiatement 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 est pending (ce n’est pas encore son tour), sent, viewed, completed ou declined, et son kind est celui du rôle : signer, approver, form_filler ou cc. L’acheminement suit l’order (celui du rôle, ou la modification à l’envoi) : tous les destinataires du plus petit ordre non terminé agissent en parallèle, et le groupe suivant commence quand ils ont terminé. Les destinataires en copie conforme ne bloquent jamais l’acheminement.

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

  • Quand l’enveloppe est envoyée (ou quand vous les ajoutez plus tard avec POST /v1/envelopes/{id}/viewers), chaque observateur reçoit un courriel à l’image de votre marque avec un lien vers une page d’état en lecture seule : le titre de l’enveloppe, l’expéditeur, chaque étape avec le nom, le rôle, l’état et l’horodatage de ses destinataires, mis à jour en direct au fil des signatures. Les adresses courriel des destinataires ne sont pas affichées.
  • Les observateurs reçoivent un nouveau courriel quand l’enveloppe est finalisée, refusée ou annulée, et 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 que l’enveloppe est en cours, le PDF scellé une fois celle-ci scellée. 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 : le lien suffit à donner accès. Seul un SHA-256 de chaque jeton de lien est stocké. Un lien fonctionne jusqu’à l’expiration de l’enveloppe (90 jours au plus), pendant 30 jours après que l’enveloppe a pris fin, et plus jamais une fois l’observateur révoqué.
  • L’ajout, la consultation (première ouverture 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 dans le certificat.

Les réponses portant sur une seule enveloppe (création, lecture, annulation) en dressent la liste :

{
"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 conforme ne comptent pas. Les observateurs révoqués libèrent leur 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é à la fin, horodatage du 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 }
}

En plus des 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 quand 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 est le seq; reconnectez-vous avec Last-Event-ID pour reprendre.

GET /v1/envelopes filtre par status, seal, template et q (texte libre sur le nom et le courriel 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 comme valeur de cursor; limit va de 1 à 100 (20 par défaut).