Skip to content

Signing webhooks

Add endpoints under Signing → Webhooks in the console. Each endpoint has its own signing secret (whsec_…), shown once when you add it.

Type When
signing_request.created A request was created.
signing_request.accepted The signer accepted and a code was sent.
certificate.issued A first-time signer’s certificate was issued, just before signing.
signing_request.completed Every document is signed. Download them now.
signing_request.declined The signer declined.
signing_request.canceled You canceled the request.
signing_request.expired Nobody acted before it expired.
signing_request.failed Too many wrong codes (code_attempts_exhausted), or signing could not be completed (signing_failed). Nothing was signed.
ping You pressed Send test.
{
"id": "evt_4f0c...",
"object": "event",
"type": "signing_request.completed",
"livemode": false,
"created_at": "2026-09-28T10:12:44Z",
"data": { "object": { "id": "sr_0c5e...", "object": "signing_request", "status": "completed", "...": "..." } }
}

data.object is the signing request as GET /v1/signing-requests/{id} returns it, without its client_secret. Events never carry the documents: fetch them from each document’s content_url.

Each delivery carries three headers:

Header Value
ePahichan-Signature t=<unix time>,v1=<hex>
ePahichan-Event The event’s type
ePahichan-Delivery This delivery’s id

v1 is the hex HMAC-SHA256, keyed with the endpoint’s signing secret, of the timestamp, a full stop and the raw request body: "<t>.<body>". Compute it over the body exactly as received, before any JSON parsing, compare in constant time, and reject a timestamp more than five minutes away from your clock. The loan system guide has the check in Node.js, Python and Java.

  • Answer with any 2xx within 10 seconds. Do the work after answering if it takes longer.
  • Anything else is retried after 30 seconds, 1, 5, 15 and 30 minutes, then hourly and every two hours, for 24 hours.
  • An endpoint failing for 24 hours is turned off. Turn it back on in the console once it is fixed.
  • A delivery may arrive more than once, and events may arrive out of order. Deduplicate by the event’s id, and read the request’s current status rather than assuming an order.
  • In the console, each endpoint’s Attempts lists what was sent and what your endpoint answered.