Webhooks are not available on our legacy Free or Build plans. Upgrade to Starter, Pro, or Premier for access.
Webhook Payload Structure
Common payload fields
Each webhook event contains the following fields in the response body:
Finch provides three general types of webhook events: account updates, job completions, and data changes.
Account Updates
Account update events contain information about account connections, such as when a connection has been established or when a connection has entered an error state. This type of webhook has the following unique schema:
Example:
Job Completion
Job completion events fire when a job finishes running, whether the final state is a success or an error. Upon receiving ajob.{job_type}.completed event, use the job_url in the payload to retrieve the job’s final status.
This type of webhook has the following
data schema:
Example:
Data Changes
Data change events fire when any data for a connection changes after Finch’s initial data sync. These could becreated, updated, or deleted events on any of our endpoints. One event fires per changed record — for example, if 10 individuals are updated across Directory, Employment, or Individual, Finch sends 10 separate events. This type of event has the following schema:
The possible
data schemas per endpoint are as follows:
Examples:
Company
Individual
Pay Statement
Supported Events
Required Events
The following events cover the core connection lifecycle. Which ones apply depends on your product scopes:Webhook Registration
Webhook endpoints should use HTTPS and expect to receive POST requests with the following headers:

Webhook Verification
Finch uses HMAC-SHA256 webhook verification. To verify a webhook using theFinch-Signature header:
- Extract the signature from the header. The
Finch-Signatureheader consists of a list of signatures (where the signature content begins after “v1,” and is space delimited) to account for secret rotations; there may be multiple signatures present for cases where a secret was rotated. During the verification process, the signature must match at least one signature in the list to be considered valid.
- Generate the webhook signature
- First, base64 decode the webhook secret to get the raw bytes.
- Then, using the decoded webhook secret, hash the webhook content in the form
{webhook_id}.{webhook_timestamp}.{body}wherewebhook_idis theFinch-Event-Id,webhook_timestampis theFinch-Timestamp, andbodyis the raw request body. The signature is sensitive to any change in the body — do not modify it before verifying. If the computed signature does not match any signature in theFinch-Signatureheader, reject the webhook. Use a constant-time comparison to avoid timing attacks.
- Verify the webhook timestamp. If the signature is valid, check that the timestamp is within five minutes of the current time. If it is not, reject the webhook. Using outdated webhooks increases susceptibility to replay attacks.
Testing Webhooks
You can send a test request to any webhook through the developer dashboard.
event_type set to test.
Retry schedule
Upon failure, Finch retries according to the following schedule with exponential backoff:- Immediately
- 5 seconds
- 5 minutes
- 30 minutes
- 2 hours
Best practices
Responding to Webhooks
To prevent unnecessary retries, receive and process webhook events in separate processes. Respond immediately with a200 to indicate successful delivery, then process the event asynchronously.
Event Delivery and Ordering
- You may occasionally receive the same webhook event more than once. Use the
Finch-Event-Idto implement idempotent event processing. - Finch does not guarantee delivery of events in the order they happen. For example, you may receive an
updateevent for anindividualbefore acreatedevent. You should also use the Finch API to occasionally fetch any missing data. For example, you can fetch an individual if you happen to receive anupdateevent first.
Event Mapping
- Each webhook includes a
connection_ididentifying the employer connection. Use it to route incoming events to the right employer in your system. For details on capturing and storing theconnection_id, see Retrieve Access Token. - Each webhook also includes an
entity_idfor the specific entity within that connection. For multi-entity connections, theentity_idis required in subsequent API requests.