Webhooks for Application Events

Webhooks for Application Events

This page describes how onboarding webhooks work without enumerating final event names or status values.

What this webhook does

  • Notifies your system when an onboarding application changes state or reaches key milestones.

  • Lets you react without polling, for example to update UI, send internal notifications, or trigger provisioning steps.

Registering the webhook

Use your onboarding webhook registration endpoint to set the callback URL your integration controls. The request body typically includes your endpoint URL and may include a shared secret used to sign deliveries. Field names may vary by environment; use the exact names defined in your API.

Example request body (example only)

{
  "url": "https://partner.example.com/webhooks/onboarding",
  "secret": "replace-with-strong-secret"
}

Event model

Two common patterns are supported across platforms. Your environment will use one of these.

Pattern A: named events

  • Each delivery includes a descriptive event name such as application.submitted or application.approved.

  • Use the event name to route handling logic.

Pattern B: status-change notifications

  • Each delivery indicates the application status changed.

  • You receive the new status (and optionally the previous status) and handle by comparing values.

Event envelope

Deliveries use a consistent JSON envelope. Fields marked optional may or may not be present depending on your environment.

Example envelope (example only)

{
  "id": "evt_01ABCD2345EF",
  "created": "2025-09-17T15:21:44Z",
  "type": "application.status_updated",
  "data": {
    "applicationId": "app_01XYZ7890MNQ",
    "status": "APPROVED",
    "previousStatus": "SIGNING_COMPLETED"
  }
}

Notes

  • type may be a named event (Pattern A) or omitted for pure status-change deliveries (Pattern B).

  • previousStatus may be omitted if your environment does not include it.

Signature verification

Webhook deliveries are signed so you can verify authenticity. Your environment will either include a signature header or a signature field in the body. Confirm the exact header name and algorithm with the API.

Typical approach (example only)

  • Compute an HMAC SHA-256 over the raw request body using your shared secret.

  • Compare the computed digest to the provided signature using a constant-time comparison.

Pseudocode (example only)

expected = hmac_sha256(secret, raw_body).hex()
if not constant_time_compare(expected, provided_signature):
    return 400

Delivery behavior

  • Respond with HTTP 200 to acknowledge receipt.

  • Non-2xx responses are retried with backoff.

  • Treat deliveries as at-least-once and make handlers idempotent by event id.

  1. Verify the signature.

  2. Check idempotency and skip if id is already processed.

  3. Persist the payload for audit.

  4. Trigger internal processing asynchronously.

  5. Return 200 OK promptly.

Last updated