Webhook Event Format
This page describes what every webhook delivery looks like, regardless of which integration you are on: the envelope, how events are identified, and how delivery behaves.
The contents of data depend on the event, and each event is documented in the
Event Catalog.
Event Structure​
When an event occurs that matches one of your destinations, banca.me sends an HTTP POST to that
destination's URL with a JSON body of exactly two fields:
{
"eventId": "9f2a1c4e-3b8d-4f71-a205-6c9e8d0b1a37",
"data": {}
}
| Field | Type | Description |
|---|---|---|
eventId | string | Identifies the event, not the delivery attempt |
data | object | Event-specific payload. Its shape depends on the event |
The envelope does not name the event​
There is no event-type field in the body and no event-type header. Nothing in the request
states whether it is loan_approved or pre_approve.
In practice this rarely matters, because most partners are on a single integration and therefore receive a single event. It matters when one endpoint is subscribed to both. Two ways to handle it:
- Register one destination per event type. Each destination has its own URL, so the URL that received the request tells you which event arrived. This is the recommended approach.
- Discriminate on the payload.
data.externalTrxIdmarksloan_approved;data.idBancamemarks the two real-estate events, anddata.estadoseparatespre_approvefromnew_lead. See Telling the events apart.
eventId and idempotency​
eventId identifies the event itself. A retry carries the same eventId as the original
attempt, so it is what you use to recognise a duplicate.
Store processed ids and skip anything you have already handled:
async function handleWebhook(event) {
const { eventId, data } = event;
if (await alreadyProcessed(eventId)) {
return; // duplicate delivery — nothing to do
}
await process(data);
await markProcessed(eventId);
}
Delivery behaviour​
These hold for every event:
| Destination scheme | HTTPS only |
| Redirects | Not followed |
| Private addresses | Rejected at registration |
Timeouts and retries are not universal — they depend on the event:
| Event | Timeout | Retries |
|---|---|---|
loan_approved | 5 seconds | one retry |
pre_approve | 5 seconds | one retry |
new_lead | 3 seconds | none — a single attempt |
Respond 2xx quickly and do the real work afterwards. A handler that finishes its processing
inline before responding will time out on anything slow, even though the data arrived intact.
That matters most for new_lead, which has both the tightest timeout and no second chance.
Once an event exhausts its attempts it is not delivered again, and there is no self-service
replay. For new_lead that means a single failure loses the event — see
Best Practices for the recovery path.
To recover a range of missed events, contact us.
What arrives in data​
| Event | Integration | Payload |
|---|---|---|
loan_approved | BNPL | Loan terms and instalment schedule |
new_lead | Real estate | Identity and contact, 11 fields |
pre_approve | Real estate | The risk evaluation, flat, in 51 fields |
All three are documented field by field in the Event Catalog. If you are not sure which apply to you, see Which Webhook Integration Is Yours.
Next steps​
- Verify that deliveries really came from banca.me — which page depends on your integration: Verify HMAC Signatures if you are BNPL, Verify the Webhook Token if you are real estate
- Build a handler that holds up in production: Best Practices