Passer au contenu principal

Envoi d’une demande de signature

Ce guide couvre la création d’une demande de signature, l’ajout d’un modèle ou d’un document, et l’invitation des destinataires à signer.

Étapes

  1. Créez ou sélectionnez un modèle
  2. Créez une demande de signature référençant le modèle
  3. Ajoutez des destinataires avec les informations requises (prénom, nom, email)
  4. Ajoutez éventuellement des champs de formulaire avec un positionnement basé sur des pourcentages
  5. Envoyez la demande par email ou intégrez la vue de signature

Schéma du destinataire (champs requis)

Changement majeur : les destinataires nécessitent désormais first_name et last_name séparément au lieu d’un seul champ name.
Chaque destinataire doit inclure :
  • first_name (requis) - Prénom du destinataire
  • last_name (requis) - Nom du destinataire
  • email (requis) - Adresse email valide
  • designation (requis) - Rôle : "Signer", "CC", ou "Approver". Les approbateurs examinent et approuvent le document (sans signature) via les types de champs approval_* ci-dessous
  • order (optionnel) - Ordre de signature pour les workflows séquentiels
Champs optionnels :
  • phone_number, street_address, city, state_province, postal_code, country, title, company
  • custom_fields - Objet avec des paires clé-valeur personnalisées

Créer une demande de signature à partir d’un modèle (API)

Endpoint : POST /signing-requests
Exemple curl (création d’une demande à partir d’un modèle) :
curl -X POST "https://api.firma.dev/functions/v1/signing-request-api/signing-requests" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "template_id": "tmpl_123",
    "name": "NDA - Acme Corp",
    "recipients": [
      { 
        "first_name": "Alice",
        "last_name": "Johnson",
        "email": "alice@example.com",
        "designation": "Signer",
        "order": 1
      }
    ]
  }'
Une réponse réussie (201) renvoie une ressource Document incluant id (le signing_request_id) et document_url le cas échéant.

Créer une demande de signature (exemple serveur) — Node (fetch)

const fetch = require('node-fetch')

async function createFromTemplate(templateId) {
  const resp = 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({
      template_id: templateId,
      name: 'NDA - Acme Corp',
      recipients: [
        {
          first_name: 'Alice',
          last_name: 'Johnson',
          email: 'alice@example.com',
          designation: 'Signer',
          order: 1
        }
      ]
    })
  })
  if (!resp.ok) throw new Error('failed to create')
  const body = await resp.json()
  return body // contient id, document_url, recipients, etc.
}

Créer une demande de signature (exemple serveur) — Python (requests)

import os
import requests

def create_from_template(template_id):
    url = 'https://api.firma.dev/functions/v1/signing-request-api/signing-requests'
    resp = requests.post(url, headers={
        'Authorization': f"Bearer {os.environ['FIRMA_API_KEY']}",
        'Content-Type': 'application/json'
    }, json={
        'template_id': template_id,
        'name': 'NDA - Acme Corp',
        'recipients': [
            {
                'first_name': 'Alice',
                'last_name': 'Johnson',
                'email': 'alice@example.com',
                'designation': 'Signer',
                'order': 1
            }
        ]
    })
    resp.raise_for_status()
    return resp.json()

Créer une demande de signature à partir d’un document

Au lieu d’utiliser un modèle, vous pouvez créer une demande de signature en téléversant directement un document PDF ou DOCX. Choisissez la méthode en fonction de la taille de votre fichier :
Pour les documents de moins de 5 Mo, incluez le fichier encodé en base64 directement dans le corps de la requête :
curl -X POST "https://api.firma.dev/functions/v1/signing-request-api/signing-requests/create-and-send" \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Employment Contract",
    "document": "JVBERi0xLjQK... (base64-encoded PDF)",
    "recipients": [
      {
        "first_name": "Alice",
        "last_name": "Johnson",
        "email": "alice@example.com",
        "designation": "Signer"
      }
    ]
  }'
Vous devez fournir exactement un seul des paramètres document, document_id, ou template_id. Ils sont mutuellement exclusifs.

