Ga naar inhoud

Webhooks

Bona Fide stuurt een HTTPS-POST naar uw endpoint voor elk envelopevent waarop u zich abonneert. Leveringen volgen de specificatie Standard Webhooks, dus elke bibliotheek daarvan kan ze verifiëren.

In Instellingen › Webhooks, of met een API-key die de scope org:manage heeft:

Terminal window
curl https://api.bonafidesign.com/v1/webhook-endpoints \
-H "Authorization: Bearer $BONA_FIDE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://app.example.com/hooks/bona-fide",
"description": "Production",
"events": ["envelope.completed", "envelope.sealed", "envelope.declined"]
}'

Het antwoord bevat secret (whsec_…), alleen deze ene keer. Een lege events-lijst abonneert op alle events. De URL moet een openbare https://-URL zijn. Een endpoint hoort bij één modus: endpoints die met een testkey zijn aangemaakt, ontvangen alleen events van enveloppen in testmodus, live endpoints alleen live events.

PATCH /v1/webhook-endpoints/{id} wijzigt de URL, de events of de beschrijving en pauzeert of hervat het endpoint (enabled). POST /v1/webhook-endpoints/{id}/test stuurt een webhook.test-ping.

Type Wanneer
envelope.created De envelop is aangemaakt
envelope.ready Het document is gerenderd en de envelop is klaar voor de ontvangers
recipient.sent Een ontvanger is aan de beurt (en bij bezorging per e-mail is de link verstuurd)
recipient.viewed Een ontvanger heeft de ondertekeningspagina voor het eerst geopend
recipient.signed Een ontvanger heeft ingediend (of is automatisch medeondertekend)
recipient.declined Een ontvanger heeft geweigerd
envelope.completed Alle ontvangers zijn klaar. data.values bevat de variabelen en alle ingevulde waarden
envelope.sealed De verzegelde pdf staat klaar om te downloaden
envelope.declined De envelop is beëindigd omdat een ontvanger heeft geweigerd
envelope.voided U hebt de envelop ingetrokken
envelope.expired expiresAt is verstreken vóór voltooiing
signing_link.used Een bezoeker is een envelop gestart via een permanente ondertekeningslink

acceptance.created is gereserveerd in het schema en wordt nog niet verstuurd.

{
"id": "evt_9sKq2Lm4Tz",
"type": "envelope.completed",
"createdAt": "2026-10-13T14:09:52.004Z",
"testMode": false,
"data": {
"envelope": {
"id": "env_8Gm2kQ4rT1",
"status": "completed",
"seal": "pending",
"recipients": [{ "id": "rcp_5Jw0pLs9Xe", "role": "client", "status": "completed", "…": "…" }],
"externalId": "user_8841",
"metadata": {},
"…": "…"
},
"values": {
"variables": { "client": { "name": "Acme Robotics, Inc." }, "effective_date": "2026-10-13" },
"recipients": {
"client": { "client_title": "CEO", "start_date": "2026-11-01" }
}
}
}
}

data.envelope is de volledige envelop op het moment van het event. data.values staat alleen in envelope.completed: de variabelen die u hebt verstuurd en de veldwaarden van elke rol per veld-id.

Elke levering bevat:

Header Waarde
webhook-id Het event-id (evt_…); bij elke nieuwe poging hetzelfde. Gebruik het om te ontdubbelen
webhook-timestamp Unix-seconden van het moment waarop deze poging is ondertekend
webhook-signature v1,<base64 HMAC-SHA256>, gescheiden door spaties als meer dan één geheim ondertekent
user-agent BonaFide-Webhooks/1

De handtekening is een HMAC-SHA256 over {webhook-id}.{webhook-timestamp}.{raw body}, met als sleutel het base64-gedecodeerde deel van het geheim na whsec_. Verifieer de ruwe body (vóór het parsen van de JSON), vergelijk in constante tijd en weiger tijdstempels die meer dan vijf minuten van uw klok afwijken.

import express from 'express';
import { Webhook } from 'standardwebhooks'; // npm i standardwebhooks
const wh = new Webhook(process.env.BONA_FIDE_WEBHOOK_SECRET!); // whsec_…
const app = express();
app.post('/hooks/bona-fide', express.raw({ type: 'application/json' }), (req, res) => {
let event;
try {
event = wh.verify(req.body, req.headers as Record<string, string>); // throws if forged or too old
} catch {
return res.sendStatus(400);
}
queue.add(event); // do the work asynchronously and answer quickly
res.sendStatus(204);
});

Een levering slaagt bij elke 2xx binnen 10 seconden. Redirects worden niet gevolgd. In alle andere gevallen wordt de levering met backoff opnieuw geprobeerd, na 5 seconden, 5 minuten, 30 minuten, 2 uur, 5 uur, 10 uur, 14 uur, 20 uur en 24 uur, tot maximaal drie dagen na het event. Daarna wordt de levering als mislukt gemarkeerd.

  • Antwoord snel en verwerk asynchroon; ontdubbel op webhook-id.
  • Leveringen kunnen in een andere volgorde binnenkomen: controleer data.envelope.status in plaats van uit te gaan van een vaste volgorde.
  • GET /v1/webhook-endpoints/{id}/deliveries toont recente pogingen met statuscodes, fouten en doorlooptijden, en elk endpoint toont het slagingspercentage over 24 uur (health).
  • POST /v1/events/{id}/redeliver stuurt een event opnieuw naar een endpoint, bijvoorbeeld na een storing.

POST /v1/webhook-endpoints/{id}/secret/rotate geeft direct een nieuw geheim terug. De volgende 24 uur wordt elke levering ondertekend met zowel het nieuwe als het oude geheim (twee vermeldingen in webhook-signature), zodat u het nieuwe geheim kunt uitrollen zonder events te missen.