Skip to main content

Webhooks

Webhooks notify your server when contract lifecycle events happen in SpotDraft. Register one or more HTTPS endpoints in Settings -> Developer settings -> Webhooks, choose the event types, and SpotDraft delivers an HTTP POST with a JSON payload.

Return a 2xx response quickly. Queue slow work so timeouts do not count as failed deliveries.

Retry behavior​

SpotDraft retries a delivery when your endpoint does not return a 2xx response, including timeouts and connection failures.

The first delivery is immediate. If it fails, SpotDraft schedules retries for that event at 5, 10, 20, 40, 80, then 160 minutes after the previous failed attempt. A worker picks up due retries about every minute, so the actual POST can land slightly after the scheduled time.

Each attempt waits up to 5 seconds to connect and 60 seconds for a response. A timeout counts as a failed delivery.

Retry and disablement are separate counters:

  • Every failed POST (the first attempt and later retries) increments a consecutive-failure counter on the webhook subscription. A successful delivery resets that counter to 0.
  • After 6 consecutive failed deliveries, SpotDraft disables the subscription. Any later scheduled retry is skipped, not sent.
  • For an endpoint that never returns 2xx, you receive 6 POSTs: the first delivery plus retries at 5, 10, 20, 40, and 80 minutes. The 160-minute retry is not delivered because the subscription is already disabled.

Re-enable the webhook in Settings -> Developer settings -> Webhooks after you fix the endpoint.

Because a retry can send the same event more than once, persist a dedupe key before you return 2xx and make downstream writes idempotent.

Delivery requirements​

  • Use HTTPS with a publicly trusted certificate.
  • Keep the endpoint publicly reachable from SpotDraft.
  • Support multiple webhook URLs per account when different systems need separate receivers.
  • Subscribe only to the event types your integration needs.
  • Acknowledge quickly and process downstream work asynchronously.

Verification​

Use X-SD-WEBHOOK-CONTENT-HASH for verification. Validate the raw request body with HMAC-SHA512 using the hmac_key returned by the HMAC key API.

import base64
import hashlib
import hmac

signature = hmac.new(
base64.b64decode(sample_hmac_key),
request.body,
digestmod=hashlib.sha512,
).hexdigest()

assert signature == request.headers["X-SD-WEBHOOK-CONTENT-HASH"]

Compare against the raw request body bytes before any JSON parsing or normalization.

Processing model​

Use this production shape:

  1. read the raw request body
  2. verify X-SD-WEBHOOK-CONTENT-HASH
  3. parse the JSON payload
  4. persist a delivery id, event id, payload hash, or other dedupe key
  5. enqueue downstream work
  6. return 2xx quickly
  7. let a worker update CRM, ERP, storage, warehouse, notification, or internal systems

Webhook delivery is a change signal. If downstream systems need the latest complete record, fetch the contract, document, metadata, or status from the API after receiving the event.

Reconciliation​

Keep webhooks as the primary path. Add a scheduled job that compares recent SpotDraft state with your internal records and repairs drift.

Do not poll every contract on a short interval just to detect lifecycle changes. Do not treat the webhook payload as the only durable source of truth. Do not run slow downstream writes inside the webhook request thread.

Common activity types​

Subscribe only to the events your integration needs. The values below are the only_for_activities options on POST /api/v2.1/public/webhooks/.

Contract lifecycle​

activity valueWhen it fires
CONTRACT_CREATEDA new contract is created
CONTRACT_DATA_UPDATEDContract data changes
CONTRACT_VERSION_UPLOADEDA new contract version is uploaded
CONTRACT_DELETEDThe contract is deleted
CONTRACT_VOIDEDThe contract is voided
CONTRACT_SENT_TO_COUNTERPARTYThe contract is sent for counterparty review or redlining
CONTRACT_REVIEW_REQUESTEDInternal review is requested
CONTRACT_REVIEW_COMPLETEDInternal review is completed
CONTRACT_MARK_FOR_EXECUTIONThe contract is marked for execution
CONTRACT_UNMARK_FOR_EXECUTIONThe contract is unmarked for execution
CONTRACT_SIGNATURE_REQUESTEDThe contract is marked or sent for signature
CONTRACT_SIGNATURE_DECLINEDA signatory declines to sign
CONTRACT_SIGNEDA required signatory completes signing
CONTRACT_EXECUTEDAll required signatures are complete
CONTRACT_PROCESS_METRIC_UPDATEDWorkflow metrics change
CONTRACT_ENTITY_UPDATEDThe contract entity changes
CONTRACT_ACTIVITY_LOG_COMMENT_CREATEDA comment is added to the contract activity log

Approvals and structured data​

activity valueWhen it fires
CONTRACT_APPROVAL_REQUESTEDAn approval is requested
CONTRACT_APPROVAL_COMPLETEDAn approval is completed
CONTRACT_EXTERNAL_METADATA_CREATEDExternal metadata is created on the contract
CONTRACT_EXTERNAL_METADATA_UPDATEDExternal metadata on the contract is updated
CONTRACT_KEY_POINTER_CREATIONA key pointer is created
CONTRACT_KEY_POINTER_UPDATIONA key pointer is updated

Counterparties​

activity valueWhen it fires
COUNTER_PARTY_CREATEDA counterparty is created
COUNTER_PARTY_UPDATEDA counterparty is updated
COUNTER_PARTY_CONTACT_CREATEDA counterparty contact is created
COUNTER_PARTY_CONTACT_UPDATEDA counterparty contact is updated
COUNTER_PARTY_ADDRESS_CREATEDA counterparty address is created
COUNTER_PARTY_ADDRESS_UPDATEDA counterparty address is updated

Email and notification events​

activity valueWhen it fires
POSTMARK_EMAIL_EVENTA Postmark email event is recorded
SIGNING_EMAIL_DELIVEREDA signing email is delivered
SIGNING_EMAIL_OPENEDA signing email is opened
SIGNING_EMAIL_NOT_DELIVEREDA signing email is not delivered
SIGNING_EMAIL_LINK_CLICKEDA signing email link is clicked
REDLINING_EMAIL_DELIVEREDA redlining email is delivered
REDLINING_EMAIL_OPENEDA redlining email is opened
REDLINING_EMAIL_NOT_DELIVEREDA redlining email is not delivered
REDLINING_EMAIL_LINK_CLICKEDA redlining email link is clicked
CONTRACT_SIGNATURE_REQUESTED_NOTIFICATION_SENTA signature-requested notification is sent

Use the API reference POST /api/v2.1/public/webhooks/ operation for request schema, examples, and version-specific payload fields.

Debugging expectations​

SpotDraft shows webhook logs in the app. Successful delivery records are retained for 30 days; failed delivery records are retained for 90 days. API logs are not exposed. Your receiver should still keep its own logs for signature verification, queue jobs, retries, and downstream processing.

At minimum, log:

  • endpoint URL and environment
  • event type or activity
  • contract id or reference id when present
  • delivery id, event id, or payload hash
  • signature verification result
  • queue job id
  • response status returned to SpotDraft
  • downstream processing result

When investigating failures, confirm that the destination URL belongs to the same region and environment strategy you use for the rest of the integration and that your endpoint returns a 2xx quickly.