Signlift

Webhooks

Recevez les événements en temps réel et vérifiez les signatures HMAC.

À chaque événement notable (notification d'un signataire, OTP envoyé, signature acquise, demande complétée ou expirée), Signlift POSTe un payload JSON signé HMAC-SHA256 sur l'URL configurée pour votre application externe.

Configuration

L'URL de webhook est configurée par application externe dans le dashboard, au moment où vous créez votre clé API. Le webhook_secret est affiché une seule fois — stockez-le aux côtés de votre clé API.

Événements

Cinq types d'événements sont émis vers les webhooks aujourd'hui :

EventDéclencheur
signer.notifiedNotification d'invitation envoyée à un signataire.
signer.otp_sentOTP envoyé à un signataire (e-mail ou SMS).
signer.signedUn signataire a finalisé sa signature.
request.completedTous les signataires ont signé.
request.expiredLa demande a dépassé sa fenêtre de validité.

Headers

Chaque requête entrante porte trois headers Signlift :

HeaderContenu
X-Signlift-EventType d'événement (ex. request.completed).
X-Signlift-DeliveryIdentifiant unique de la tentative de livraison. Idempotence côté client.
X-Signlift-SignatureSignature HMAC-SHA256 du body, format sha256=<hex>.

Le Content-Type est toujours application/json.

Format du payload

{
  "event": "request.completed",
  "occurred_at": "2026-05-17T15:12:43Z",
  "signature_request": {
    "id": 42,
    "status": "completed",
    "mode": "sequential"
  },
  "signer": {
    "id": 1768,
    "first_name": "Jeanne",
    "last_name": "Dupont",
    "full_name": "Jeanne Dupont",
    "email": "jeanne@example.com",
    "status": "signed"
  }
}
  • event : type d'événement (identique au header X-Signlift-Event).
  • occurred_at : horodatage ISO 8601 UTC.
  • signature_request : toujours présent — id, status, mode.
  • signer : présent uniquement pour les événements liés à un signataire (signer.notified, signer.otp_sent, signer.signed).

Les détails complets d'une demande (signataires, documents, URLs signées) ne sont pas inclus dans le payload — récupérez-les via GET /api/v1/signature_requests/:id.

Vérification HMAC

Le header X-Signlift-Signature contient la signature HMAC-SHA256 du body brut (avant tout parsing JSON), encodée en hexadécimal et préfixée par sha256=.

require "openssl"
require "active_support/security_utils"

def verify_signlift_webhook(raw_body, header, secret)
  expected = "sha256=" + OpenSSL::HMAC.hexdigest("SHA256", secret, raw_body)
  ActiveSupport::SecurityUtils.secure_compare(expected, header.to_s)
end
import crypto from "node:crypto"

function verifySignliftWebhook(rawBody, header, secret) {
  const expected =
    "sha256=" + crypto.createHmac("sha256", secret).update(rawBody).digest("hex")
  const a = Buffer.from(expected)
  const b = Buffer.from(header || "")
  return a.length === b.length && crypto.timingSafeEqual(a, b)
}
import hmac
import hashlib

def verify_signlift_webhook(raw_body: bytes, header: str, secret: str) -> bool:
    expected = "sha256=" + hmac.new(
        secret.encode(), raw_body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, header or "")

Retry policy

Si votre endpoint répond avec un code HTTP ≠ 2xx, est injoignable, ou met plus de 10 secondes à répondre, Signlift réessaie selon le calendrier suivant :

TentativeDélai depuis l'échec précédent
11 minute
25 minutes
325 minutes
42 heures
510 heures

Soit 5 retries au total, sur environ 13 h 30. Après 5 échecs, la livraison est marquée failed et n'est plus retentée automatiquement.

Idempotence côté client

Votre handler doit être idempotent : un même événement peut être livré plusieurs fois (échec puis retry, double notification réseau, etc.).

Utilisez X-Signlift-Delivery comme clé de déduplication — chaque tentative porte un identifiant unique, persistez-le côté votre app.

delivery_id = request.headers["X-Signlift-Delivery"]
return head :ok if WebhookEvent.exists?(delivery_id: delivery_id)
WebhookEvent.create!(delivery_id: delivery_id, ...)

On this page