Aller au contenu principal
Certyneo

Dossier API · Mise en œuvre

Intégrer la signature électronique dans une application ou un site web : le guide pas à pas

Pour intégrer la signature électronique dans une application, il faut trois appels d'API et un webhook : téléverser le document, créer l'enveloppe avec ses signataires, l'envoyer, puis réagir à l'événement de fin de signature. Ce guide détaille d'abord le choix d'architecture — invitation par e-mail, signature dans une iframe de votre site, ou automatisation sans code — puis chaque étape avec du code prêt à adapter, sur l'API REST de Certyneo.

Mis à jour le 26 septembre 2026 · Rédigé par l'équipe Certyneo

Trois façons d'intégrer la signature dans votre produit

Avant d'écrire la première ligne, décidez où le signataire signe. Ce choix conditionne l'expérience utilisateur, le forfait nécessaire et la quantité de code.

1. Invitation par e-mail : le plus simple

Votre application crée l'enveloppe par API ; Certyneo envoie l'invitation par e-mail, le signataire signe sur la page de signature hébergée, puis votre application est prévenue par webhook. C'est l'intégration la plus rapide : aucune interface de signature à héberger, les relances automatiques sont gérées pour vous. Elle convient aux contrats envoyés à des clients, des salariés ou des fournisseurs qui n'ont pas de compte chez vous.

2. Signature intégrée en iframe : l'utilisateur ne quitte pas votre site

L'utilisateur est déjà connecté à votre portail et signe sans changer d'onglet : c'est le parcours idéal pour un tunnel de souscription, une ouverture de compte ou une validation de devis. Votre serveur demande une URL de signature à usage limité (POST /api/v1/envelopes/:id/embed-url) et l'affiche dans une iframe. Cette option est disponible dès le forfait Standard, sur un domaine que vous avez déclaré et vérifié.

3. Sans code : Make, n8n, Power Automate

Si le déclencheur vit dans un outil existant — une ligne de Google Sheets, un deal gagné dans le CRM, un formulaire rempli —, un scénario d'automatisation fait le même travail que l'API sans développement. Certyneo est disponible sur Make et n8n, et se branche à Power Automate pour l'écosystème Microsoft 365. Le guide Make ou Zapier aide à choisir l'outil.

Quelle architecture pour quel besoin
CritèreInvitation par e-mailIframe intégréeSans code
DéveloppementFaibleMoyen (front + back)Aucun
Le signataire quitte votre siteOuiNonOui
Forfait minimum pour la productionStandardStandardSelon le connecteur
Cas typiqueContrats, avenants, RHSouscription en ligne, portail clientFlux internes, CRM, tableurs

Prérequis : clé API, environnement de test, domaine

  1. Créez un compte et générez une clé de test sk_test_ depuis le tableau de bord. Elle fonctionne sur tous les forfaits, y compris Gratuit ; le détail des limites est dans le guide API de signature électronique gratuite.
  2. Stockez la clé côté serveur uniquement, dans une variable d'environnement (CERTYNEO_API_KEY). Une clé API ne doit jamais apparaître dans le code envoyé au navigateur ni dans une application mobile.
  3. Déclarez un point de terminaison webhook (une URL HTTPS de votre backend) et notez son secret : il sert à vérifier que les événements viennent bien de Certyneo.
  4. Pour l'iframe, déclarez et vérifiez le domaine qui affichera la signature. En développement, http://localhost est accepté avec une clé de test.

Toutes les routes décrites ici sont sous https://certyneo.com/api/v1 et s'authentifient avec l'en-tête Authorization: Bearer <clé>. La référence complète, générée depuis la spécification OpenAPI, est sur la page documentation de l'API.

Étape 1 — Téléverser le document

Le document part en multipart/form-data, dans un champ file. La réponse renvoie l'identifiant du document, à réutiliser à l'étape suivante. Un même document peut servir à plusieurs enveloppes.

cURL — POST /documents
curl https://certyneo.com/api/v1/documents \
  -H "Authorization: Bearer $CERTYNEO_API_KEY" \
  -F "file=@contrat.pdf"

# 201 Created
# { "id": "cm8doc...", "name": "contrat.pdf", "status": "READY", ... }

Si vos contrats sont toujours bâtis sur le même gabarit, créez plutôt un modèle dans le tableau de bord ou par API (/api/v1/templates) et passez templateId à la création : les documents et la position des champs sont alors repris du modèle.

Étape 2 — Créer l'enveloppe et placer les champs

L'enveloppe réunit le ou les documents, les destinataires et les champs à remplir. Elle est créée en brouillon : rien n'est envoyé tant que vous n'appelez pas l'étape 3, ce qui laisse le temps de la vérifier ou de la faire valider.

