Guides

Placement automatique des champs de signature avec des balises d'ancre : Positionnement de champ basé sur le texte

Graphique abstrait avec fond sombre présentant un rectangle divisé, des lignes pointillées libellées "X=?" et "Y=?", et une flèche pointant vers la droite, suggérant une transformation.

Si vous avez déjà positionné des champs de signature en calculant des coordonnées x/y sur un PDF, vous savez à quel point cela devient fastidieux à grande échelle. Modifiez la mise en page du document, et chaque coordonnée devient invalide. Ajoutez une deuxième page, et vous devez recalculer les décalages pour la moitié de vos champs.

Les balises d’ancrage résolvent ce problème. Intégrez directement dans votre modèle PDF des marqueurs de texte comme {{SIGN_HERE}} ou {{DATE}}, et Firma.dev les détecte automatiquement et place les bons types de champs à ces emplacements. Les marqueurs sont supprimés du document final, de sorte que les signataires ne les voient jamais. Un seul appel API, aucun calcul de coordonnées.

Les balises d’ancrage ont été lancées dans la version v1.11.0 et prennent en charge tous les types de champs, des règles de correspondance flexibles et jusqu’à 100 balises par demande de signature.

Démarrage rapide

La façon la plus rapide de faire fonctionner les balises d’ancrage : intégrez un marqueur dans votre PDF, puis créez une demande de signature avec un tableau anchor_tags.

Étape 1 : ajoutez le texte {{SIGN_HERE}} quelque part dans votre PDF à l’endroit où vous souhaitez que le champ de signature apparaisse. Vous pouvez le faire dans l’outil qui génère vos documents, qu’il s’agisse d’un modèle Word, d’une bibliothèque PDF ou d’un service de génération de documents.

Étape 2 : créez une demande de signature basée sur un document avec la définition de balise d’ancrage :

const response = await fetch(
  'https://api.firma.dev/functions/v1/signing-request-api/signing-requests',
  {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.FIRMA_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      workspace_id: workspaceId,
      document: documentBase64,
      name: 'NDA - Acme Corp',
      anchor_tags: [
        {
          anchor_string: '{{SIGN_HERE}}',
          type: 'signature',
          recipient_id: 'temp_1',
          required: true
        }
      ],
      recipients: [
        {
          id: 'temp_1',
          first_name: 'Jane',
          last_name: 'Smith',
          email: 'jane@example.com',
          designation: 'Signer',
          order: 1
        }
      ]
    })
  }
);

const signingRequest = await response.json();
const response = await fetch(
  'https://api.firma.dev/functions/v1/signing-request-api/signing-requests',
  {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.FIRMA_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      workspace_id: workspaceId,
      document: documentBase64,
      name: 'NDA - Acme Corp',
      anchor_tags: [
        {
          anchor_string: '{{SIGN_HERE}}',
          type: 'signature',
          recipient_id: 'temp_1',
          required: true
        }
      ],
      recipients: [
        {
          id: 'temp_1',
          first_name: 'Jane',
          last_name: 'Smith',
          email: 'jane@example.com',
          designation: 'Signer',
          order: 1
        }
      ]
    })
  }
);

const signingRequest = await response.json();
const response = await fetch(
  'https://api.firma.dev/functions/v1/signing-request-api/signing-requests',
  {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.FIRMA_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      workspace_id: workspaceId,
      document: documentBase64,
      name: 'NDA - Acme Corp',
      anchor_tags: [
        {
          anchor_string: '{{SIGN_HERE}}',
          type: 'signature',
          recipient_id: 'temp_1',
          required: true
        }
      ],
      recipients: [
        {
          id: 'temp_1',
          first_name: 'Jane',
          last_name: 'Smith',
          email: 'jane@example.com',
          designation: 'Signer',
          order: 1
        }
      ]
    })
  }
);

const signingRequest = await response.json();

Firma.dev analyse le PDF à la recherche de {{SIGN_HERE}}, place un champ de signature à cet emplacement, l’assigne au destinataire et supprime le texte du marqueur du document. C’est tout.

