Skip to main content
Instead of polling the API for changes, register an endpoint and Palm pushes events to you. Webhooks deliver events from all Palm products through a single integration — verification results, monitoring alerts, and compliance updates all arrive at the same endpoint.
Image showcasing a history page with information about webhooks.

Setting up a webhook

When you create a webhook in Palm Console, you specify:
  • URL: The HTTPS endpoint that will receive events. HTTP is not supported.
  • Events: The event types you want to subscribe to.
Palm generates a signing secret (format: whsec_...) at creation time. This secret is returned once — store it securely. You’ll need it to verify that incoming requests are from Palm.

Event format

All events follow a consistent naming pattern:
  • {resource}.{action}
  • {resource}.{sub_resource}.{action}
Every event payload contains:
FieldDescription
idUnique event identifier. Use for idempotency.
objectAlways event.
typeThe event type (e.g., user.verification.completed).
created_atISO 8601 timestamp.
dataEvent-specific payload. Structure depends on event type.

Event catalog

A note on naming: Webhook event types use user (e.g., user.verification.completed) while the rest of the docs refer to “person” for KYC verification. These are the same entity — the event names reflect the API resource name.

Verification events

Fired when verification processing completes. Payloads include the verification ID, risk level, match results, and — for business verification — associate results.
EventDescription
user.verification.completedPerson (KYC) verification finished.
business.verification.completedBusiness (KYB) verification finished. Includes associate-level results.

Monitoring events

Fired by the monitoring system when Palm detects changes from external sources (Secretary of State filings). These events only fire for businesses enrolled in Monitor.
EventDescription
business.registration.updatedRegistration data changed (status, name, address, officers, filings). Includes structured diffs with previous and current values.
business.filing.dueA compliance filing deadline is approaching.
business.filing.overdueA compliance filing deadline has passed.

Platform events

Fired when entities are created or removed through the API.
EventDescription
user.createdA person was created.
user.removedA person was removed.
business.createdA business was created.
business.removedA business was removed.
session.completedAn onboarding session workflow completed.

Example payloads

Verification completed

When a business verification completes, the payload includes risk assessment and field-level match results for the business and each associate:
JSON
{
  "id": "evt_1704538200000_f6g7h8i9j0k1",
  "object": "event",
  "type": "business.verification.completed",
  "created_at": "2025-01-06T10:30:00Z",
  "data": {
    "object": {
      "business_id": "bus_987e6543-e21a-45b6-c789-012345678901",
      "verification_id": "ver_456e7890-f12a-34b5-c678-901234567890",
      "reference_id": "your_business_ref_789",
      "risk": {
        "level": "low",
        "reasons": []
      },
      "match": {
        "legal_name": "match",
        "ein": "match",
        "entity_type": "match",
        "address_line_1": "match"
      },
      "associates": [
        {
          "user_id": "123e4567-e89b-12d3-a456-426614174000",
          "verification_id": "660e8400-e29b-41d4-a716-446655440001",
          "status": "completed",
          "risk": { "level": "low", "reasons": [] },
          "match": {
            "first_name": "match",
            "last_name": "match",
            "date_of_birth": "match",
            "ssn": "match"
          },
          "watchlist": { "status": "clear" }
        }
      ]
    }
  }
}

Registration change (monitoring)

When registration data changes, the payload includes structured diffs so you can process changes programmatically:
JSON
{
  "id": "evt_1704538200000_h8i9j0k1l2m3",
  "object": "event",
  "type": "business.registration.updated",
  "created_at": "2026-01-12T10:30:00Z",
  "data": {
    "business": {
      "id": "987e6543-e21a-45b6-c789-012345678901",
      "palm_id": "A1B2-C3D4-E5F6",
      "legal_name": "NEW NAME LLC",
      "registration_jurisdiction_id": "US-NC"
    },
    "changes": [
      {
        "attribute": "name.legal",
        "action": "updated",
        "summary": "Legal name changed from OLD NAME LLC to NEW NAME LLC",
        "previous_value": "OLD NAME LLC",
        "current_value": "NEW NAME LLC"
      },
      {
        "attribute": "address.principal",
        "action": "updated",
        "summary": "Principal address updated",
        "previous_value": {
          "street_line_1": "123 OLD ST",
          "city": "RALEIGH",
          "state": "NC",
          "postal_code": "27601"
        },
        "current_value": {
          "street_line_1": "456 NEW ST",
          "city": "CHARLOTTE",
          "state": "NC",
          "postal_code": "28202"
        }
      }
    ]
  }
}
The data.business object is a lightweight reference — enough to identify which business changed. Use GET /business/{id} to retrieve the full record.

Filing deadline (monitoring)

Filing events include the filing type and due date:
JSON
{
  "id": "evt_1704538200000_l2m3n4o5p6q7",
  "object": "event",
  "type": "business.filing.due",
  "created_at": "2026-02-26T12:00:00Z",
  "data": {
    "object": {
      "type": {
        "id": "annual_report",
        "name": "Annual Report"
      },
      "frequency": "annual",
      "due_date": "2026-04-15"
    },
    "business": {
      "id": "987e6543-e21a-45b6-c789-012345678901",
      "palm_id": "A1B2-C3D4-E5F6",
      "legal_name": "ACME HOLDINGS LLC",
      "registration_jurisdiction_id": "US-NC"
    }
  }
}

Verifying signatures

All webhook payloads are signed using HMAC-SHA256. Always verify signatures before processing events. Palm sends three headers with every delivery:
HeaderDescription
Palm-SignatureFormat: t={timestamp},v1={signature}
Palm-Webhook-IdThe webhook endpoint receiving the event.
Palm-Event-TypeThe event type being delivered.
To verify:
  1. Extract the timestamp (t) and signature (v1) from the Palm-Signature header.
  2. Check the timestamp is within 5 minutes of current time. Reject stale timestamps to prevent replay attacks.
  3. Construct the signed payload: {timestamp}.{raw_request_body}
  4. Compute HMAC-SHA256 using your webhook secret (whsec_...).
  5. Compare your computed signature with the v1 value using constant-time comparison.
Do not skip signature verification, even in development. Unsigned requests could come from anywhere.

Retries and delivery

Timeout: Your endpoint must respond within 10 seconds. Return a 2xx immediately, then process the event asynchronously. Update event types: If your endpoint returns a non-2xx status or times out, Palm retries:
AttemptDelay
1st retry1 minute
2nd retry5 minutes
3rd retry30 minutes
4th retry2 hours
After 5 total attempts (1 original + 4 retries), the delivery is marked as failed. Auto-disable: If a webhook accumulates 10 consecutive failed deliveries across any events, Palm automatically disables it. Check webhook execution logs in Palm Console to monitor delivery health.

Idempotency

Events may be delivered more than once. Use the event id field to deduplicate. If your processing is not naturally idempotent, store processed event IDs and skip duplicates.

Best practices

  • Respond fast, process later: Return a 2xx immediately and handle the event asynchronously. Heavy processing that exceeds the 10-second timeout will trigger retries and eventually disable your webhook.
  • Always verify signatures: Validate the Palm-Signature header on every request. This is your only guarantee the event came from Palm.
  • Deduplicate with event IDs: Network issues can cause duplicate deliveries. Store the id from each processed event to avoid processing it twice.
  • Subscribe selectively: Only subscribe to events you act on. If you don’t need user.created events, don’t subscribe — it reduces noise and load on your endpoint.
  • Monitor delivery health: Check webhook execution logs in Palm Console regularly. A pattern of failures usually means your endpoint is slow or returning errors.

Next steps