Set up your endpoint
During onboarding, give Everbility an HTTPS endpoint such as:webhook_secret. This secret is separate from your OAuth client_secret and is used only to verify webhook signatures.
Your endpoint must:
- use HTTPS;
- accept
POSTrequests with anapplication/jsonbody; - not rely on credentials embedded in the URL;
- return a
2xxresponse within 10 seconds after durably accepting the event.
Events
Expiry is checked every minute, so an expiry event is normally queued within one minute of
expires_at.
Payload
Request headers
Every delivery includes:Everbility-Webhook-Timestamp is the Unix timestamp for that delivery attempt. A retry keeps the same event ID and JSON body but receives a new timestamp and signature.
Verify the signature
Build the signed message from the timestamp, a literal period, and the exact raw request bytes:v1= using a constant-time comparison.
express.raw({ type: "application/json" }) on the webhook route before express.json() in Express, or call await request.body() before JSON parsing in FastAPI.
Handle an event safely
1
Read the raw request
Capture the body as bytes and read the timestamp, signature, and event ID headers.
2
Verify the request
Reject malformed signatures and timestamps more than five minutes away from your server clock. Compare the signature in constant time.
3
Deduplicate and persist
Use
Everbility-Webhook-Id or the payload’s top-level id as a unique key. Persist the event or enqueue your work before acknowledging it.4
Return a success response
Return
200, 202, or 204 promptly. Perform slower document retrieval and processing asynchronously.5
Read the current API state
Treat the webhook as a notification. Poll the session if needed, and use a current OAuth access token to retrieve a completed document.
Retrieve a completed document
data.document_url is relative to the API host. Resolve it against https://api.everbility.com and authenticate with your OAuth access token:
Delivery and retries
- Any
2xxresponse marks the event delivered. - Network errors, a 10-second timeout, and every non-
2xxresponse are failures. Redirects are not followed, so a3xxresponse is retried. - Everbility makes up to seven total attempts: the initial attempt, then retries after approximately 1 minute, 5 minutes, 30 minutes, 2 hours, 8 hours, and 24 hours.
- After the seventh failed attempt, the delivery becomes terminally failed. Use session-status polling as your recovery path.
- Retries keep the same event ID and raw JSON body. Each attempt receives a new timestamp and signature.
- Do not depend on delivery order. A retry can arrive after a later event.
Go-live checklist
- Your endpoint is HTTPS and does not redirect.
- You preserve the raw request body before parsing JSON.
- You verify the dedicated webhook secret, timestamp, and signature.
- You deduplicate by event ID and return
2xxonly after durable acceptance. - Your handler responds in less than 10 seconds and processes slow work asynchronously.
- You retrieve documents with OAuth, not the webhook secret.
- You retain status polling for recovery and monitor repeated delivery failures.