Skip to main content

Webhooks

Receive real-time notifications when events occur in your Propper account.

Setting Up Webhooks​

  1. Go to Settings → Webhooks in your dashboard
  2. Click Add Endpoint
  3. Enter your endpoint URL
  4. Select the events you want to receive
  5. Save and copy your signing secret

Webhook Payload​

{
"id": "8f1a6c2e-4b7d-4a91-9c3e-2d5f8b0a7e14",
"type": "agreement.recipient_signed",
"version": 1,
"occurredAt": "2026-01-15T10:30:12.481Z",
"orgId": "3c9d1e77-2a45-4f68-b0c1-9e7a4d2b6f83",
"source": "sign-api",
"data": {
"orgId": "3c9d1e77-2a45-4f68-b0c1-9e7a4d2b6f83",
"agreementId": "b2e4f915-7c8a-4d13-9f60-1a8c5e3b7d92",
"title": "Service Agreement",
"status": "IN_PROGRESS",
"occurredAt": "2026-01-15T10:30:12.481Z",
"recipient": {
"id": "d7c3a018-5f2b-4e96-8a41-6b0d9c2e5f37",
"email": "signer@propper.ai",
"name": "Jordan Lee",
"role": "SIGNER",
"order": 1
}
}
}

Every event shares the envelope fields id, type, version, occurredAt, orgId, source, and data. The data fields depend on the event type; see Sign Webhooks for each agreement event.

Verifying Signatures​

All webhooks include a signature header for verification:

X-Propper-Signature: sha256=abc123...
import crypto from 'crypto';

function verifyWebhook(payload: string, signature: string, secret: string): boolean {
const expected = crypto.createHmac('sha256', secret).update(payload).digest('hex');

return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(`sha256=${expected}`));
}

Event Types​

Sign Events​

EventDescription
agreement.createdAn agreement was created
agreement.sentThe agreement was sent to its recipients
agreement.deliveredEvery recipient's invitation email was delivered (not sent for every agreement)
agreement.viewedA recipient opened the agreement for the first time
agreement.recipient_signedA recipient finished signing
agreement.completedEvery recipient finished and the signed document is ready
agreement.declinedA recipient declined to sign
agreement.voidedThe agreement was voided
agreement.recalledThe sender recalled the agreement for editing, returning it to draft
agreement.expiredThe agreement expired before it was completed

Click Events​

EventDescription
click.acceptance.completedAn acceptance is recorded and its evidence is complete
click.evidence.createdThe evidence record for an acceptance is created
click.evidence.signedThe evidence record is signed
click.evidence.failedEvidence could not be produced; the acceptance itself is still recorded

Retry Policy​

Failed webhook deliveries are retried with exponential backoff:

  • 1st retry: 1 minute
  • 2nd retry: 5 minutes
  • 3rd retry: 30 minutes
  • 4th retry: 2 hours
  • 5th retry: 24 hours

After 5 failed attempts, the endpoint is disabled and you'll be notified.