Démarrage rapide
Vous voulez faire signer un PDF depuis votre logiciel, votre CRM ou votre site ? Il faut cinq appels : créer un dossier, y ajouter le PDF, ajouter le signataire, placer son champ de signature, puis envoyer. Signoui s’occupe du reste : e-mail d’invitation, code de vérification, scellement du PDF, dossier de preuve, et un webhook pour vous prévenir.
- Créez un compte sur app.signoui.fr (2 envois offerts par mois, sans carte bancaire).
- Créez une clé de test dans l’espace client, rubrique Développeurs. Une clé
sk_test_n’envoie aucun e-mail ni SMS et ne consomme aucun envoi. - Lancez le parcours complet ci-dessous, puis ouvrez le lien
test_sign_urlsrenvoyé par l’envoi pour signer vous-même dans votre navigateur. - Passez en production avec une clé
sk_live_distincte : rien d’autre ne change dans votre code.
KEY="sk_test_xxx"
API="https://api.signoui.fr/v1"
# 1. Créer le dossier (brouillon)
ENV=$(curl -s -X POST "$API/envelopes" \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-H "Idempotency-Key: devis-2026-0412" \
-d '{"title":"Devis n° 2026-0412","workflow":"sequential","message":"Bonjour, voici le devis dont nous avons parlé.","expires_in_days":30,"metadata":{"crm_id":"12345"}}' \
| jq -r .id)
# 2. Ajouter le PDF (20 Mo et 300 pages maximum)
DOC=$(curl -s -X POST "$API/envelopes/$ENV/documents" \
-H "Authorization: Bearer $KEY" \
-F "file=@devis-2026-0412.pdf;type=application/pdf" | jq -r .id)
# 3. Ajouter un signataire (téléphone au format international pour le code SMS)
SGN=$(curl -s -X POST "$API/envelopes/$ENV/signers" \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"full_name":"Marie Dupont","email":"marie.dupont@exemple.fr","phone":"+33612345678","otp_channel":"sms"}' \
| jq -r .id)
# 4. Placer son champ de signature (points PDF, origine en bas à gauche de la page)
curl -s -X POST "$API/envelopes/$ENV/fields" \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d "{\"document_id\":\"$DOC\",\"signer_id\":\"$SGN\",\"kind\":\"signature\",\"page\":3,\"x\":60,\"y\":80,\"width\":180,\"height\":60}"
# 5. Envoyer à la signature
curl -s -X POST "$API/envelopes/$ENV/send" \
-H "Authorization: Bearer $KEY" -H "Idempotency-Key: send-devis-2026-0412"
Ensuite, attendez le webhook envelope.completed (voir Webhooks) ou interrogez GET /envelopes/{id}, puis téléchargez le PDF scellé et l’archive de preuve (voir Télécharger le PDF signé et la preuve).
L’essentiel
| Élément | Valeur |
|---|---|
| URL de base | https://api.signoui.fr/v1 |
| Authentification | en-tête Authorization: Bearer sk_live_… ou sk_test_… |
| Format | JSON (UTF-8) en entrée et en sortie ; multipart/form-data pour l’envoi du PDF |
| Identifiants | préfixés : env_… (dossier), doc_… (document), sgn_… (signataire), fld_… (champ), evt_… (événement) |
| Dates | ISO 8601 avec fuseau, par exemple 2026-10-07T14:03:11+00:00 |
| Limite de débit | 60 requêtes par minute et par clé (ajustable sur demande), HTTP 429 au-delà |
| Hébergement | 100 % en France (OVH), aucune donnée hors de l’Union européenne |
| Référence OpenAPI | api.signoui.fr/v1/docs (interactive) et openapi.json (schéma brut, pour générer un client) |
Clés de test et clés réelles
Une clé sk_test_ crée des dossiers en mode test : aucun e-mail ni SMS ne part, rien n’est décompté, les liens de signature sont renvoyés dans la réponse pour automatiser vos tests de bout en bout, et les webhooks ne sont pas livrés (ils sont journalisés côté Signoui). Les dossiers de test et réels sont séparés : chaque clé ne voit que ceux de son mode.
Une clé sk_live_ fait tout pour de vrai : chaque signataire d’un dossier envoyé consomme un envoi du solde de votre organisation.
Portées d’une clé
Chaque clé a ses portées : envelopes:read, envelopes:write, documents:download. Une clé sans la portée nécessaire reçoit un 403 insufficient_scope. Les clés se créent et se révoquent dans l’espace client, rubrique Développeurs.
La clé API ne doit jamais se trouver dans le navigateur ni dans une application mobile : appelez l’API depuis votre serveur.
Le modèle en une minute
Un dossier (envelope) contient un document PDF, un ou plusieurs signataires, et des champs placés sur le document (au minimum un champ signature par signataire).
On crée le dossier en brouillon, on ajoute le PDF, les signataires et les champs, puis on l’envoie. Il est alors figé. Chaque signataire reçoit un lien unique, lit le document en entier, remplit ses champs, donne son consentement, puis saisit un code reçu par SMS ou par e-mail, qui vaut signature. Quand tout le monde a signé, Signoui scelle le PDF (signature PAdES, horodatage, page « Certificat de signature »), produit une archive de preuve et vous prévient par webhook.
Statuts d’un dossier
draft → pending → sealing → completed, ou bien :
declined: un signataire a refusé ;expired: le délai de signature est dépassé ;cancelled: vous avez annulé le dossier ;failed: incident de scellement, pris en charge par nos équipes.
Statuts d’un signataire
waiting (pas encore son tour, en circuit séquentiel) → notified → opened → consented → signed, ou declined.
Circuits
sequential: les signataires reçoivent l’invitation l’un après l’autre, dans l’ordre derank.parallel: tous la reçoivent en même temps.
Points d’entrée
GET /me
Retourne l’organisation, la clé utilisée et le solde d’envois. Pratique pour vérifier une clé et afficher le solde dans votre outil.
{
"organization_id": "org_01J8Q…",
"organization_name": "Martin Rénovation",
"billing_mode": "prepaid",
"sends_available": 47,
"api_key_id": "key_01J8Q…",
"api_key_name": "Site web",
"mode": "live",
"scopes": ["envelopes:read", "envelopes:write", "documents:download"]
}
sends_available : envois restants (envois offerts du mois et packs). null signifie illimité (compte API à facturation mensuelle). Un envoi correspond à un signataire d’un dossier envoyé, code SMS compris.
POST /envelopes
Crée un dossier en brouillon.
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
title |
texte, 300 caractères max. | oui | Titre affiché aux signataires (objet des e-mails) |
workflow |
sequential ou parallel |
non (défaut sequential) |
Ordre de signature |
message |
texte, 2 000 caractères max. | non | Message personnel dans l’e-mail d’invitation |
expires_in_days |
entier de 1 à 180 | non (défaut 30) | Délai de signature après l’envoi |
metadata |
objet JSON, 4 Ko max. | non | Vos propres références (identifiant CRM, numéro de devis…), renvoyées telles quelles |
reminders_enabled |
booléen | non (défaut true) |
Rappels automatiques par e-mail à J+3 et J+7 |
Réponse 201 : l’objet dossier. Accepte l’en-tête Idempotency-Key.
POST /envelopes/{id}/documents
Ajoute le PDF au dossier. Envoi en multipart/form-data, champ file. Un seul PDF par dossier, 20 Mo et 300 pages maximum, dossier en draft uniquement.
{
"id": "doc_01J8Q…",
"kind": "original",
"filename": "devis-2026-0412.pdf",
"sha256": "8090ce…",
"size_bytes": 184233,
"page_count": 3,
"created_at": "2026-10-07T14:01:52+00:00"
}
Conservez sha256 : c’est l’empreinte du document qui sera scellée et inscrite au journal de preuve.
POST /envelopes/{id}/signers
Ajoute un signataire.
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
full_name |
texte, 200 caractères max. | oui | Nom complet |
email |
oui | Unique dans le dossier | |
phone |
texte | si otp_channel vaut sms ou choice, ou si delivery vaut sms |
Format international, par exemple +33612345678 |
rank |
entier, 1 ou plus | non | Ordre en circuit séquentiel (défaut : à la suite). En parallèle, toujours 1 |
otp_channel |
sms, email, choice ou none |
non (défaut : réglage de l’organisation) | Canal du code qui vaut signature, voir ci-dessous |
delivery |
email, sms ou none |
non (défaut email) |
Comment le signataire reçoit son invitation, voir ci-dessous |
external_id |
texte, 100 caractères max. | si otp_channel vaut none |
Identifiant du signataire dans votre système, inscrit au dossier de preuve |
return_url |
URL https | non | Page de votre site où renvoyer le signataire après signature |
Canal du code (otp_channel)
sms(recommandé) : le code arrive par SMS, un canal indépendant de l’e-mail, ce qui renforce l’identification du signataire en cas de contestation.email: le code arrive par e-mail.choice: le signataire choisit SMS ou e-mail au moment de signer ; son choix est inscrit au journal de preuve. Téléphone requis.none: aucun code, réservé à la signature intégrée avec un signataire que vous avez déjà identifié.
Invitation (delivery)
email: lien de signature par e-mail, avec rappels à J+3 et J+7.sms: lien de signature par SMS.none: rien n’est envoyé ; vous ouvrez vous-même le lien dans votre site (voir Signature intégrée).
Réponse 201 : l’objet signataire (voir Objet dossier).
POST /envelopes/{id}/fields
Place un champ sur le document.
| Champ | Type | Description |
|---|---|---|
document_id, signer_id |
texte | Document et signataire concernés |
kind |
signature, initials, text, checkbox, date ou mention |
mention : texte à recopier, par exemple « Lu et approuvé » ; date est pré-remplie à la date de signature |
page |
entier, 1 ou plus | Numéro de page |
x, y, width, height |
nombres | En points PDF (1/72 de pouce), origine en bas à gauche de la page. Une page A4 mesure 595 × 842 points |
required |
booléen (défaut true) |
Champ obligatoire |
label |
texte, 200 caractères max. | Libellé affiché au signataire |
Exemple : une signature en bas à gauche de la page 3 se place avec "x": 60, "y": 80, "width": 180, "height": 60.
Chaque signataire doit avoir au moins un champ signature, sinon l’envoi est refusé (signature_field_missing). Un signataire ne peut remplir que ses propres champs.
POST /envelopes/{id}/send
Envoie le dossier à la signature. Le dossier est figé, l’empreinte du PDF est inscrite au journal, un envoi est décompté par signataire, puis le premier signataire (circuit séquentiel) ou tous les signataires (circuit parallèle) sont invités.
L’appel est idempotent : renvoyer un dossier déjà envoyé retourne le dossier tel quel. Accepte aussi l’en-tête Idempotency-Key.
Erreurs possibles :
402 credits_insufficient: solde insuffisant, le message indique combien d’envois manquent ;422 document_missing,signer_missingousignature_field_missing: le dossier est incomplet ;409 invalid_transition: le dossier n’est plus en brouillon.
En mode test, la réponse contient test_sign_urls, par exemple {"sgn_…": "https://app.signoui.fr/sign/…"}, pour ouvrir le parcours de signature dans un navigateur.
GET /envelopes et GET /envelopes/{id}
GET /envelopes?status=pending&limit=25&cursor=… liste vos dossiers du plus récent au plus ancien, filtrables par status. La pagination se fait par curseur : repassez next_cursor tel quel ; null signifie que vous êtes à la fin.
GET /envelopes/{id} retourne l’état complet d’un dossier : l’objet dossier.
Télécharger le PDF signé et la preuve
GET /envelopes/{id}/documents/{document_id}/download, avec la portée documents:download. Un dossier contient jusqu’à trois documents, repérés par kind dans documents[] :
kind |
Disponible | Contenu |
|---|---|---|
original |
dès l’ajout | Le PDF tel que vous l’avez fourni |
sealed |
statut completed |
Le PDF signé : champs incrustés, page « Certificat de signature » ajoutée, signature électronique PAdES visible dans Adobe Reader, horodatage. Content-Type: application/pdf |
evidence |
completed, declined ou expired, quelques secondes après |
Archive ZIP de preuve autoportante : PDF original et scellé, journal d’audit chaîné (JSON), certificats, jeton d’horodatage, ancrage OpenTimestamps, notice de vérification. Content-Type: application/zip |
Le PDF scellé est aussi vérifiable publiquement, sans compte, sur app.signoui.fr/verify.
POST /envelopes/{id}/cancel
Annule un dossier en draft ou pending. Corps facultatif : {"reason": "…"}. Les liens de signature deviennent inutilisables et les signataires qui n’ont pas signé sont prévenus. Les envois décomptés ne sont pas restitués.
GET /envelopes/{id}/events
Retourne le journal de preuve du dossier, dans l’ordre chronologique. Chaque événement est chaîné au précédent par une empreinte SHA-256 (prev_hash → hash) : on ne peut ni retirer ni modifier un événement sans casser la chaîne.
{
"id": "evt_…",
"seq": 12,
"type": "signer.signed",
"occurred_at": "2026-10-07T14:20:58+00:00",
"actor": "signer:sgn_…",
"signer_id": "sgn_…",
"ip": "92.184.x.x",
"user_agent": "Mozilla/5.0 (iPhone…)",
"data": { "document_sha256": "8090ce…", "identification": "email_link+otp_sms" },
"prev_hash": "…",
"hash": "…"
}
Principaux types : envelope.created, document.added, signer.added, field.added, envelope.sent, signer.notified, signer.embed_link_created, signer.opened, document.viewed (pages et temps de lecture), field.filled, signer.consented (texte et version du consentement), otp.sent, otp.failed, otp.verified, signer.signed, envelope.all_signed, envelope.sealed, timestamp.anchored, envelope.declined, envelope.expired, envelope.cancelled, reminder.sent, operator.unmasked (consultation de l’identité d’un signataire par notre support, motif inclus).
Objet dossier
{
"id": "env_01J8Q…",
"mode": "live",
"title": "Devis n° 2026-0412",
"status": "pending",
"workflow": "sequential",
"message": "Bonjour, voici le devis dont nous avons parlé.",
"metadata": { "crm_id": "12345" },
"expires_at": "2026-11-06T14:03:11+00:00",
"sent_at": "2026-10-07T14:03:11+00:00",
"completed_at": null,
"closed_at": null,
"close_reason": null,
"created_at": "2026-10-07T14:01:40+00:00",
"documents": [
{ "id": "doc_…", "kind": "original", "filename": "devis.pdf", "sha256": "…",
"size_bytes": 184233, "page_count": 3, "created_at": "…" }
],
"signers": [
{ "id": "sgn_…", "rank": 1, "full_name": "Marie Dupont", "email": "marie.dupont@exemple.fr",
"phone": "+33612345678", "otp_channel": "sms", "status": "notified",
"notified_at": "…", "opened_at": null, "signed_at": null,
"declined_at": null, "decline_reason": null }
],
"fields": [
{ "id": "fld_…", "document_id": "doc_…", "signer_id": "sgn_…", "kind": "signature",
"page": 3, "x": 60, "y": 80, "width": 180, "height": 60,
"required": true, "label": null, "value": null, "filled_at": null }
],
"test_sign_urls": null
}
closed_at et close_reason sont renseignés pour les statuts declined, expired et cancelled. Après signature, fields[].value contient la valeur saisie (pour une signature : le nom tapé ou « tracé manuscrit »).
Webhooks
Signoui prévient votre serveur en temps réel par une requête POST en HTTPS. Les webhooks se gèrent dans l’espace client, rubrique Développeurs : URL, événements souscrits, et bouton « Tester » qui envoie un événement ping. Le secret de signature n’est affiché qu’une fois, à la création : conservez-le côté serveur.
Événements
| Type | Quand |
|---|---|
envelope.sent |
Le dossier est envoyé, le ou les premiers signataires sont invités |
signer.signed |
Un signataire a signé (le dossier passe au suivant ou au scellement) |
envelope.completed |
Tout le monde a signé : PDF scellé et archive de preuve disponibles |
envelope.declined |
Un signataire a refusé (motif dans signers[].decline_reason) |
envelope.expired |
Délai dépassé sans signature complète |
envelope.cancelled |
Dossier annulé (par l’API ou depuis l’espace client) |
ping |
Test manuel depuis l’espace client |
Souscrivez à * pour tout recevoir, à une liste précise, ou à un motif comme envelope.*.
Corps de la requête
{
"id": "job_01J8Q…",
"type": "envelope.completed",
"created_at": "2026-10-07T14:21:40+00:00",
"mode": "live",
"data": {
"envelope": {
"id": "env_01J8Q…",
"status": "completed",
"title": "Devis n° 2026-0412",
"signers": [{ "id": "sgn_…", "status": "signed", "rank": 1 }]
}
}
}
Le webhook est volontairement léger : il ne contient ni donnée personnelle ni document. À réception, appelez GET /envelopes/{id} pour l’état complet et, si le statut est completed, téléchargez les documents sealed et evidence.
Vérifier la signature (obligatoire)
| En-tête | Contenu |
|---|---|
Signoui-Event |
Type de l’événement |
Signoui-Delivery |
Identifiant unique de la livraison, pour dédoublonner |
Signoui-Signature |
t=<horodatage unix>,v1=<HMAC-SHA256 en hexadécimal> |
User-Agent |
Signoui-Webhooks/1.0 |
La signature vaut HMAC-SHA256(secret, "<t>." + corps brut). Vérifiez-la sur le corps brut, avant de le décoder, et refusez les livraisons dont t date de plus de 5 minutes, pour bloquer les rejeux.
Python (Flask, FastAPI, Django) :
import hmac, hashlib, time
def verify_signoui(secret: str, signature_header: str, raw_body: bytes, tolerance: int = 300) -> bool:
parts = dict(p.split("=", 1) for p in signature_header.split(","))
t, v1 = int(parts["t"]), parts["v1"]
if abs(time.time() - t) > tolerance:
return False
expected = hmac.new(secret.encode(), f"{t}.".encode() + raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, v1)
PHP :
<?php
function verify_signoui(string $secret, string $header, string $rawBody, int $tolerance = 300): bool {
parse_str(str_replace(',', '&', $header), $p); // ['t' => '…', 'v1' => '…']
if (abs(time() - (int) $p['t']) > $tolerance) return false;
$expected = hash_hmac('sha256', $p['t'] . '.' . $rawBody, $secret);
return hash_equals($expected, $p['v1']);
}
// $raw = file_get_contents('php://input');
// verify_signoui($secret, $_SERVER['HTTP_SIGNOUI_SIGNATURE'], $raw);
Node.js (avec Express, utilisez express.raw({ type: 'application/json' }) pour garder le corps brut) :
const crypto = require("crypto");
function verifySignoui(secret, header, rawBody, tolerance = 300) {
const p = Object.fromEntries(header.split(",").map((s) => s.split("=")));
if (Math.abs(Date.now() / 1000 - Number(p.t)) > tolerance) return false;
const expected = crypto.createHmac("sha256", secret).update(`${p.t}.`).update(rawBody).digest("hex");
return expected.length === p.v1.length &&
crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(p.v1));
}
Livraison et nouvelles tentatives
Répondez par un code 2xx en moins de 10 secondes ; si votre traitement est long, faites-le en arrière-plan. Toute autre réponse, ou un délai dépassé, déclenche de nouvelles tentatives espacées : 30 secondes, 2 minutes, 8 minutes, 32 minutes, puis 2 heures.
Après le cinquième échec, le webhook est désactivé et un événement webhook.disabled est enregistré ; réactivez-le depuis l’espace client une fois le problème corrigé. Une même livraison peut exceptionnellement arriver deux fois : dédoublonnez sur Signoui-Delivery.
L’URL doit être en HTTPS et publique (pas d’adresse de réseau privé), et les redirections ne sont pas suivies.
Signature intégrée
Votre client est déjà connecté sur votre site ou dans votre application ? Il peut signer sans en sortir. Trois réglages, cumulables :
- Pas d’invitation envoyée :
delivery: "none"à la création du signataire. Signoui n’envoie ni e-mail ni SMS : vous obtenez le lien vous-même. - Lien ouvert dans votre site : après l’envoi du dossier, demandez un lien de signature et affichez-le dans une iframe, ou redirigez-y votre client.
- Sans code (facultatif) :
otp_channel: "none"etexternal_id. Votre client lit, remplit, consent et confirme, sans code. Lisez d’abord ce que vous assumez.
POST /envelopes/{id}/signers/{signer_id}/sign-link
Corps facultatif : durée de validité de 5 minutes à 24 heures (60 minutes par défaut) et page de retour.
{ "ttl_minutes": 60, "return_url": "https://www.monsite.fr/merci" }
Réponse :
{
"url": "https://app.signoui.fr/sign/…",
"expires_at": "2026-10-08T10:12:00+00:00",
"signer_id": "sgn_…",
"mode": "embedded"
}
Conditions : le dossier est envoyé (pending) et c’est le tour de ce signataire (en circuit séquentiel). Chaque appel génère un nouveau lien et rend le précédent inutilisable ; le lien envoyé par e-mail, s’il existe, reste valable. Le lien est personnel : générez-le au moment où votre client est connecté chez vous, et ne le transmettez pas ailleurs.
Dans une iframe
Déclarez d’abord vos domaines dans l’espace client, rubrique Paramètres, « Signature intégrée : domaines autorisés » (par exemple https://www.monsite.fr, un par ligne). Sans cela, les navigateurs refusent d’afficher la page de signature dans une iframe. Ensuite :
<iframe src="URL_RETOURNÉE_PAR_SIGN_LINK" title="Signature du document"
style="width:100%;height:720px;border:0" allow="clipboard-write"></iframe>
<script>
window.addEventListener("message", function (e) {
if (e.origin !== "https://app.signoui.fr") return; // n'écoutez que Signoui
if (e.data && e.data.type === "signoui:signed") {
// e.data.envelope_id, e.data.signer_id,
// e.data.envelope_status : "pending" ou "completed"
// Masquez l'iframe et affichez votre confirmation.
}
});
</script>
Sur mobile, affichez l’iframe en pleine largeur (la page est conçue à partir de 390 pixels) ou préférez la redirection. La page de signature fonctionne sans cookie tiers, y compris dans Safari et en navigation privée.
Par redirection
Redirigez votre client vers l’URL obtenue. À la fin, si un return_url est défini (à la création du signataire ou dans l’appel sign-link), un bouton « Revenir sur le site » s’affiche et le retour se fait automatiquement après 2,5 secondes.
Ne considérez pas le retour sur votre site comme la preuve de la signature : votre client peut fermer la page avant. La source de vérité est le webhook signer.signed (ou GET /envelopes/{id}).
Signature sans code : ce que vous assumez
Avec otp_channel: "none", Signoui ne vérifie plus l’identité du signataire par un second canal : c’est vous qui l’avez identifié, par son compte chez vous. La preuve le dit explicitement : identification: "delegated_to_sender" et votre external_id dans le journal, mention « identification déléguée à l’émetteur » sur le certificat. La lecture complète, le consentement, l’horodatage, l’adresse IP et le scellement restent identiques.
En cas de contestation, la solidité de la signature dépend alors de votre propre authentification (mot de passe seul, double authentification…), que vous devrez pouvoir démontrer. C’est un choix courant pour des devis et contrats entre un professionnel et un client déjà identifié. Pour les engagements importants, gardez le code SMS (otp_channel: "sms"), qui fonctionne aussi en signature intégrée. Cette option est encadrée par nos conditions générales d’utilisation.
Idempotence
Sur POST /envelopes et POST /envelopes/{id}/send, passez un en-tête Idempotency-Key : une chaîne unique de votre choix, par exemple votre numéro de devis. Rejouer la même requête dans les 24 heures renvoie la réponse d’origine, sans rien recréer ni renvoyer. Réutiliser la même clé avec un corps différent donne une erreur 409 idempotency_mismatch.
C’est ce qui vous permet de relancer sans risque un appel qui a échoué sur un problème réseau : jamais deux dossiers, jamais deux invitations.
Erreurs
Toutes les erreurs ont la même forme :
{
"error": {
"code": "credits_insufficient",
"message": "Solde insuffisant : 2 envois nécessaires (un par signataire), 1 disponible. Achetez un pack d'envois.",
"param": null
}
}
| HTTP | code |
Signification |
|---|---|---|
| 401 | missing_api_key, invalid_api_key |
Clé absente, inconnue ou révoquée |
| 402 | credits_insufficient, organization_suspended |
Solde d’envois insuffisant ; organisation suspendue |
| 403 | insufficient_scope |
La clé n’a pas la portée requise |
| 404 | not_found, document_not_found |
Ressource inexistante, ou appartenant à une autre organisation (même réponse, volontairement) |
| 409 | invalid_transition, signer_duplicate, rank_taken, idempotency_mismatch |
Action impossible dans l’état actuel |
| 422 | validation_error, document_missing, signer_missing, signature_field_missing |
Entrée invalide (param indique le champ en cause) |
| 429 | rate_limited |
Trop de requêtes : attendez une minute avant de réessayer |
Bonnes pratiques
- Vérifiez ce qui a été signé. Gardez le
sha256du document envoyé et comparez-le àdata.document_sha256de l’événementsigner.signeddu journal : c’est la preuve que le document signé est bien celui que vous avez envoyé. - Archivez la preuve chez vous. Téléchargez l’archive
evidencedèsenvelope.completed. Signoui la conserve 10 ans, mais la preuve vous appartient. - Séparez test et production. Une clé
sk_test_en développement et en recette, une clésk_live_distincte en production, chacune avec les seules portées nécessaires. - Préférez le code SMS (
otp_channel: "sms") : un second canal, indépendant de l’e-mail, renforce l’identification du signataire. - Gardez la clé sur votre serveur, jamais dans une page web ni une application mobile.
- Rendez vos appels rejouables avec
Idempotency-Key, et traitez les webhooks en arrière-plan.
Limites
| Limite | Valeur |
|---|---|
| Taille du PDF | 20 Mo et 300 pages maximum, un PDF par dossier |
metadata |
4 Ko maximum |
| Débit | 60 requêtes par minute et par clé |
| Délai de signature | 1 à 180 jours |
| Langue | E-mails, SMS et pages de signature en français |
Une question technique, un besoin de débit plus élevé ou un compte API facturé au mois ? Écrivez-nous, un développeur vous répond.
Dernière mise à jour : .