Identity API: Webhook Events

The Identity API publishes webhook events when producer identity, contact, financial, or E&O data changes. Use these events to keep downstream systems synchronized without polling.

For instructions on how to register an endpoint, verify delivery, and validate signatures, see the Webhooks Quick Start Guide.

Sensitive data

Identity events can carry personally identifiable and financial information (SSN, FEIN, bank account and routing numbers). Treat every event payload as sensitive — restrict logging, encrypt at rest, and limit access to systems that need it.

Available Events

Event TypeWhen It FiresCommon Use Cases
id.producer.updatedA producer identity record (person or firm) is created or updatedKeep producer master data in sync — names, NPN, demographics
id.producer.deletedA producer identity record is deletedRemove the producer from downstream stores; reconcile deletions
id.producer.address.updatedA single address record is created or updatedUpdate a single stored address record
id.producer.address.deletedA single address record is deletedRemove a single stored address record
id.producer.addresses.updatedA producer's address set changes — carries the full current setReplace your whole stored address set in one write, with no follow-up calls
id.producer.phone.updatedA single phone record is created or updatedUpdate a single stored phone record
id.producer.phone.deletedA single phone record is deletedRemove a single stored phone record
id.producer.phone_numbers.updatedA producer's phone set changes — carries the full current setReplace your whole stored phone set in one write, with no follow-up calls
id.producer.bank_account.updatedA bank account record is created or updatedKeep payment details current ahead of a commission run
id.producer.bank_account.deletedA bank account record is deletedStop routing payments to a removed account
id.producer.errors_and_omissions.updatedAn E&O policy record is created or updatedTrack E&O coverage and expiry; gate appointments on active coverage
id.producer.errors_and_omissions.deletedAn E&O policy record is deletedDrop the policy from your coverage records; re-check whether any active coverage remains
id.producer.pay_distribution.updatedA producer's pay distribution configuration changesUpdate commission payout splits before the next pay cycle
id.producer.firm.assignedAn individual producer is associated with a firmUpdate firm rosters; apply firm-level entitlements
id.producer.firm.unassignedAn individual producer is removed from a firmRemove firm-level access and roster membership

Event Schema

All Identity API webhook events share the same envelope:

{
  "id": "whe_01je7babqteg8v9p30k8zpg3ga",
  "type": "id.producer.updated",
  "timestamp": "2026-06-30T17:33:00Z",
  "data": {}
}
FieldTypeDescription
idstringUnique identifier for this event. Uses the whe_ prefix. Repeated on retries — use for deduplication.
typestringThe specific event type (see table above)
timestampstring (ISO 8601)UTC time the event was generated
dataobjectEvent-specific payload (see below)

Field Names: Events vs. REST

Some early events were named independently of the REST API, so a handful of fields differ from their REST equivalents. These divergences are frozen — renaming them would break existing subscribers — and all newer events use the REST field names. Where an event field diverges, map it using this table:

ResourceREST fieldEvent field (legacy)Events affected
AddressidaddressIdid.producer.address.updated / .deleted
AddresstypeaddressTypeid.producer.address.updated
PhoneidphoneIdid.producer.phone.updated / .deleted
PhonetypephoneTypeid.producer.phone.updated
InsurancePolicyidpolicyIdid.producer.errors_and_omissions.updated / .deleted
InsurancePolicytypepolicyTypeid.producer.errors_and_omissions.updated
InsurancePolicycarrierproviderNameid.producer.errors_and_omissions.updated
InsurancePolicyexpiryexpirationDateid.producer.errors_and_omissions.updated
FirmnamebusinessNameid.producer.updated
FirmtypebusinessTypeid.producer.updated
FirmemailprimaryEmailid.producer.updated
BankAccountidbankAccountIdid.producer.bank_account.updated / .deleted
BankAccountname, number, routingNumber, typebankAccountName, bankAccountNumber, bankAccountRoutingNumber, bankAccountTypeid.producer.pay_distribution.updated (embedded bank account)
PayDistributionidpayDistributionIdid.producer.pay_distribution.updated

Events also carry context fields (producerId, npn) that have no REST-resource equivalent — these identify the owning producer and are not divergences.

Event Payloads

id.producer.updated

Fires when a producer identity record is created or updated. The shape of data differs between individual producers and firms.

FieldTypeApplies to
idUUIDBoth
firmIdUUIDIndividuals associated with a firm
npnStringBoth
typeStringBoth (INDIVIDUAL or FIRM)
firstName, middleName, lastName, suffixStringIndividual only
preferredFirstNameStringIndividual only
genderStringIndividual only
dateOfBirthDateIndividual only
ssnStringIndividual only
primaryEmail, secondaryEmailStringIndividual only
finraCrdNumberStringBoth
businessNameStringFirm only (REST: name)
businessTypeStringFirm only (REST: type)
feinStringFirm only
createdAt, updatedAtDate-TimeBoth

Individual example:

