BunnyDoc
APIAPI de signature électronique

API de signature électronique

Envoyez des documents à signer directement depuis vos propres systèmes : échangez une clé d'API contre un jeton, créez des enveloppes à partir de modèles, gérez des contacts et récupérez les liens de signature via une API REST simple.

L'API de signature électronique permet à votre application de faire ce que votre équipe fait dans l'app : transformer un modèle en demande de signature, l'envoyer et la suivre jusqu'à un PDF signé et horodaté avec piste d'audit, sans que personne n'ouvre BunnyDoc.

C'est une API REST réduite et ciblée. JSON en entrée, JSON en sortie, un seul jeton porteur et exactement les mêmes permissions que celles dont votre équipe dispose déjà dans l'app.

URL de base

Tous les endpoints se trouvent sous https://api2.bunnydoc.com/v1. Tous les chemins de ces pages sont relatifs à cette base.

Comment fonctionne l'authentification

L'accès se fait en deux étapes, et c'est la première chose à mettre en place. Votre clé d'API à longue durée de vie est envoyée une seule fois pour obtenir un jeton d'accès à courte durée de vie ; toutes les autres requêtes ne transportent que le jeton, de sorte que la clé ne circule plus jamais.

Créez une clé d'API

Dans l'app, ouvrez Paramètres → Clés d'API (propriétaire ou administrateur uniquement) et créez une clé. Elle ressemble à bd_live_… et n'est affichée qu'une seule fois, à la création : copiez-la en lieu sûr. Elle ne peut ensuite plus être récupérée, seulement renouvelée.

Échangez la clé contre un jeton d'accès

Envoyez votre clé à POST /v1/auth/token. Vous recevez un jeton porteur valable une heure.

Appelez l'API avec le jeton

Envoyez Authorization: Bearer <token> sur toutes les autres requêtes. Mettez le jeton en cache et réutilisez-le jusqu'à son expiration ; n'en générez pas un nouveau à chaque appel.

Gardez votre clé d'API côté serveur

Une clé d'API agit au nom de toute votre entreprise. Ne l'intégrez jamais dans un navigateur, une app mobile ou un client que vous ne contrôlez pas. Si une clé est exposée, révoquez-la dans Paramètres → Clés d'API et créez-en une nouvelle : la révocation invalide immédiatement ses jetons en cours, alors que le renouvellement les laisse valables le reste de leur heure.

Construisez dans cet ordre

Une intégration complète, c'est cinq appels. Faites-les dans cet ordre et vous rencontrerez les pièges là où ils coûtent le moins cher : un 404 sur un modèle que vous pouvez lire, pas un 422 sur un envoi que vous vouliez livrer.

Trouvez le modèle à envoyer

GET /v1/templates pour le localiser, puis GET /v1/templates/{id} pour lire ses rôles. En pratique, ce second appel n'est pas optionnel : il vous indique quels rôles remplir et lesquels sont verrouillés.

Décidez qui l'envoie

Omettez sender_email pour envoyer au nom du propriétaire de la clé, ou appelez GET /v1/users pour laisser votre interface choisir un collègue. Envoyer au nom de quelqu'un d'autre utilise ses permissions, pas celles du propriétaire de la clé.

Envoyez

POST /v1/envelopes/from-template. Crée et envoie en un seul appel ; si l'envoi échoue, rien ne subsiste. Conservez l'envelope_id renvoyé.

Abonnez-vous à la suite

POST /v1/webhooks : l'API n'a volontairement aucun endpoint de statut d'enveloppe. Récupérez le PDF final depuis envelope.document_ready.

Les endpoints en un coup d'œil

Chaque requête est autorisée à la fois par le scope de votre clé et par la permission de l'utilisateur qui la possède : une clé ne peut jamais faire plus que ce que cette personne peut faire dans l'app.

