Agent skill

OneSpan Webhooks Skill

Receive and authenticate OneSpan Sign (e-signature) callback notifications. Use when setting up a OneSpan callback endpoint, checking the callback key sent as Authorization: Basic, debugging 401s, or handling events such as PACKAGE_COMPLETE, DOCUMENT_SIGNED, SIGNER_COMPLETE and PACKAGE_DECLINE.

Install this skill

npx skills add hookdeck/webhook-skills --skill onespan-webhooks


OneSpan Sign sends JSON callback notifications (webhooks) to a URL you register whenever something happens to a package (a "transaction" in the new experience): created, sent, signed, completed, declined and so on. Payloads are not signed. The only authentication is the callback key you register, sent back in the Authorization header.

When to Use This Skill

  • How do I receive OneSpan Sign callback notifications?
  • How do I verify the OneSpan callback key in the Authorization: Basic header?
  • Does OneSpan sign webhook payloads? (No: shared callback key only)
  • Why does my OneSpan callback endpoint return 401?
  • How do I handle PACKAGE_COMPLETE, DOCUMENT_SIGNED or SIGNER_COMPLETE events?

Verification (core)

The callback key is passed as Authorization: Basic {callbackKey}. That is the raw key, NOT base64(user:pass), so don't decode it as HTTP Basic. Store the whole header value (including the Basic prefix) as ONESPAN_AUTHORIZATION and compare the whole Authorization header to it:

const crypto = require('crypto');

// Hash both sides: equal-length buffers, so timingSafeEqual never throws.
function safeEqual(a, b) {
  const ha = crypto.createHash('sha256').update(String(a)).digest();
  const hb = crypto.createHash('sha256').update(String(b)).digest();
  return crypto.timingSafeEqual(ha, hb);
}

function verifyOneSpanRequest(headers, expected = process.env.ONESPAN_AUTHORIZATION) {
  if (!expected) return false;                  // never accept when unconfigured
  const received = headers['authorization'];    // full value, e.g. "Basic myCallbackKey"
  return Boolean(received) && safeEqual(received, expected);
}

Return 401 when this fails (missing header or mismatch), 400 for a body that isn't a JSON object, and 2xx once handled. Read the body raw (express.raw({ type: '*/*' })) so any content type works, and parse JSON only after the credential check. Python and Next.js equivalents are in references/verification.md.

What this does and doesn't give you: a static shared credential authenticates the sender, not the body, and gives no replay protection (there is no signature and no timestamp). Use HTTPS, treat the callback key like a password, and rotate it if it leaks (register a new key with POST /api/callback or in the UI).

For complete handlers with tests, see examples/express/, examples/nextjs/, examples/fastapi/.

Event Types

The event type is the name field in the JSON body. Documented events:

EventMeaning
PACKAGE_CREATEPackage created
PACKAGE_ACTIVATEPackage moved from DRAFT or DELETED to SENT
DOCUMENT_SIGNEDA document was signed, or consent/disclosure accepted (documentId set)
SIGNER_COMPLETEA signer finished all documents
PACKAGE_COMPLETEPackage completed signing (sessionUser is the last signer)
PACKAGE_DECLINEA recipient declined; message holds the reason
EMAIL_BOUNCEEmail bounced; message holds the bounce type

Others: COBROWSE_REQUEST, DOCUMENT_VIEWED, KBA_FAILURE, PACKAGE_ARCHIVE, PACKAGE_ATTACHMENT, PACKAGE_DEACTIVATE, PACKAGE_DELETE, PACKAGE_DISPUTE, PACKAGE_EXPIRE, PACKAGE_READY_FOR_COMPLETE, PACKAGE_RESTORE, PACKAGE_TRASH, RECORDINGS_READY, ROLE_REASSIGN, SIGNER_LOCKED, TEMPLATE_CREATE and the eOriginal events EDEPOSIT_SUCCESS, EDEPOSIT_FAILURE, EDEPOSIT_FAILURE_ATTEMPT. See references/overview.md.

Body fields: name, sessionUser, packageId, documentId, message, createdDate (the docs show ISO strings and, for eDeposit events, epoch milliseconds).

Environment Variables

ONESPAN_AUTHORIZATION=Basic myCallbackKey   # full header value: "Basic " + your callback key

Local Development

npx hookdeck-cli listen 3000 onespan --path /webhooks/onespan

No account required. Use the printed URL as the callback URL in OneSpan Sign.

Resources


Repository

hookdeck/webhook-skills

v0.1.0 · MIT · Updated Nov 3, 2026

View on GitHub →