Créer le workflow

Afficher en MarkdownOuvrir dans Claude

Parapheurs (workflows)

Qu’est-ce qu’un parapheur ?

Un parapheur (workflow) est un processus de signature et/ou de validation. Il est créé sous un utilisateur — son gestionnaire — et porte un identifiant wfl_.

Un parapheur est composé d’étapes (steps), jouées séquentiellement. Chaque étape réunit un ou plusieurs destinataires (recipients) qui agissent, eux, en parallèle. C’est la combinaison des deux qui décrit l’ordre des signatures :

  • plusieurs destinataires dans une même étape → ils signent/valident en parallèle ;
  • plusieurs étapes successives → elles s’enchaînent dans l’ordre (séquentiel).

Structure d’ensemble — chaque niveau porte ses propres champs :

Parapheur (wfl_) ← niveau 1 : le parapheur (section [*Le parapheur — champs de premier niveau (niveau 1)*](#le-parapheur-champs-de-premier-niveau-niveau-1))
├─ champs propres : name, description, workflowMode, notifiedEvents,
│ allowConsolidation, layoutId + data1…16, templateId
├─ steps[] ← niveau 2 : les étapes, séquentielles (section [*Les étapes — steps (niveau 2)*](#les-etapes-steps-niveau-2))
│ ├─ champs propres : stepType, requiredRecipients, validityPeriod,
│ │ invitePeriod, maxInvites, sendDownloadLink,
│ │ hideAttachments, faceToFaceSignature…
│ │
│ └─ recipients[] ← niveau 3 : les destinataires, en parallèle (section [*Les destinataires — recipients (niveau 3)*](#les-destinataires-recipients-niveau-3))
│ └─ champs propres : consentPageId, userId | contactId | (email+nom),
│ phoneNumber, country, organizationId, preferredLocale
└─ watchers[] ← niveau 4 : les observateurs, au niveau du parapheur (section [*Les observateurs — watchers (niveau 4) & les notifications*](#les-observateurs-watchers-niveau-4-les-notifications))
userId (utilisateur) | email (contact)

Deux modes existent :

  • FULL (par défaut) — toutes les possibilités : plusieurs étapes, observateurs, consolidation, création depuis un modèle…
  • SINGLE_SIGNER — un parapheur à une seule étape (le plus simple).

Remarque importante : le mode SINGLE_SIGNER (“signataire unique”) permet en particulier de construire un parapheur avec des champs dynamiques qui sont à compléter par le signataire avant la signature. Cette fonctionnalité est prise en charge par le Workflow Manager mais pas par l’Evidence Manager et donc le processus de saisie de ces informations n’est pas géré par le fichier de preuve.

Du fait que son intérêt est surtout de permettre à un gestionnaire de parapheur d’autoriser une saisie préalable afin de faire compléter un ou plusieurs documents par le signataire avant sa signature, il est important de noter que dès lors qu’un développeur s’appuie sur l’API, il est préférable de faire effectuer cette saisie ainsi que tous ses contrôles associés par l’application métier. À noter d’ailleurs qu’aucun contrôle n’est effectué par le Workflow Manager sur les champs de saisie qui sont uniquement du texte libre. Par conséquent le mode SINGLE_SIGNER n’est pas abordé plus avant dans cette documentation. On précise également que le mode signataire unique peut être désactivé au niveau du tenant.

Créer un parapheur (à l’état brouillon)

POST /api/users/{userId}/workflows
Authorization: Bearer act_<id>.<secret>
Content-Type: application/json
{
"name": "Attestation d'emprunt de matériel",
"workflowMode": "FULL",
"notifiedEvents": [ "recipientFinished", "workflowStopped", "workflowFinished" ],
"steps": [
{
"stepType": "signature",
"requiredRecipients": 1,
"recipients": [ { "consentPageId": "cop_…", "userId": "usr_…" } ]
}
]
}

Le parapheur est rattaché au gestionnaire ({userId} dans l’URL) et créé à l’état brouillon : rien n’est envoyé tant qu’il n’est pas lancé (section Cycle de vie & statuts). L’appel s’authentifie avec un jeton d’API dont l’utilisateur a le droit de créer des parapheurs (fondation Groupes, rôles & droits).

Le corps reflète les niveaux ci-dessus : les champs propres du parapheur, le tableau steps[] (chaque étape contenant ses recipients[]) et, le cas échéant, watchers[]. Les quatre sections suivantes détaillent chacun de ces niveaux.

Le parapheur — champs de premier niveau (niveau 1)

ChampRôle
nameNom du parapheur (requis).
descriptionDescription (facultative). À noter que la description s’affiche au destinataire lors du processus de signature ou de validation.
workflowModeFULL (défaut) ou SINGLE_SIGNER. Voir la remarque du section Qu’est-ce qu’un parapheur ?.
notifiedEventsÉvénements dont le gestionnaire est notifié (section Les observateurs — watchers (niveau 4) & les notifications).
allowConsolidationAutoriser la consolidation. (Null en SINGLE_SIGNER). Ce champ autorise le destinataire à signer, en un seul processus d’authentification, tous les parapheurs pour lesquels la consolidation est activée, sous réserve que le mode d’authentification soit identique.
layoutId, data1data16Disposition de métadonnées (layoutId) et ses valeurs (data1data16) — voir la fondation Métadonnées.
templateIdCréer à partir d’un modèle. (Null en SINGLE_SIGNER). Il est déconseillé d’utiliser un modèle — voir la fondation Positionnement et périmètre.
stepsLes étapes du parapheur — détaillées au section Les étapes — steps (niveau 2). (Une seule autorisée en SINGLE_SIGNER).
watchersLes observateurs du parapheur — détaillés au section Les observateurs — watchers (niveau 4) & les notifications. (Null en SINGLE_SIGNER).

Cogestion. La possibilité de faire cogérer un parapheur par d’autres utilisateurs (champs allowedCoManagerUsers / coManagerNotifiedEvents visibles sur l’objet parapheur) dépend entièrement des modèles : elle n’est disponible que pour un parapheur créé à partir d’un modèle. Les modèles étant hors périmètre d’une utilisation raisonnée de l’API (voir templateId ci-dessus et la fondation Positionnement et périmètre), la cogestion n’est donc pas détaillée ici.

Les étapes — steps (niveau 2)

Les étapes s’enchaînent séquentiellement. Champs propres à chaque étape :

ChampRôle
stepTypesignature ou approval (validation).
requiredRecipientsNombre de destinataires notifiés en parallèle devant signer ou valider pour que l’étape s’achève. C’est un principe appelé « signatures ou validations suffisantes » par Goodflag. Ce principe est intéressant dès lors qu’une notion de “quorum” est présente.
validityPeriodDurée de validité de l’étape, en ms (min 1 jour, max ≈ 99 jours).
invitePeriodDélai de relance des invitations, en ms (min 1 jour, max 30 jours).
maxInvitesNombre maximum d’invitations envoyées (0 à 99). Attention : en mettant 0, le destinataire ne sera jamais invité à signer / valider.
sendDownloadLinkEnvoyer au(x) destinataire(s) un lien de téléchargement des documents signés en fin de parapheur.
hideAttachmentsCacher l’ensemble des pièces jointes au(x) signataire(s) ou validateur(s) de l’étape.
viewConfidentialAttachmentsAfficher les pièces jointes marquées confidentielles au(x) signataire(s) ou validateur(s) de l’étape.
hideWorkflowRecipientsMasquer au(x) destinataire(s) de l’étape les autres destinataires.
requireSupportingDocuments / supportingDocumentsListExiger des pièces justificatives (liste, 5 max). Les pièces justificatives ne sont pas signées.
allowCommentsAutoriser les commentaires sur l’étape.
disableMandatoryViewingLever l’obligation pour le(s) destinataire(s) de visualiser le(s) document(s) avant de signer ou valider.
faceToFaceSignatureActiver la signature en face à face (uniquement sur une étape configurée en série), dont la page de consentement est de type OTP mail ou SMS et le signataire est un contact. Cette fonctionnalité n’a de sens qu’en mode interactif via le portail.

(Toutes les durées sont en millisecondes — fondation Structure > Formats de données.)

Les destinataires — recipients (niveau 3)

Les destinataires d’une même étape agissent en parallèle. Chaque destinataire est associé à une page de consentement (consentPageId), qui fixe le choix d’un cachet ou d’une signature des documents et le mode d’authentification du destinataire (fondation Pages de consentement). On l’identifie de l’une des manières suivantes :

Contrairement au comportement du portail, qui permet de créer « à la volée » utilisateurs et/ou contacts lors de la création d’un parapheur, avec l’API, les utilisateurs et/ou contacts désignés doivent exister au préalable : l’API ne les crée pas automatiquement. L’identité en clair reste utilisable, mais elle produit un destinataire ad hoc, propre à ce parapheur : il n’est pas enregistré comme utilisateur ou contact réutilisable. Le détail des règles d’identification (et pourquoi userId est préférable) est traité dans les cas d’usage.

Autres champs propres au destinataire, utiles voire indispensables :

ChampRôle
consentPageId(requis) Page de consentement : cachet ou signature + mode d’authentification (fondation Pages de consentement).
userId / contactId / email+firstName+lastNameIdentification du destinataire (voir ci-dessus). On rappelle qu’en mode API il est préférable de provisionner les destinataires en tant qu’utilisateurs.
phoneNumberIndispensable pour une signature avancée avec OTP SMS.
countryPour une signature qualifiée ou bien une signature avancée avec vérification de pièce d’identité , le pays de naissance est obligatoire.
organizationIdSigner au nom d’une organisation.
preferredLocaleLangue des e-mails de notification. (La langue de la page de consentement, comme celle du portail, est déterminée par la langue du navigateur.)
Très important : au sein d’une étape, il ne peut y avoir 2 destinataires ayant la même adresse mail.

Les observateurs — watchers (niveau 4) & les notifications

Deux mécanismes de notification, tous deux au niveau du parapheur :

  • notifiedEvents — la liste des événements dont le gestionnaire est notifié.
  • watchers — des observateurs supplémentaires, chacun avec ses propres notifiedEvents. (Null en SINGLE_SIGNER.) Chaque observateur est soit un utilisateur (watchers[].userId), soit un non-utilisateur désigné par son e-mail (watchers[].email). Côté Portail, cela correspond aux deux boutons « Ajouter un observateur » (liste déroulante des utilisateursuserId) et « Ajouter un CC » (liste déroulante des contacts du gestionnaire, ou une adresse e-mail saisie librement). Dans tous les cas, un CC arrive à l’API sous la forme d’un e-mail (watchers[].email) : le champ contactId n’est pas pris en charge pour un watcher (il est ignoré silencieusement, l’observateur n’étant alors pas enregistré).

Les valeurs de notifiedEvents (mêmes valeurs pour le gestionnaire et pour chaque observateur) sont les suivantes :

  • workflowStarted : le parapheur est démarré ;
  • recipientFinished : un destinataire a signé ou validé ;
  • recipientRefused : un destinataire a refusé de signer ou de valider ;
  • workflowStopped : le parapheur est arrêté ;
  • workflowFinished : le parapheur est terminé ;
  • workflowFinishedDownloadLink : le parapheur est terminé et un lien de téléchargement des fichiers signés avec les pièces jointes a été envoyé ;
  • workflowFinishedDownloadLinkNoAttachment : le parapheur est terminé et un lien de téléchargement des fichiers signés sans les pièces jointes à été envoyé ;
  • commentCreated : un commentaire a été déposé (les commentaires peuvent être désactivés au niveau du tenant) ;
  • coManagerAdded : un cogestionnaire a été ajouté au parapheur (s’appuie sur les modèles) ;
  • coManagerRemoved : un cogestionnaire a été retiré du parapheur (s’appuie sur les modèles).

Ce sont les mêmes eventTypes que les webhooks ; la liste exhaustive et la charge utile sont traitées dans la fondation Suivi & webhooks.

Minimiser les e-mails. Pour ne laisser au signataire que l’invitation à signer :

  • mettez notifiedEvents: [] au niveau du parapheur → aucune notification e-mail au gestionnaire (ni « un destinataire a signé », ni « parapheur terminé », etc.) ;
  • n’ajoutez aucun watchers (personne en copie/observateur) ;
  • laissez sendDownloadLink: false au niveau de l’étape → pas d’e-mail de lien de téléchargement du document signé en fin de parapheur.

L’invitation du signataire est, elle, indépendante de notifiedEvents : elle part au lancement et se règle via invitePeriod / maxInvites (section Les étapes — steps (niveau 2)). Pour une invitation unique, sans relance, mettez maxInvites: 1.

Cycle de vie & statuts

Le statut d’un parapheur est porté par workflowStatus. Les valeurs effectivement renvoyées par l’API sont :

workflowStatusLibellé PortailÉtat
draftBrouillonle parapheur existe, mais rien n’est envoyé ; c’est ici qu’on charge les documents et pose les champs de signature (fondation Documents & champs de signature). Tant que le parapheur n’est pas complet (au moins 1 étape de signature et au moins 1 document à signer), le parapheur ne peut être démarré.
startedDémarréla première étape est lancée, les invitations partent, les étapes s’enchaînent.
finishedTerminétoutes les étapes ont été accomplies — mais le parapheur reste modifiable (voir ci-dessous).
stoppedArrêtéle parapheur a été interrompu.
archivedClôturéétat définitif et figé : plus aucune modification n’est possible.

Deux pièges de vocabulaire à connaître.

  • Le Portail affiche « Clôturé », mais la valeur du champ utilisé en mode API est archived (pour raisons historiques : ce statut, d’abord nommé « Archivé », a été renommé « Clôturé » côté Portail lors de l’ajout des connecteurs d’archivage, sans changer la valeur de l’API).
  • closed n’est pas un statut : c’est un horodatage (date de clôture). Le statut d’un parapheur clôturé est bien archived.

Les transitions draftstartedstopped se font par PATCH /api/workflows/{id} avec { "workflowStatus": … } (concurrence optimiste If-Match facultative, fondation Structure > Concurrence : l’en-tête conditionnel If-Match) :

  1. Lancerdraftstarted : la première étape démarre, les premières invitations partent.
  2. Arrêterstartedstopped.
  3. Reprendre un cycle — un parapheur finished ou stopped peut être modifié (par exemple pour ajouter des étapes) puis redémarré. finished n’est donc pas définitif.
  4. Clôturer (finishedarchived) — c’est le seul état définitif (le parapheur est figé). La clôture ne se fait pas par PATCH workflowStatus mais par l’endpoint dédié POST /api/workflows/{id}/archive :
  • archivage local (par défaut) : l’appel suffit ; les documents sont conservés localement dans l’environnement du Workflow Manager ;
  • archivage externe (optionnel) : dépose les documents chez un tiers ; nécessite un archiveur déclaré et l’activation sur le tenant (voir activateExternalArchive + externalArchivingParameters), l’avancement étant suivi via externalArchiveStatus.

La clôture renseigne l’horodatage closed et conditionne la disponibilité définitive du dossier de preuve (voir la fondation Documents signés & preuves).

Horodatages : created, started, stopped, finished, closed. Suivi en cours de déroulé : progress, steps[].isStarted / steps[].isFinished, currentRecipientEmails / currentRecipientUsers (qui doit agir maintenant).

Invitations à signer. L’invitation part automatiquement : au lancement du parapheur (workflowStatus: started) et à la fin de chaque étape intermédiaire. Dans le cas normal, vous n’avez donc rien à appeler ; les relances sont réglées par invitePeriod / maxInvites (section Les étapes — steps (niveau 2)). Deux endpoints permettent d’intervenir sur l’invitation — POST /api/workflows/{id}/invite (obtenir le lien) et POST /api/workflows/{id}/sendInvite (renvoyer le message de la plateforme) — mais ils répondent à des besoins distincts, détaillés juste après. Tous deux exigent un corps { "recipientEmail": … } identifiant le destinataire et renvoient l’inviteUrlomettre ce corps provoque une erreur HTTP 500. Leurs erreurs métier renseignent sur les conditions : InvalidWorkflowStatus (le statut du parapheur n’autorise pas l’opération, par exemple parce qu’un administrateur ou un cogestionnaire a clôturé le parapheur entre temps), WorkflowNotFound, RecipientNotFound, et — pour sendInviteInviteAlreadySent.

Deux endpoints, deux usages sans rapport entre eux.

  • POST /api/workflows/{id}/invite — obtenir le lien pour l’acheminer soi-même. L’appel fabrique l’invitation et restitue son inviteUrl sans qu’aucun message ne parte. Associé à maxInvites: 0 (section Les étapes — steps (niveau 2)), il donne à l’application le contrôle entier de l’acheminement : c’est le mode prévu pour qu’un intégrateur transmette lui-même le lien de signature, par son propre canal ou en l’affichant dans son interface.
  • POST /api/workflows/{id}/sendInvite — relancer l’invitation de la plateforme. L’appel réexpédie le message d’invitation émis automatiquement, par exemple lorsqu’il s’est perdu ou a été supprimé avec les indésirables. C’est l’équivalent, côté API, du bouton de relance dont dispose le gestionnaire dans le Portail. Il suppose donc l’envoi automatique (maxInvites ≥ 1) et n’a pas de sens dans un parcours où l’application gère elle-même le lien.

Le second n’est pas le prolongement du premier : le lien issu de /invite est géré par l’intégrateur, et /sendInvite ne s’y applique pas.

Ce que contient l’inviteUrl. L’adresse est de la forme https://<plateforme>/invite?token=…, où le jeton est un JWT dont la charge utile désigne le parcours : aud (toujours invite), workflowId, stepId, userId, consentVersion et iat. Deux conséquences pratiques :

  • aucune revendication exp n’y figure — la durée de validité n’est pas dans le lien mais arbitrée côté serveur par le validityPeriod de l’étape et le statut du parapheur ; il est donc inutile d’espérer prolonger un accès en manipulant l’URL ;
  • le lien est un porteur : sa seule détention suffit à se présenter comme le signataire désigné. Il ne doit pas être journalisé, ni transiter par une URL de redirection, ni s’afficher ailleurs que derrière l’authentification de votre application. L’authentification exigée par la page de consentement reste, elle, entièrement en place — voir la fondation Règles d’intégration technico-juridiques.

La référence propose par ailleurs la duplication et la suppression d’un parapheur.