Pour faire ceciEndpointScope
Échanger une clé d'API contre un jetonPOST /v1/auth/token—
Lister vos modèlesGET /v1/templatestemplates:read
Obtenir un modèle et ses rôlesGET /v1/templates/{id}templates:read
Lister les contactsGET /v1/contactscontacts:read
Créer un contactPOST /v1/contactscontacts:write
Créer une enveloppe à partir d'un modèle et l'envoyerPOST /v1/envelopes/from-templateenvelopes:send
Récupérer les liens de signature d'une enveloppe envoyéeGET /v1/envelopes/{id}/signing-linksenvelopes:send
Lister les membres de l'entrepriseGET /v1/usersusers:read
Lister les événements auxquels vous pouvez vous abonnerGET /v1/webhooks/eventswebhooks:read
Lister vos abonnements webhookGET /v1/webhookswebhooks:read
Abonner un endpoint à des événementsPOST /v1/webhookswebhooks:write
Désabonner un endpointDELETE /v1/webhooks/{id}webhooks:write

Vous voulez être notifié lorsqu'un document est signé, refusé ou annulé plutôt que d'interroger l'API ? Utilisez les webhooks — et récupérez le PDF final directement dans la charge utile de envelope.document_ready.

Conventions

  • JSON en entrée, JSON en sortie — envoyez et attendez application/json.
  • Limité à votre entreprise — chaque ressource appartient à une entreprise, et les requêtes ne franchissent jamais les frontières entre entreprises.
  • Les mêmes permissions que l'app — une clé ne peut faire que ce que le rôle de son propriétaire autorise. Voir Utilisateurs et rôles.
  • Les scopes restreignent l'accès — les scopes d'une clé (templates:read, contacts:read, contacts:write, envelopes:send, webhooks:read, webhooks:write, users:read) ne peuvent que limiter ce que son propriétaire pouvait déjà faire, jamais l'étendre.

Pagination

Les endpoints de liste acceptent page (à partir de 1) et per_page (jusqu'à 100, 25 par défaut), et renvoient un objet pagination :

{
  "data": [ /* … */ ],
  "pagination": { "page": 1, "per_page": 25, "total": 134, "total_pages": 6 }
}

Quotas

Les lectures ne consomment rien sur votre offre. Deux choses sont mesurées :

  • Envoyer consomme l'allocation distincte de demandes de signature API : une unité par enveloppe, quel que soit le nombre de destinataires. Ce n'est pas le même compteur que les enveloppes envoyées depuis l'app. Une fois épuisée, les envois renvoient 402 quota_exceeded et rien n'est livré.
  • Créer un contact consomme l'allocation de contacts ordinaire de votre offre, et renvoie 403 quota_exceeded lorsqu'elle est pleine. Vous n'avez pas besoin de créer des contacts pour leur envoyer des documents, c'est donc facile à éviter.

Vérifiez les deux dans Paramètres → Facturation → Ressources.

Limites de débit

Les requêtes sont limitées par clé d'API (l'endpoint du jeton, par IP). Dépasser une limite renvoie 429 rate_limited avec un en-tête standard Retry-After en secondes : patientez ce délai puis réessayez.

LimitePortée
20 échanges de jeton / 15 minpar IP
100 envois / 15 minpar clé d'API
1000 autres requêtes / 15 minpar clé d'API

Compter par clé (et non par IP) signifie qu'une adresse de sortie partagée — une plateforme d'intégration, un NAT — ne fait jamais compter le trafic d'un client contre celui d'un autre.

Erreurs

Toutes les erreurs ont la même forme : basez-vous sur error.code, jamais sur le texte du message. Voir la référence des erreurs complète.

{
  "error": {
    "code": "unknown_signer_role",
    "message": "…",
    "details": { },
    "reference": "0190f3a2-7b6c-7e21-9a3f-2c9b1d4e5f60"
  }
}

reference apparaît sur les erreurs que nous journalisons côté serveur (5xx et 422). Conservez-la dans vos propres logs : nous la citer permet de retrouver l'échec exact en une seule recherche.

Guides associés

Sur cette page