Notez que les balises d'ancrage ne fonctionnent qu'avec la création de demandes de signature basées sur un document, et non sur modèle. Vous envoyez le PDF brut et laissez le système d’ancrage gérer le placement des champs.

Types de champs pris en charge

Les balises d’ancrage prennent en charge tous les types de champs disponibles dans Firma.dev. Définissez la propriété type de chaque balise d’ancrage sur l’une de ces valeurs :

signature pour les champs de signature, initials pour les champs d’initiales, text pour la saisie de texte sur une seule ligne, textarea pour la saisie de texte sur plusieurs lignes, date pour les champs de date, checkbox pour les cases à cocher, radio pour les groupes de boutons radio, dropdown pour les menus déroulants, url pour les champs d’URL, stamp pour les champs de tampon et file pour les champs de téléversement de fichiers.

Chaque type affiche le composant de champ approprié dans l’expérience de signature. Une balise d’ancrage date crée un sélecteur de date, une dropdown crée un menu déroulant, et ainsi de suite.

Options de correspondance et de positionnement

Le comportement de correspondance par défaut fonctionne dans la plupart des cas, mais vous pouvez affiner la façon dont Firma.dev trouve et positionne les champs créés par ancrage.

Sensibilité à la casse : Définissez case_sensitive sur true ou false (la valeur par défaut est false). Avec une correspondance insensible à la casse, {{sign_here}} et {{SIGN_HERE}} correspondent toutes deux.

Correspondance sur le mot entier : Définissez whole_word sur true pour empêcher les correspondances partielles. Si votre chaîne d’ancrage est SIGN et que whole_word est false, elle correspondrait aussi à SIGNATURE ou COSIGN. La définir sur true garantit qu’elle ne correspond qu’au mot exact.

Ciblage d’occurrences spécifiques : si votre PDF contient plusieurs fois la même chaîne d’ancrage, vous pouvez cibler des occurrences spécifiques avec occurrence. Définissez-la sur 1 pour la première correspondance, 2 pour la deuxième, etc. Omettez-la ou définissez match_all sur true pour placer des champs à chaque occurrence.

Positionnement avec décalage : ajustez finement l’endroit où le champ se place par rapport au texte d’ancrage à l’aide de offset_x et offset_y. Vous pouvez spécifier des décalages en pourcentage (par rapport aux dimensions de la page) ou en pixels. C’est utile lorsque vous souhaitez que le champ soit positionné légèrement en dessous ou à droite du marqueur, plutôt que directement dessus.

Gestion élégante des ancres manquantes : définissez ignore_if_not_present sur true si la chaîne d’ancrage peut ne pas exister dans chaque document. Sans cela, une ancre manquante renvoie une erreur. Lorsqu’elle est activée, Firma.dev ignore silencieusement cette balise et traite le reste.

Configuration avancée

Voici un exemple plus complet qui combine plusieurs balises d’ancrage avec différents types de champs, des dimensions personnalisées et des décalages de positionnement :

