Développeurs · API · Webhooks

Un POST. Envoyé pour signature.

Une API REST pour envoyer des PDF à signer et suivre chaque signataire, des webhooks signés pour chaque étape, des clés d'idempotence et des codes d'erreur stables. Les clés API et les webhooks sont inclus dans l'offre Enterprise.

Ce que vous pouvez construire : des signatures depuis votre propre logiciel
curl https://api.wesign.now/v1/signing-requests \
  -H "Authorization: Bearer $WSK_KEY" \
  -H "Idempotency-Key: order-123/sign" \
  -F "file=@contract.pdf" \
  -F 'signers=[{"email":"jane@acme.com","role":"client"}]' \
  -F "placement=auto_append"

# → 201 Created
# {
#   "documentId": "8a1e4f9a-…",
#   "status": "pending",
#   "signers": [{
#     "role": "client",
#     "signingUrl": "https://acme.wesign.now/en/sign/…",
#     "emailed": true, …
#   }], …
# }
Ce que vous obtenez

Une API, des webhooks et une documentation que vos outils savent lire.

API REST

Envoyez un PDF, suivez chaque signataire, relancez ou retirez la demande, téléchargez le PDF scellé et sa piste d'audit. Clés Bearer, réponses JSON et une spécification OpenAPI 3.1 avec un identifiant pour chaque opération.

Vue d'ensemble de l'API

Webhooks signés

signing_request.sent, .viewed, .signed, document.completed et d'autres, chacun signé en HMAC-SHA256. Une livraison échouée est retentée pendant environ 45 heures ; le journal des livraisons vous permet de la renvoyer.

Événements webhook

Documentation pour assistants IA

llms.txt liste chaque page de la documentation, llms-full.txt les contient toutes en texte brut, et openapi.json la forme exacte des requêtes et des réponses. Donnez-les à votre assistant de code.

Pour les assistants IA

Exemples concrets.

Quatre appels dont la plupart des intégrations ont besoin. Noms de champs tels que dans la spécification OpenAPI.

1. Envoi avec placement par ancre

Placez un marqueur comme [[ls:signature:buyer]] dans votre PDF. Nous y plaçons le champ de signature de l'acheteur et masquons le marqueur. Pas de marqueur dans le PDF ? Nous ajoutons une page de signature.

POST /v1/signing-requests
Content-Type: multipart/form-data

file=@offer.pdf        # the PDF contains [[ls:signature:buyer]]
signers=[{"email":"buyer@acme.com","role":"buyer","name":"Ann Buyer"}]
placement=anchors

2. Plusieurs signataires, dans l'ordre

Trois signataires, l'un après l'autre. Le signataire 2 n'est invité qu'une fois que le signataire 1 a signé.

POST /v1/signing-requests
Content-Type: multipart/form-data

file=@contract.pdf
signing_mode=sequential
placement=auto_append
signers=[
  {"email":"founder@acme.com","role":"founder"},
  {"email":"investor@vc.example","role":"investor"},
  {"email":"witness@law.example","role":"witness"}
]

3. Récepteur de webhook

Vérifiez l'horodatage et le HMAC sur le corps brut, puis traitez l'événement.

// Node + Express. The full verifier (Node and PHP) is in the docs.
app.post('/wesign/callback', express.raw({ type: 'application/json' }), (req, res) => {
  // X-WeSign-Signature: t=<unix seconds>,v1=<hex>  (two v1 for 24 h after a rotation)
  const parts = (req.get('x-wesign-signature') ?? '').split(',')
  const t = parts[0]?.startsWith('t=') ? parts[0].slice(2) : ''
  if (!t || Math.abs(Date.now() / 1000 - Number(t)) > 300) return res.status(401).end()
  const expected = crypto.createHmac('sha256', SECRET)
    .update(`${t}.${req.body}`).digest()
  const valid = parts.filter((p) => p.startsWith('v1=')).some((p) => {
    const got = Buffer.from(p.slice(3), 'hex')
    return got.length === expected.length && crypto.timingSafeEqual(got, expected)
  })
  if (!valid) return res.status(401).end()

  const evt = JSON.parse(req.body.toString('utf8'))
  if (evt.event === 'document.completed') {
    // fetch evt.signed_pdf_url with your API key, compare evt.sha256, keep a copy
  }
  res.sendStatus(200)
})

4. Réessai idempotent

La même clé avec le même corps dans les 24 heures rejoue la première réponse : un réessai après une erreur réseau n'envoie jamais deux fois.

POST /v1/signing-requests
Idempotency-Key: order-123/sign

# First call:                      201 Created
# Same key + same body (24 h):     201, the same body, Idempotent-Replayed: true
# Same key while the first runs:   409 idempotency_in_progress + Retry-After
# Same key + a different body:     422 idempotency_key_reuse
Recettes

Ce que vous pouvez construire aujourd'hui.

Chaque modèle utilise l'API REST et les webhooks. Les cartes renvoient à la documentation qui le décrit.

Non disponible : un SDK, un bac à sable ou des clés de test, ainsi que des applications ou plug-ins pour d'autres outils.

Conçu pour la production.

Clés Bearer, deux périmètres

Chaque clé appartient à un seul espace de travail. Une clé full appelle toute l'API ; une clé embedded gère uniquement les sessions de signature intégrée. Limitez une clé à vos adresses IP ; une révocation prend effet immédiatement.

60 requêtes par minute et par clé

Une fenêtre fixe par clé pour tous les endpoints /v1. Les réponses réussies portent les en-têtes RateLimit-* ; une 429 porte Retry-After.

Codes d'erreur stables

Chaque erreur est un JSON avec un message lisible (error), un code stable et, si utile, meta. Testez le code ; le message peut évoluer.

PDF scellés et vérifiables

Le PDF signé porte un sceau PAdES que tout lecteur conforme peut vérifier. La piste d'audit liste chaque événement avec son heure, l'adresse e-mail et l'adresse IP masquée du signataire, ainsi que chaque vérification par code SMS.

L'accès API est inclus dans Enterprise.

Les clés API et les webhooks font partie de l'offre Enterprise. Dites-nous ce que vous voulez connecter. La documentation est publique : vous pouvez la lire d'abord.