Webhooks
Get notified on your own server when an application is approved, declined, booked and more.
A webhook is an HTTP request that LendAPI sends to your server when something happens to an application, for example when it is approved or booked. Webhooks let your systems react right away, without polling the API. You register one HTTPS URL per scope (all products, or specific products). LendAPI then sends a JSON POST to that URL for each application event and includes a key you choose so your server can confirm the request came from LendAPI.
Key concepts
- Webhook URL: the HTTPS endpoint on your server that receives events.
- Webhook key: a secret you choose (at least 16 characters, no spaces). LendAPI sends it in a request header with every event.
- Key Name: how the key is sent: Bearer (in the
Authorizationheader) or X-API-Key (in theX-API-KEYheader). - Products: which products the webhook covers. All Products, or one or more specific products.
- Webhook Variables: extra variables you choose to include in every event payload.
- Event: one notification, identified by a unique
event_idand an eventtypesuch asapplication.approved.
How it works
sequenceDiagram
participant L as LendAPI
participant S as Your server
Note over L: Application event occurs<br/>(e.g. approved)
L->>S: POST webhook URL (JSON event + your key)
alt 2xx within 15 seconds
S-->>L: 200 OK
else Error, non-2xx or timeout
S-->>L: 500 / no response
Note over L: Wait about 60 seconds, then retry<br/>(up to 3 retries, same event_id)
L->>S: POST same event again
end
- An application event happens, such as a decision or a document upload.
- LendAPI picks the webhook for that application. A webhook set up for the application's product is used first. If there isn't one, the All Products webhook is used.
- LendAPI sends the event in the background, so it never slows down the applicant.
- Your server responds. Any
2xxstatus within 15 seconds counts as delivered.
Retries
If your server returns a non-2xx status, doesn't respond within 15 seconds, or can't be reached, LendAPI retries the event up to 3 more times, about 60 seconds apart. Every retry carries the same event_id, so you can safely ignore duplicates. After the last failed attempt, the event is not sent again.
Environments
Sandbox and Production have separate webhook settings. Events for Sandbox applications are sent to the webhook configured in Sandbox. See Sandbox and Live.
Event reference
Event types
Expand the list below to see every event type. Your server should accept any event type and ignore the ones it doesn't need. New event types may be added over time.
All event types
Event type | When it is sent |
|---|---|
application.started | An applicant starts a new application on your hosted application pages. |
application.processing | The application is being processed. |
application.identity_review | A team member approved the application from identity review. |
application.review | The application has been routed to manual credit review. |
application.request_docs | The application is waiting for the applicant to upload documents. |
application.docreceived | The applicant (or your team) has uploaded a requested document. |
application.doc_ai_completed | Automated document processing (DocAI) has finished for an uploaded document. |
application.approved | The application was approved. |
application.declined | The application was declined, by a decision or by a team member. |
application.booked | The application was booked. |
application.withdrawn | The application was withdrawn. |
application.autowithdrawn | The application was withdrawn automatically after a period of inactivity. |
application.closed | A team member closed the application. |
application.middesk_completed | Business verification with Middesk has finished. |
manual_credit_pull | A team member pulled a credit report manually from the application. |
Payload
Every event is a JSON POST.
{
"api_version": "v1",
"event_id": "7f6b2a4e-3c1d-4e8f-9a2b-0c4d5e6f7a8b",
"type": "application.approved",
"product_id": 101,
"outcome": "Auto Approve",
"data": {
"app_id": "d130f351-26a1-4698-9b64-92ae8c46c644",
"tenant_id": "8199c002-0c26-46ec-8aaf-db487f39de1b",
"current_step_label": "approved",
"stage": 1,
"stage_label": "Approved",
"additional_data": {
"utm_source": "partner-site"
},
"custom": {
"variables": {
"annual_income": 85000,
"requested_amount": 15000
}
}
}
}| Header | Value |
|---|---|
Content-Type | application/json |
Authorization | Bearer <your webhook key> (when Key Name is Bearer) |
X-API-KEY | <your webhook key> (when Key Name is X-API-Key) |
Payload fields
| Field | Description |
|---|---|
api_version | Always v1. |
event_id | Unique ID for this event. Stays the same across retries. Use it to detect duplicates. |
type | The event type. See Event types. |
product_id | ID of the application's product, or an empty string if it can't be determined. |
outcome | Name of the application's final decision outcome, or an empty string. |
data.app_id | The application ID. Use it with Get an application to fetch full details. |
data.tenant_id | Your tenant ID. |
data.current_step_label | The label of the step (Product Studio page) the application is currently on. |
data.stage / data.stage_label | The application's stage number and display name. Custom stages show your custom label. |
data.additional_data | Query parameters that were passed on the application link or on the API call that created the application. Useful for passing your own reference IDs through. |
data.custom.variables | Present only if you selected Webhook Variables. Maps each selected variable to its value for this application. |
data.subtenant_id | Present only when the application belongs to a sub-tenant. |
data.branch_code / data.branch_name | Present only when your workspace uses branches. null when the application isn't assigned to a branch. |
Some events add extra top-level fields with event-specific details. For example, application.autowithdrawn includes status_type and inactive_days, and manual_credit_pull includes pull_status, pull_message and bureau_name.
Payload is a notification, not a full recordThe payload tells you what happened and to which application. Call the API with
data.app_idwhen you need the full application data.
Set up webhooks
Add a webhook
- Switch to the environment (Sandbox or Production) you want to configure.
- Open the profile menu in the top-right corner and select Settings.
- Open the Webhook tab.
- Click Webhook (the button with the plus icon).
- Under Products, keep All Products or choose specific products.
- Enter the URL. It must use HTTPS.
- Choose the Key Name: Bearer or X-API-Key.
- Enter a Webhook Key of at least 16 characters with no spaces.
- Click Add Webhook.
The new webhook is active right away. To add variables to the payload, click Add Variables in the webhook's Variables column and choose them in the Webhook Variables dialog.
From the webhook list you can also view or copy the key, edit the webhook, and turn it on or off with the Status switch.
One active webhook per scopeOnly one webhook can be active for All Products, and only one for any given product. Turning a webhook on (or creating a new one) turns off the other webhook that covers the same products. Creating webhooks requires an active, paid LendAPI plan.
Handle events on your server
- Check the key. Compare the
AuthorizationorX-API-KEYheader with your webhook key, and reject requests that don't match. LendAPI doesn't sign payloads, so this key is how you confirm the sender. - Respond fast. Return a
2xxas soon as you have stored the event, then do the heavy work in the background. Responses slower than 15 seconds count as failures and are retried. - Deduplicate on
event_id. Retries reuse the sameevent_id. Process each ID once. - Don't rely on order. Events are delivered in the background and retries can arrive later, so events for one application may arrive out of order. Use
stageandstage_label, or fetch the application, to get its current state. - Use a separate endpoint for Sandbox so test traffic never reaches production systems.
Send webhooks from a flow
Separately from the workspace webhook above, a flow can send its own request with a Send Webhook step. This step posts the variables you select, plus the flow's ID and version, to any public HTTPS URL. It includes Idempotency-Key and X-Event-Id headers and makes up to 3 attempts within 15 seconds, retrying only connection errors, 429 and 5xx responses. See Flow Builder.
Permissions
Webhook settings are on the Webhook tab of the Settings module. Viewing needs view access to that tab, and adding, editing or turning webhooks on and off needs edit access. See Roles and Permissions.
Related guides
Updated 10 minutes ago