{
  "id": "whe_01je7babqteg8v9p30k8zpg3ga",
  "type": "id.producer.updated",
  "data": {
    "id": "18de9286-2ad9-4b83-96c7-6d4d63a085b1",
    "type": "INDIVIDUAL",
    "npn": "444444",
    "firstName": "Richard",
    "middleName": "Person",
    "lastName": "Rogers",
    "suffix": "",
    "preferredFirstName": "Rich",
    "gender": "MALE",
    "dateOfBirth": "1987-01-01",
    "ssn": "123456788",
    "primaryEmail": "richard@example.com",
    "secondaryEmail": "",
    "finraCrdNumber": "2523523",
    "createdAt": "2026-01-15T10:30:00Z",
    "updatedAt": "2026-06-30T17:33:00Z"
  }
}

Firm example:

{
  "id": "whe_01je7babqteg8v9p30k8zpg3ga",
  "type": "id.producer.updated",
  "data": {
    "id": "18de9286-2ad9-4b83-96c7-6d4d63a085b0",
    "type": "FIRM",
    "npn": "222222",
    "businessName": "RDRR LLC",
    "businessType": "LLC",
    "fein": "123456789",
    "primaryEmail": "rdrr@example.com",
    "finraCrdNumber": "",
    "createdAt": "2026-01-15T10:30:00Z",
    "updatedAt": "2026-06-30T17:33:00Z"
  }
}

id.producer.deleted

FieldTypeDescription
idUUIDThe producer's record ID
npnStringThe producer's NPN
{
  "id": "whe_01je7babqteg8v9p30k8zpg3ga",
  "type": "id.producer.deleted",
  "data": {
    "id": "18de9286-2ad9-4b83-96c7-6d4d63a085b0",
    "npn": "222222"
  }
}

id.producer.address.updated

Fires when a single address record is created or updated.

FieldTypeDescription
producerIdUUIDThe producer's record ID
npnStringThe producer's NPN
addressIdUUIDUnique identifier for the address record (REST: id)
addressTypeStringType of address, e.g. MAILING (REST: type)
addressLine1, addressLine2StringStreet address
city, county, state, zip, countryStringLocation fields
moveInDateDateDate the producer moved to this address
preferredBooleanWhether this is the preferred address
updatedAtDate-TimeWhen the record was last updated
{
  "id": "whe_01je7babqteg8v9p30k8zpg3ga",
  "type": "id.producer.address.updated",
  "data": {
    "producerId": "be941609-884a-466b-8a87-2f158d79ebec",
    "npn": "1234",
    "addressId": "5025c204-5c07-47c6-b9d3-11ad09c35f43",
    "addressType": "MAILING",
    "addressLine1": "123 Easy Street",
    "addressLine2": "Suite 500",
    "city": "Athens",
    "county": "Clarke",
    "state": "GA",
    "zip": "30606",
    "country": "USA",
    "moveInDate": "2026-05-02",
    "preferred": true,
    "updatedAt": "2026-06-05T00:03:37Z"
  }
}

id.producer.address.deleted

FieldTypeDescription
producerIdUUIDThe producer's record ID
npnStringThe producer's NPN
addressIdUUIDUnique identifier for the deleted address

id.producer.addresses.updated

Fires when a producer's address set changes and carries the full current set of addresses, so you can replace your stored state without follow-up calls. producerId may be a person or firm ID.

FieldTypeDescription
producerIdUUIDThe producer's record ID (person or firm)
npnStringThe producer's NPN
addressesArrayThe producer's current addresses — each with id, type, addressLine1, addressLine2, city, state, zip, county, country, moveInDate, preferred
updatedAtDate-TimeWhen this snapshot was generated

id.producer.phone.updated

FieldTypeDescription
producerIdUUIDThe producer's record ID
npnStringThe producer's NPN
phoneIdUUIDUnique identifier for the phone record (REST: id)
numberStringThe phone number
phoneTypeStringType of phone number, e.g. CELL (REST: type)
preferredBooleanWhether this is the preferred phone number
updatedAtDate-TimeWhen the record was last updated

id.producer.phone.deleted

FieldTypeDescription
producerIdUUIDThe producer's record ID
npnStringThe producer's NPN
phoneIdUUIDUnique identifier for the deleted phone record

id.producer.phone_numbers.updated

Fires when a producer's phone set changes and carries the full current set of phone numbers. producerId may be a person or firm ID.

FieldTypeDescription
producerIdUUIDThe producer's record ID (person or firm)
npnStringThe producer's NPN
phoneNumbersArrayThe producer's current phones — each with id, number, extension, type, preferred
updatedAtDate-TimeWhen this snapshot was generated

id.producer.bank_account.updated

Fires when a bank account record is created or updated.

FieldTypeDescription
producerIdUUIDThe producer's record ID
npnStringThe producer's NPN
bankAccountIdUUIDUnique identifier for the bank account record (REST: id)
typeStringAccount type (e.g. CHECKING)
numberStringThe bank account number
routingNumberStringBank routing number
nameStringDisplay label for the bank account
primaryAccountBooleanWhether this is the producer's primary account
payDistributionsArrayPay distribution configurations associated with the producer, if any
updatedAtDate-TimeWhen the record was last updated

