דלגו לתוכן

Webhooks

Bona Fide שולחת בקשת HTTPS מסוג POST לנקודת הקצה שלכם על כל אירוע מעטפה שנרשמתם אליו. המשלוחים פועלים לפי המפרט Standard Webhooks, כך שכל אחת מהספריות שלו יכולה לאמת אותם.

בהגדרות › Webhooks, או עם מפתח API שיש לו את ההרשאה org:manage:

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"]
}'

התגובה כוללת את secret (whsec_…), רק הפעם הזו. רשימת events ריקה נרשמת לכל האירועים. כתובת ה-URL חייבת להיות ציבורית ולהתחיל ב-https://. נקודת קצה שייכת למצב אחד: נקודות קצה שנוצרו עם מפתח בדיקה מקבלות רק אירועים של מעטפות במצב בדיקה, ונקודות קצה חיות מקבלות רק אירועים חיים.

PATCH /v1/webhook-endpoints/{id} משנה את כתובת ה-URL, את האירועים או את התיאור, ומשהה או מחדש את נקודת הקצה (enabled). POST /v1/webhook-endpoints/{id}/test שולח פינג webhook.test.

סוג מתי
envelope.created המעטפה נוצרה
envelope.ready המסמך רונדר והמעטפה מוכנה לנמענים שלה
recipient.sent הגיע תורו של נמען (ובמסירה באימייל, הקישור שלו נשלח)
recipient.viewed נמען פתח את דף החתימה בפעם הראשונה
recipient.signed נמען שלח (או נחתם חתימה נגדית אוטומטית)
recipient.declined נמען סירב
envelope.completed כל הנמענים סיימו. data.values כולל את המשתנים וכל ערך שהוזן
envelope.sealed ה-PDF הנעול מוכן להורדה
envelope.declined המעטפה הסתיימה כי נמען סירב
envelope.voided ביטלתם את המעטפה
envelope.expired expiresAt חלף לפני ההשלמה
signing_link.used מבקר התחיל מעטפה מקישור חתימה קבוע

acceptance.created שמור בסכמה ועדיין לא נפלט.

{
"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 הוא המעטפה המלאה בזמן האירוע. data.values קיים רק ב-envelope.completed: המשתנים ששלחתם, וערכי השדות של כל תפקיד לפי מזהה שדה.

כל משלוח כולל:

כותרת ערך
webhook-id מזהה האירוע (evt_…); זהה בכל ניסיון חוזר. משמש למניעת כפילויות
webhook-timestamp שניות Unix ברגע שבו הניסיון הזה נחתם
webhook-signature v1,<base64 HMAC-SHA256>, מופרדים ברווח כשיותר מסוד אחד חותם
user-agent BonaFide-Webhooks/1

החתימה היא HMAC-SHA256 על {webhook-id}.{webhook-timestamp}.{raw body}, כשהמפתח הוא החלק של הסוד שאחרי whsec_, אחרי פענוח base64. יש לאמת את הגוף הגולמי (לפני ניתוח ה-JSON), להשוות בזמן קבוע, ולדחות חותמות זמן שרחוקות ביותר מחמש דקות מהשעון שלכם.

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);
});

משלוח מצליח בכל תגובת 2xx תוך 10 שניות. הפניות (redirects) לא נעקבות. כל דבר אחר מנוסה שוב עם השהיה הולכת וגדלה: אחרי 5 שניות, 5 דקות, 30 דקות, שעתיים, 5 שעות, 10 שעות, 14 שעות, 20 שעות ו-24 שעות, לכל היותר שלושה ימים אחרי האירוע. אחר כך המשלוח מסומן כנכשל.

  • עונים מהר ומעבדים באופן אסינכרוני; מונעים כפילויות לפי webhook-id.
  • משלוחים יכולים להגיע שלא לפי הסדר: בודקים את data.envelope.status במקום להניח רצף מסוים.
  • GET /v1/webhook-endpoints/{id}/deliveries מציג ניסיונות אחרונים עם קודי סטטוס, שגיאות ותזמונים, וכל נקודת קצה מציגה את שיעור ההצלחה שלה ב-24 השעות האחרונות (health).
  • POST /v1/events/{id}/redeliver שולח אירוע לנקודת קצה שוב, למשל אחרי השבתה.

POST /v1/webhook-endpoints/{id}/secret/rotate מחזיר סוד חדש מיד. במשך 24 השעות הבאות כל משלוח נחתם גם בסוד החדש וגם בישן (שתי רשומות ב-webhook-signature), כך שאפשר לפרוס את הסוד החדש בלי לאבד אירועים.