Webhooks

Inbound webhook endpoints for BoldSign and DocuSign signature events.

FinDesk exposes two inbound webhook endpoints today. Both receive events from third-party signature providers — they are not general-purpose hooks you subscribe to and they do not require authentication via bearer token; instead each verifies a per-provider signature on the raw request body.

There is no outbound webhook delivery from FinDesk to your systems at this time.

BoldSign

POST https://app.findesk.com.au/api/webhooks/boldsign

Configure BoldSign to deliver document events to this URL. Set a webhook secret in BoldSign and provide the same value to FinDesk so it can validate signatures (config('boldsign.webhook_secret') on the FinDesk side).

Signature verification

Each request carries an X-BoldSign-Signature header. FinDesk recomputes:

HMAC-SHA256(raw_body, webhook_secret)   // hex-encoded

and rejects the request with 401 Unauthorized unless the recomputed value matches the header byte-for-byte (hash_equals).

Events handled

FinDesk extracts a documentId from the payload (data.documentId or top-level documentId) and matches it against BoldSignDocument records. The status on the matching record is updated based on the event:

Inbound event/status keyword Stored status
signed (without sent) or completed signed
declined declined
revoked revoked
viewed viewed
anything else sent

The first transition into signed, declined, or revoked also stamps the corresponding signed_at / declined_at / revoked_at timestamp.

Responses

Status Returned when
200 OK {"ok": true} Signature valid, payload processed (or documentId did not match a record FinDesk knows about — the call is acknowledged without changes).
401 Unauthorized Signature missing, mismatched, or no secret is configured.
422 Unprocessable Entity Payload contained no documentId.

DocuSign

POST https://app.findesk.com.au/api/webhooks/docusign

DocuSign Connect listens at this URL. The HMAC secret is stored per-team on teams.docusign_webhook_hmac_key, so signatures are validated against the team that owns the document referenced by the envelope.

Signature verification

The envelope ID is read from data.envelopeId, envelopeId, or data.envelopeSummary.envelopeId. FinDesk looks up the matching DocuSignDocument, then validates X-DocuSign-Signature-1 against:

base64( HMAC-SHA256(raw_body, team.docusign_webhook_hmac_key) )

Unmatched signatures return 401 Unauthorized. Envelopes that do not map to any FinDesk record are acknowledged with 200 OK and ignored.

Events handled

Only events whose event field starts with envelope- are acted on. The envelope status is normalised:

Inbound status Stored status
completed completed
declined declined
voided voided
delivered delivered
anything else sent

Documents that are already in a terminal status (completed, declined, voided) ignore further updates.

Responses

Status Returned when
200 OK {"ok": true} Signature valid, payload processed or safely ignored (unknown envelope, non-envelope event, terminal status already reached).
401 Unauthorized Signature missing or mismatched.
422 Unprocessable Entity Payload contained no envelope ID.

Operational notes

  • Both endpoints expect the raw, unmodified request body — proxies must not re-serialise JSON between the provider and FinDesk, or the HMAC will fail to verify.
  • Both endpoints are idempotent in practice: redelivering the same payload either re-applies the same final status or is short-circuited by the terminal-status guard (DocuSign).
  • Failed verifications are logged but not retried by FinDesk — your provider's own retry policy decides whether the call is repeated.