Signoui

Documentation de l'API Signoui

Tout pour envoyer des documents à signer depuis votre application, suivre les signatures en temps réel et récupérer les preuves. API REST en JSON, hébergée en France.

URL de base
https://api.signoui.fr/v1
Authentification
Authorization: Bearer sk_…
Schéma OpenAPI
openapi.json

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.

  1. Créez un compte sur app.signoui.fr (2 envois offerts par mois, sans carte bancaire).
  2. 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.
  3. Lancez le parcours complet ci-dessous, puis ouvrez le lien test_sign_urls renvoyé par l’envoi pour signer vous-même dans votre navigateur.
  4. 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 de rank.
  • 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 e-mail 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_missing ou signature_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 :

  1. 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.
  2. 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.
  3. Sans code (facultatif) : otp_channel: "none" et external_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 sha256 du document envoyé et comparez-le à data.document_sha256 de l’événement signer.signed du 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 evidence dès envelope.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 : .

Votre prochain devis, signé aujourd'hui.

Compte gratuit, sans carte bancaire. 2 envois par mois offerts avec code SMS, pour toujours.