const response = await fetch(
  'https://api.firma.dev/functions/v1/signing-request-api/signing-requests',
  {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.FIRMA_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      workspace_id: workspaceId,
      document: documentBase64,
      name: 'Employment Agreement',
      anchor_tags: [
        {
          anchor_string: '{{EMPLOYEE_SIGNATURE}}',
          type: 'signature',
          recipient_id: 'temp_1',
          required: true,
          width: 30,
          height: 8,
          offset_y: 2
        },
        {
          anchor_string: '{{EMPLOYEE_DATE}}',
          type: 'date',
          recipient_id: 'temp_1',
          required: true
        },
        {
          anchor_string: '{{EMPLOYEE_INITIALS}}',
          type: 'initials',
          recipient_id: 'temp_1',
          required: true,
          match_all: true
        },
        {
          anchor_string: '{{MANAGER_SIGNATURE}}',
          type: 'signature',
          recipient_id: 'temp_2',
          required: true
        },
        {
          anchor_string: '{{BENEFITS_OPT_IN}}',
          type: 'checkbox',
          recipient_id: 'temp_1',
          required: false,
          ignore_if_not_present: true
        }
      ],
      recipients: [
        {
          id: 'temp_1',
          first_name: 'Sarah',
          last_name: 'Chen',
          email: 'sarah@example.com',
          designation: 'Signer',
          order: 1
        },
        {
          id: 'temp_2',
          first_name: 'Mike',
          last_name: 'Torres',
          email: 'mike@example.com',
          designation: 'Signer',
          order: 2
        }
      ]
    })
  }
);
const response = await fetch(
  'https://api.firma.dev/functions/v1/signing-request-api/signing-requests',
  {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.FIRMA_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      workspace_id: workspaceId,
      document: documentBase64,
      name: 'Employment Agreement',
      anchor_tags: [
        {
          anchor_string: '{{EMPLOYEE_SIGNATURE}}',
          type: 'signature',
          recipient_id: 'temp_1',
          required: true,
          width: 30,
          height: 8,
          offset_y: 2
        },
        {
          anchor_string: '{{EMPLOYEE_DATE}}',
          type: 'date',
          recipient_id: 'temp_1',
          required: true
        },
        {
          anchor_string: '{{EMPLOYEE_INITIALS}}',
          type: 'initials',
          recipient_id: 'temp_1',
          required: true,
          match_all: true
        },
        {
          anchor_string: '{{MANAGER_SIGNATURE}}',
          type: 'signature',
          recipient_id: 'temp_2',
          required: true
        },
        {
          anchor_string: '{{BENEFITS_OPT_IN}}',
          type: 'checkbox',
          recipient_id: 'temp_1',
          required: false,
          ignore_if_not_present: true
        }
      ],
      recipients: [
        {
          id: 'temp_1',
          first_name: 'Sarah',
          last_name: 'Chen',
          email: 'sarah@example.com',
          designation: 'Signer',
          order: 1
        },
        {
          id: 'temp_2',
          first_name: 'Mike',
          last_name: 'Torres',
          email: 'mike@example.com',
          designation: 'Signer',
          order: 2
        }
      ]
    })
  }
);
const response = await fetch(
  'https://api.firma.dev/functions/v1/signing-request-api/signing-requests',
  {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.FIRMA_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      workspace_id: workspaceId,
      document: documentBase64,
      name: 'Employment Agreement',
      anchor_tags: [
        {
          anchor_string: '{{EMPLOYEE_SIGNATURE}}',
          type: 'signature',
          recipient_id: 'temp_1',
          required: true,
          width: 30,
          height: 8,
          offset_y: 2
        },
        {
          anchor_string: '{{EMPLOYEE_DATE}}',
          type: 'date',
          recipient_id: 'temp_1',
          required: true
        },
        {
          anchor_string: '{{EMPLOYEE_INITIALS}}',
          type: 'initials',
          recipient_id: 'temp_1',
          required: true,
          match_all: true
        },
        {
          anchor_string: '{{MANAGER_SIGNATURE}}',
          type: 'signature',
          recipient_id: 'temp_2',
          required: true
        },
        {
          anchor_string: '{{BENEFITS_OPT_IN}}',
          type: 'checkbox',
          recipient_id: 'temp_1',
          required: false,
          ignore_if_not_present: true
        }
      ],
      recipients: [
        {
          id: 'temp_1',
          first_name: 'Sarah',
          last_name: 'Chen',
          email: 'sarah@example.com',
          designation: 'Signer',
          order: 1
        },
        {
          id: 'temp_2',
          first_name: 'Mike',
          last_name: 'Torres',
          email: 'mike@example.com',
          designation: 'Signer',
          order: 2
        }
      ]
    })
  }
);

Quelques points à noter dans cet exemple. La balise {{EMPLOYEE_INITIALS}} utilise match_all: true, donc si le PDF comporte des marqueurs d’initiales sur les pages 1, 5 et 12, les trois obtiennent des champs. La case à cocher {{BENEFITS_OPT_IN}} utilise ignore_if_not_present: true parce que toutes les versions du contrat de travail n’incluent pas cette section. Et le offset_y: 2 sur le champ de signature le décale légèrement vers le bas par rapport à la position du texte d’ancrage.