Handle with care: this payload contains bank account and routing numbers. Do not write it to general-purpose logs, and store it only in systems approved for financial data.

{
  "id": "whe_01je7babqteg8v9p30k8zpg3ga",
  "type": "id.producer.bank_account.updated",
  "data": {
    "producerId": "00283595-fc7b-4999-80ab-fb4a70c21b04",
    "npn": "1234",
    "bankAccountId": "5025c204-5c07-47c6-b9d3-11ad09c35f43",
    "type": "CHECKING",
    "number": "1234567890",
    "routingNumber": "123456789",
    "name": "Wells Fargo",
    "primaryAccount": true,
    "updatedAt": "2026-06-05T00:03:37Z"
  }
}

id.producer.bank_account.deleted

FieldTypeDescription
producerIdUUIDThe producer's record ID
npnStringThe producer's NPN
bankAccountIdUUIDUnique identifier for the deleted bank account

id.producer.errors_and_omissions.updated

Fires when an errors and omissions (E&O) policy record is created or updated.

FieldTypeDescription
producerIdUUIDThe producer's record ID
npnStringThe producer's NPN
policyIdUUIDUnique identifier for the E&O policy (REST: id)
policyTypeStringType of policy, e.g. INDIVIDUAL (REST: type)
policyNumberStringPolicy number
carrierStringName of the E&O insurance provider
providerNameStringLegacy duplicate of carrier — prefer carrier
totalLimitDecimalTotal coverage limit
effectiveDateDateWhen the policy became effective
expirationDateDateWhen the policy expires (REST: expiry)
certificateNumberStringCertificate number
hasFileBooleanWhether a certificate document is uploaded for this policy
updatedAtDate-TimeWhen the record was last updated
{
  "id": "whe_01je7babqteg8v9p30k8zpg3ga",
  "type": "id.producer.errors_and_omissions.updated",
  "data": {
    "producerId": "fcd7c256-2cdc-43ad-b4ce-6c52c0e1cf20",
    "npn": "2523523",
    "policyId": "c2e7c7ac-c994-4989-a703-7eec29a9038b",
    "policyType": "INDIVIDUAL",
    "policyNumber": "EO-458812",
    "carrier": "EZLandC",
    "providerName": "EZLandC",
    "totalLimit": 1000000,
    "effectiveDate": "2026-01-04",
    "expirationDate": "2027-01-04",
    "certificateNumber": "4524524",
    "hasFile": true,
    "updatedAt": "2026-06-05T00:03:37Z"
  }
}

id.producer.errors_and_omissions.deleted

FieldTypeDescription
producerIdUUIDThe producer's record ID
npnStringThe producer's NPN
policyIdUUIDUnique identifier for the deleted E&O policy

id.producer.pay_distribution.updated

Fires when a producer's pay distribution configuration changes. Each distribution splits commission payments across one or more bank accounts.

FieldTypeDescription
payDistributionIdStringUnique identifier for the pay distribution (REST: id)
producerIdUUIDThe producer's record ID
producerTypeStringperson or firm
effectiveFromDateStart of the distribution's effective window (inclusive)
effectiveUntilDateEnd of the effective window (exclusive)
detailsArrayDistribution splits — each with id, bankAccountId, bankAccountName, bankAccountNumber, bankAccountRoutingNumber, bankAccountType, primaryAccount, percentage, amount, priority, remainder

Handle with care: the embedded bank account details include account and routing numbers.


id.producer.firm.assigned

Fires when an individual producer is associated with a firm.

FieldTypeDescription
producerIdUUIDThe individual producer's record ID
producerNpnStringThe individual producer's NPN
firmIdUUIDThe firm the producer was assigned to
firmNpnStringThe firm's NPN

id.producer.firm.unassigned

Fires when an individual producer is removed from a firm. Carries the same payload shape as id.producer.firm.assigned.


Subscribing to Events

When registering your endpoint in the webhook portal, subscribe to the id high-level event group to receive all Identity API events, or subscribe to specific event types if you only need a subset.

See the Webhooks Quick Start Guide for step-by-step registration instructions.

Processing Recommendations

  • Use id for deduplication — if an event is retried, the envelope id stays the same. Store processed event IDs to avoid duplicate processing.
  • Respond quickly — your endpoint must return 2xx within 5 seconds. Offload heavy processing to a queue or background job.
  • Validate signatures — verify the webhook-signature header against your signing secret before processing.
  • Restrict logging of payloads — bank account and identity events carry sensitive data; log the envelope (id, type, timestamp) rather than the full data object.
  • Use updatedAt for ordering — if you receive multiple events for the same resource in quick succession, use data.updatedAt to determine the most recent state.
  • Reconcile with REST — webhook delivery is at-least-once, not guaranteed-ordered. Periodically reconcile against GET /v2/persons and GET /v2/bank-accounts with updated_since as a safety net.