Ajout de champs de formulaire (positionnement basé sur des pourcentages)

Important : toutes les coordonnées de position des champs (x, y, width, height) doivent être des pourcentages (0-100) relatifs aux dimensions de la page, et non des pixels. Le champ page_number est requis.
Lors de la création directe d’une demande de signature (POST /signing-requests) ou de sa mise à jour, vous pouvez ajouter des champs de formulaire :

Exemple de positionnement de champ

{
  "name": "Contract with Fields",
  "recipients": [
    {
      "first_name": "Bob",
      "last_name": "Smith",
      "email": "bob@example.com",
      "designation": "Signer",
      "order": 1
    }
  ],
  "fields": [
    {
      "type": "signature",
      "required": true,
      "recipient_id": "recipient_uuid_here",
      "page_number": 1,
      "position": {
        "x": 10,
        "y": 80,
        "width": 30,
        "height": 8
      }
    },
    {
      "type": "text",
      "required": true,
      "recipient_id": "recipient_uuid_here",
      "variable_name": "company_name",
      "page_number": 1,
      "position": {
        "x": 50,
        "y": 20,
        "width": 40,
        "height": 5
      }
    },
    {
      "type": "date",
      "required": true,
      "page_number": 1,
      "date_signing_default": true,
      "position": {
        "x": 10,
        "y": 90,
        "width": 20,
        "height": 4
      }
    }
  ]
}

Types de champs

  • signature - Champ de signature
  • text - Saisie de texte sur une seule ligne
  • date - Sélecteur de date
  • checkbox - Case à cocher
  • dropdown - Sélecteur déroulant (nécessite dropdown_options)
  • initials - Champ d’initiales
  • image - Champ image
  • approval_signature - Tampon APPROVED (Approbateur uniquement)
  • approval_checkmark - Coche d’approbation (Approbateur uniquement)
  • approval_date - Date d’approbation (Approbateur uniquement)
Les types de champs approval_* ne peuvent être attribués qu’à un destinataire dont la designation est "Approver" (en attribuer un à un Signataire renvoie une erreur 400). Leur valeur est établie côté serveur lorsque l’approbateur termine son examen, vous n’avez donc pas à soumettre de valeur pour eux, et le tampon d’approbation est apposé sur le certificat d’achèvement.

Directives de positionnement

Le système de coordonnées utilise des pourcentages pour une mise à l’échelle responsive :
  • x : 0 (bord gauche) à 100 (bord droit)
  • y : 0 (bord supérieur) à 100 (bord inférieur)
  • width : pourcentage de la largeur de la page (par ex., 30 = 30 % de largeur)
  • height : pourcentage de la hauteur de la page (par ex., 8 = 8 % de hauteur)
Pour une page US Letter (8,5” × 11”), utilisez ces conversions approximatives :
  • 1 pouce ≈ 11,76 % de largeur
  • 1 pouce ≈ 9,09 % de hauteur

Mise à jour des demandes de signature

Avant qu’une demande de signature ne soit envoyée, vous pouvez mettre à jour ses détails via l’API. L’API propose deux méthodes :
Impossible de mettre à jour après l’envoi : une fois qu’une demande de signature est envoyée, elle ne peut plus être modifiée. Les mises à jour ne fonctionnent que pour les demandes ayant le statut not_sent.

Mise à jour complète (PUT)

Utilisez comprehensive-update-signing-request pour les mises à jour complexes impliquant plusieurs sections. Quand l’utiliser :
  • Mise à jour de plusieurs destinataires à la fois
  • Suppression de destinataires (avec réattribution/suppression des champs)
  • Mise à jour des champs et des rappels ensemble
  • Effectuer des modifications coordonnées sur plusieurs sections
Structure : toutes les sections sont optionnelles, mais au moins une doit être fournie :
  • signing_request_properties - Mettre à jour le nom, la description, le document, l’expiration, les paramètres
  • recipients - Upsert des destinataires (inclure id pour mettre à jour, omettre pour créer)
  • deleted_recipients - Supprimer des destinataires avec field_action (supprimer ou réattribuer les champs)
  • fields - Upsert des champs (inclure id pour mettre à jour, omettre pour créer)
  • reminders - Upsert des rappels (inclure id pour mettre à jour, omettre pour créer)