cURL — POST /envelopes avec un champ placé par ancre
curl https://certyneo.com/api/v1/envelopes \
  -H "Authorization: Bearer $CERTYNEO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "subject": "Contrat de prestation — Acme",
    "documentIds": ["cm8doc..."],
    "signatureLevel": "SIMPLE",
    "recipients": [
      { "email": "marie.dupont@example.com", "name": "Marie Dupont" }
    ],
    "fields": [
      {
        "recipientEmail": "marie.dupont@example.com",
        "fieldType": "SIGNATURE",
        "anchorText": "Signature du client",
        "anchorPlacement": "below",
        "pageNumber": 2, "x": 380, "y": 640, "width": 180, "height": 60
      }
    ],
    "redirectUrl": "https://votre-app.fr/contrat/merci"
  }'

# 201 Created → { "id": "cm8env...", "status": "DRAFT", ... }

Placer les champs sans calculer de coordonnées

Le champ anchorText cite un texte présent dans le PDF (« Signature du client », « Lu et approuvé ») et la signature se pose à côté, selon anchorPlacement (right, below, above ou left). Les coordonnées x/y restent obligatoires : elles servent de repli si l'ancre est introuvable, pour qu'un envoi n'échoue jamais sur un document dont la mise en page a changé. La réponse signale les ancres non appliquées.