Les dimensions (width et height) suivent le même système de coordonnées basé sur des pourcentages que celui utilisé par les champs positionnés manuellement. Les balises d’ancrage et les champs manuels fonctionnent ensemble, vous pouvez donc utiliser des ancres pour la majorité de vos champs tout en ajoutant, dans la même demande, des champs manuels basés sur des coordonnées pour les cas limites.

Migration depuis d’autres plateformes

Si vous migrez depuis un autre fournisseur de signature électronique qui utilise le positionnement des champs basé sur du texte, les concepts se transposent directement. La syntaxe de la chaîne d’ancrage et les noms de propriétés diffèrent, mais le mécanisme sous-jacent est le même : intégrer un marqueur, définir le type de champ, laisser l’API gérer le positionnement.

Depuis Auto-Place de DocuSign : DocuSign utilise anchorString, anchorXOffset, anchorYOffset et des types spécifiques aux onglets comme signHereTabs. Dans Firma.dev, cela devient anchor_string, offset_x, offset_y et le champ universel type. anchorIgnoreIfNotPresent de DocuSign correspond à ignore_if_not_present. anchorCaseSensitive de DocuSign correspond à case_sensitive. La principale différence structurelle est que Firma.dev utilise un seul tableau anchor_tags avec une propriété type, plutôt que des tableaux séparés pour chaque type d’onglet.

Depuis les Smart Anchors de Yousign : Le concept de « smart anchors » de Yousign, avec détection du type de champ, se traduit directement. Les options de correspondance et de positionnement sont comparables, bien que les noms de propriétés utilisent la convention snake_case de Firma.dev.

La limite est de 100 balises d’ancrage par demande de signature, ce qui couvre confortablement la plupart des flux de travail documentaires. Si vous traitez des documents qui nécessitent réellement plus de 100 champs, envisagez de répartir le tout sur plusieurs demandes de signature ou d’utiliser une combinaison de balises d’ancrage et de définitions de champs basées sur des modèles.

Référence de l’API

Le tableau anchor_tags est disponible sur le point de terminaison de création de demandes de signature basées sur un document (POST /signing-requests). Chaque élément du tableau est un objet AnchorTag avec environ 25 propriétés configurables.

Les propriétés clés :

anchor_string (obligatoire) est le marqueur de texte à rechercher dans le PDF. type (obligatoire) est le type de champ à créer. recipient_id attribue le champ à un destinataire spécifique à l’aide de son ID ou d’un ID temporaire. required indique si le champ est obligatoire ou facultatif. offset_x et offset_y ajustent la position du champ par rapport à l’emplacement de l’ancre. width et height définissent des dimensions personnalisées. case_sensitive contrôle si la correspondance est sensible à la casse. whole_word empêche les correspondances partielles de chaînes. occurrence cible une instance spécifique lorsque l’ancre apparaît plusieurs fois. match_all place des champs à chaque occurrence. ignore_if_not_present ignore la balise sans erreur si le texte d’ancrage n’est pas trouvé dans le document.

Pour obtenir le schéma complet avec toutes les propriétés et leurs types, consultez le journal des modifications de l’API pour la version v1.11.0.

Prochaines étapes

Les balises d’ancrage se marient bien avec la génération programmatique de documents. Si votre application génère des contrats, des NDA ou des documents d’intégration à partir de modèles, vous pouvez intégrer des chaînes d’ancrage pendant la génération et laisser Firma.dev gérer automatiquement le placement des champs à chaque demande.

Commencez gratuitement avec Firma.dev, sans carte bancaire requise.

  1. Titre

Image de fond

Prêt à ajouter des signatures électroniques à votre application ?

Commencez gratuitement. Aucune carte de crédit requise. Payez seulement 0,029 € par enveloppe lorsque vous êtes prêt à passer en direct.

Image de fond

Prêt à ajouter des signatures électroniques à votre application ?

Commencez gratuitement. Aucune carte de crédit requise. Payez seulement 0,029 € par enveloppe lorsque vous êtes prêt à passer en direct.

Image de fond

Prêt à ajouter des signatures électroniques à votre application ?

Commencez gratuitement. Aucune carte de crédit requise. Payez seulement 0,029 € par enveloppe lorsque vous êtes prêt à passer en direct.