Exigences :
  • ✅ Peut mettre à jour plusieurs sections en une seule requête
  • ✅ Prend en charge la suppression de destinataires avec gestion des champs
  • ✅ Ne fonctionne que si la demande n’a pas encore été envoyée
Exemple (Node.js) :
const response = await fetch(`https://api.firma.dev/functions/v1/signing-request-api/signing-requests/${signingRequestId}`, {
  method: 'PUT',
  headers: {
    'Authorization': `Bearer ${process.env.FIRMA_API_KEY}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    signing_request_properties: {
      name: 'Updated Contract Name',
      expiration_hours: 72
    },
    recipients: [
      {
        id: 'rec1-e89b-12d3-a456-426614174000', // Inclure id pour mettre à jour un destinataire existant
        first_name: 'Jane',
        last_name: 'Smith',
        email: 'jane@example.com',
        designation: 'Signer',
        order: 1
      },
      {
        // Omettre id pour créer un nouveau destinataire
        first_name: 'Bob',
        last_name: 'Johnson',
        email: 'bob@example.com',
        designation: 'CC',
        order: 2
      }
    ],
    fields: [
      {
        id: 'field1-e89b-12d3-a456-426614174000',
        type: 'signature',
        position: { x: 15, y: 85, width: 30, height: 10 },
        page_number: 1,
        required: true,
        recipient_id: 'rec1-e89b-12d3-a456-426614174000'
      }
    ]
  })
});

const updatedRequest = await response.json();

Mise à jour partielle (PATCH)

Utilisez partially-update-signing-request pour mettre à jour des propriétés spécifiques ou un seul destinataire. Quand l’utiliser :
  • Mise à jour du nom, de la description ou des paramètres
  • Ajout ou mise à jour d’un destinataire à la fois
  • Effectuer des modifications ciblées sans affecter les autres données
Important : impossible de mettre à jour à la fois les propriétés ET un destinataire dans la même requête. Choisissez l’un ou l’autre :
  • Mettre à jour uniquement les propriétés (name, description, document, expiration_hours, settings)
  • OU mettre à jour/créer un seul destinataire
Avantages :
  • ✅ N’envoyez que les champs que vous souhaitez modifier
  • ✅ Plus efficace pour les petits changements
  • ✅ Les autres champs restent inchangés
  • ✅ Plus sûr pour les modifications concurrentes
Exemple (Node.js) :
// Mettre à jour un seul destinataire
const response = await fetch(`https://api.firma.dev/functions/v1/signing-request-api/signing-requests/${signingRequestId}`, {
  method: 'PATCH',
  headers: {
    'Authorization': `Bearer ${process.env.FIRMA_API_KEY}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    recipient: {
      id: 'rec123-e89b-12d3-a456-426614174000', // Inclure id pour mettre à jour un destinataire existant
      first_name: 'John',
      last_name: 'Updated',
      email: 'john.updated@example.com',
      designation: 'Signer',
      order: 1
    }
  })
});

const updatedRequest = await response.json();
Exemple (Python) :
import requests
import os

# Mettre à jour uniquement les propriétés (nom et expiration)
response = requests.patch(
    f"https://api.firma.dev/functions/v1/signing-request-api/signing-requests/{signing_request_id}",
    headers={
        "Authorization": f"Bearer {os.getenv('FIRMA_API_KEY')}",
        "Content-Type": "application/json"
    },
    json={
        "name": "Updated Contract Name",
        "expiration_hours": 72
    }
)

updated_request = response.json()

Choisir entre PUT et PATCH

ScénarioUtiliserRaison
Reconstruction complète de la demande de signaturePUTRemplacement complet avec toutes les sections (properties, recipients, fields, reminders)
Mise à jour du nom ou des paramètres uniquementPATCHPlus efficace, préserve les destinataires et les champs
Ajout/mise à jour d’un destinatairePATCHMode destinataire unique, les autres destinataires restent inchangés
Mise à jour de plusieurs destinatairesPUTPeut upserter plusieurs destinataires en une seule requête
Suppression de destinataires avec réattribution des champsPUTPrend en charge deleted_recipients avec field_action
Modification du document et de tous les champsPUTChangements structurels majeurs
Mise à jour des champs personnalisésPATCHPréserve la demande de signature principale
Remplacement de tous les destinatairesPUTApproche table rase
Important : les deux méthodes de mise à jour ne fonctionnent qu’avant l’envoi de la demande de signature. Une fois envoyée, la demande de signature devient immuable pour empêcher toute altération des workflows de signature actifs.
Bonnes pratiques :
  • Mettez à jour les demandes de signature avant d’appeler /send
  • Validez les données des destinataires avant de mettre à jour
  • Utilisez PATCH pour les modifications incrémentales
  • Implémentez une logique de nouvelle tentative avec un backoff exponentiel

Envoi (invitations par email)

Une fois que vous avez un ID de demande de signature (et avez effectué les mises à jour nécessaires), appelez POST /signing-requests/{signing_request_id}/send pour envoyer des emails à tous les destinataires.

Exemple

curl -X POST "https://api.firma.dev/functions/v1/signing-request-api/signing-requests/sr_abc123/send" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "custom_message": "Please sign this NDA by EOD." }'
L’endpoint /send vérifie que tous les destinataires disposent des informations requises (first_name, last_name, email) et que tous les champs avec variable_name ont des données correspondantes dans les enregistrements des destinataires.

Intégration de la vue de signature

L’interface publique de signature est disponible selon le modèle suivant : https://app.firma.dev/signing/{signing_request_user_id} Notes :
  • Le signing_request_user_id est généralement renvoyé dans le cadre de l’objet recipients ou en tant que jeton propre à chaque destinataire ; consultez la réponse de GET /signing-requests/id pour les liens ou jetons de signature au niveau du destinataire.
  • Si l’API renvoie directement un document_url ou embed_url, utilisez-le. Sinon, générez un lien de signature éphémère côté serveur et renvoyez-le au frontend.

Exemple — récupérer les détails de signature et afficher un iframe

### Obtenir l'URL de signature

- Le `signing_request_user_id` est renvoyé dans le tableau `recipients` après la création
- Vous pouvez également récupérer les détails de la demande de signature via GET `/signing-requests/{id}` pour obtenir les liens de signature par destinataire

### Exemplerécupérer les détails de signature et afficher un iframe

```js
// récupérer la demande de signature
const r = await fetch('/internal/signing-request/' + signingRequestId)
const json = await r.json()

// récupérer l'URL de signature du destinataire
const recipient = json.recipients[0]
const signingUrl = recipient.signing_url || `https://app.firma.dev/signing/${recipient.id}`

// afficher l'iframe
const iframe = document.createElement('iframe')
iframe.src = signingUrl
iframe.style.width = '100%'
iframe.style.height = '900px'
iframe.frameBorder = '0'
iframe.allow = 'camera;microphone;clipboard-write'
document.getElementById('signing-root').appendChild(iframe)

Cas particuliers et astuces

  • Ordre de signature : assurez-vous que les destinataires ont des valeurs order séquentielles (1, 2, 3…) pour les workflows de signature séquentiels
  • Piste d’audit : téléchargez la piste d’audit via GET /signing-requests/{id}/tracking pour voir toutes les actions des utilisateurs
  • Téléchargement du PDF terminé : utilisez GET /signing-requests/{id}/download après l’achèvement
  • Webhooks : abonnez-vous à des événements comme signing_request.completed plutôt que d’effectuer du polling (voir le guide Webhooks)

Prochaines étapes

  • Pour les workflows de signature séquentiels avec plusieurs signataires, assurez-vous que chaque destinataire a une valeur order séquentielle (1, 2, 3…).
  • Pour l’audit et la conformité, téléchargez le PDF final via GET /signing-requests/signing_request_id/download après l’achèvement.
  • Utilisez les webhooks (voir le Guide Webhooks) pour réagir aux événements de signature plutôt que d’effectuer du polling.