Les options utiles à la création

  • signatureLevel : SIMPLE (par défaut), ADVANCED — qui active un code par SMS et demande un numéro de téléphone au format international pour chaque signataire — ou QUALIFIED. Voir la page signature électronique qualifiée pour savoir quand elle s'impose.
  • signingOrder : PARALLEL (tous invités en même temps, par défaut) ou SEQUENTIAL (dans l'ordre du tableau recipients).
  • reminderEnabled et reminderDays : relances automatiques, de 1 à 30 jours.
  • expiresAt : date d'expiration de l'enveloppe.
  • redirectUrl : page de votre site où renvoyer le signataire après signature (HTTPS obligatoire, http://localhost accepté avec une clé de test).
  • category et tags : classement métier, pour retrouver les enveloppes dans le tableau de bord et filtrer la liste par API.

Étape 3 — Envoyer, ou afficher la signature dans votre site

L'envoi déclenche les invitations par e-mail et décompte l'enveloppe de votre quota mensuel. À partir de là, l'enveloppe suit son cycle de vie : envoyée, consultée, signée, terminée — ou refusée, expirée, annulée.

cURL — POST /envelopes/:id/send
curl -X POST https://certyneo.com/api/v1/envelopes/cm8env.../send \
  -H "Authorization: Bearer $CERTYNEO_API_KEY"

Variante iframe : obtenir une URL de signature

Pour faire signer dans votre interface, votre serveur demande une URL de signature pour l'origine de la page qui l'affichera. Sans recipientEmail, c'est le premier signataire en attente qui est visé. L'autorisation d'affichage expire au bout de deux heures : demandez l'URL au moment où l'utilisateur ouvre la page, pas à la création du contrat.

cURL — POST /envelopes/:id/embed-url
curl https://certyneo.com/api/v1/envelopes/cm8env.../embed-url \
  -H "Authorization: Bearer $CERTYNEO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "origin": "https://votre-app.fr", "recipientEmail": "marie.dupont@example.com" }'

# → { "signingUrl": "https://certyneo.com/sign/...", "recipientEmail": "marie.dupont@example.com", ... }

Côté navigateur, il suffit d'afficher signingUrl dans une iframe. Ne transmettez jamais la clé API au front : seule l'URL de signature, liée à un signataire et à une origine, quitte votre serveur.

Étape 4 — Recevoir les webhooks et vérifier leur signature

Plutôt que d'interroger l'API en boucle, laissez Certyneo vous prévenir. Chaque événement arrive en POST JSON sur votre point de terminaison, avec un en-tête X-Certyneo-Event (le nom de l'événement) et un en-tête X-Certyneo-Signature : le HMAC SHA-256, en hexadécimal, du corps brut de la requête, calculé avec le secret du point de terminaison.

Node.js (Express) — vérifier puis traiter un webhook
import crypto from "node:crypto";
import express from "express";

const app = express();

// Corps BRUT : le HMAC se calcule sur les octets reçus, pas sur un JSON re-sérialisé.
app.post("/webhooks/certyneo", express.raw({ type: "application/json" }), (req, res) => {
  const expected = crypto
    .createHmac("sha256", process.env.CERTYNEO_WEBHOOK_SECRET)
    .update(req.body)
    .digest("hex");
  const received = req.get("X-Certyneo-Signature") ?? "";
  const ok =
    received.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(received), Buffer.from(expected));
  if (!ok) return res.status(401).end();

  const { id, event, data } = JSON.parse(req.body.toString("utf8"));
  // id est identique à chaque nouvelle tentative : ignorez un id déjà traité.
  if (event === "envelope.completed") {
    // data.envelopeId, data.recipients, data.signedDocumentUrl…
  }
  res.status(200).end();
});
Python (Flask) — même vérification
import hashlib, hmac, os
from flask import Flask, request, abort

app = Flask(__name__)

@app.post("/webhooks/certyneo")
def certyneo_webhook():
    expected = hmac.new(os.environ["CERTYNEO_WEBHOOK_SECRET"].encode(),
                        request.get_data(), hashlib.sha256).hexdigest()
    if not hmac.compare_digest(expected, request.headers.get("X-Certyneo-Signature", "")):
        abort(401)
    payload = request.get_json()
    # payload["event"], payload["data"]["envelopeId"]…
    return "", 200

Les événements à écouter

  • envelope.completed : tous les signataires ont signé ; le document signé est disponible (signedDocumentUrl). C'est l'événement principal.
  • recipient.signed et recipient.viewed : suivi signataire par signataire, utile pour afficher une progression.
  • envelope.declined, envelope.expired et envelope.voided : l'enveloppe ne sera pas signée ; prévenez l'utilisateur ou relancez le processus.
  • envelope.created et envelope.sent : utiles pour la journalisation.

Répondez vite (moins de 10 secondes) avec un code 2xx, et faites le traitement lourd en tâche de fond. En cas d'échec — code 5xx, 408, 425, 429 ou délai dépassé —, Certyneo relance jusqu'à 5 tentatives, après 1 minute, 5 minutes, 15 minutes puis 1 heure. Les autres codes 4xx sont définitifs. Les événements en échec restent consultables et rejouables depuis le tableau de bord. Tout le détail est sur la page webhooks de signature électronique.

Étape 5 — Récupérer le document signé et la preuve

Une fois envelope.completed reçu, téléchargez le PDF signé (GET /api/v1/envelopes/:id/signed-document) et la piste d'audit (GET /api/v1/envelopes/:id/audit-trail), puis archivez-les avec le dossier concerné dans votre application. Le lien signedDocumentUrl du webhook est temporaire : ne le stockez pas comme référence permanente.

Pour une conservation longue durée, Certyneo propose aussi un coffre-fort numérique ; la durée de conservation se règle entre 3, 5, 10 ans ou sans limite.

Mise en production : la liste de contrôle

  1. Remplacez la clé sk_test_ par une clé sk_live_ (forfait Standard ou supérieur), stockée dans votre gestionnaire de secrets.
  2. Surveillez les en-têtes X-RateLimit-Remaining et gérez le code 429 avec l'en-tête Retry-After : la limite va de 60 requêtes par minute et par clé en Standard à 1 000 en Enterprise.
  3. Rendez votre traitement des webhooks idempotent (un même id peut arriver deux fois) et journalisez les signatures HMAC refusées.
  4. Choisissez le bon niveau de signature pour chaque type de document, et prévoyez les numéros de téléphone si vous passez en signature avancée.
  5. Testez les cas d'échec : signataire qui refuse, enveloppe expirée, annulation (POST /api/v1/envelopes/:id/void).

Vous venez d'un autre éditeur ? Le guide migrer de DocuSign ou Yousign vers Certyneo liste les équivalences. Pour la vue d'ensemble — tarifs, conformité eIDAS, SLA —, voir la page API de signature électronique, et l'article de blog guide développeur de l'API REST pour un tour des bonnes pratiques.

Testez l'API Certyneo gratuitement

Clé de test sk_test_ disponible dès le compte gratuit : envoyez votre première enveloppe en quelques minutes.

Questions fréquentes

Comment intégrer une signature électronique sur un site web ?

Deux options : envoyer une invitation par e-mail depuis votre backend (trois appels : téléverser le PDF, créer l'enveloppe, l'envoyer), ou afficher la page de signature dans une iframe de votre site avec une URL obtenue par POST /envelopes/:id/embed-url. Dans les deux cas, un webhook vous prévient à la fin de la signature.

Combien de temps faut-il pour intégrer une API de signature électronique ?

Le parcours par e-mail tient en trois appels d'API et un point de terminaison webhook : quelques heures pour un premier prototype sur une clé de test. L'iframe, la gestion des erreurs et les tests de bout en bout prennent plus de temps, selon votre application.

Peut-on signer sans quitter mon application ?

Oui, avec la signature intégrée : votre serveur demande une URL de signature pour un signataire et l'origine de votre page, puis l'affiche dans une iframe. Disponible dès le forfait Standard, sur un domaine déclaré et vérifié ; l'autorisation expire au bout de deux heures.

Comment savoir qu'un document a été signé ?

Abonnez un point de terminaison à l'événement envelope.completed : il arrive dès que tous les signataires ont signé, avec la liste des signataires et un lien temporaire vers le document signé. Vérifiez toujours l'en-tête X-Certyneo-Signature avant de traiter l'événement.

Faut-il un SDK pour intégrer l'API Certyneo ?

Non : l'API REST s'appelle avec n'importe quel client HTTP, comme dans les exemples cURL, Node et Python de ce guide. Aucun SDK officiel n'est encore publié ; la spécification OpenAPI permet d'en générer un pour votre langage.

Dans le même dossier : l'API de signature électronique

Point de départ du dossier : l'API de signature électronique Certyneo (REST, webhooks, eIDAS).

Sources

Offres des éditeurs tiers relevées sur leurs pages publiques à la date de mise à jour indiquée ; elles peuvent évoluer. Une erreur ? contact@certyneo.com