Use webhooks to receive events at your HTTPS receiver. Obtain the authorized partner or customer ID for your account and complete API authentication.
1. Register a receiver
Call POST /api/Webhook/register?partnerId=<partnerId> with the body below. For a customer subscription, use customerId instead. Always supply exactly one valid target ID; the id property in a subscription response is a separate subscription identifier.
{
"webhookUri": "https://receiver.example.com/webhooks/plexe",
"isActive": true,
"webhooks": [
"WB_Customer_Created",
"WB_Application_Created"
]
}
Choose events explicitly. An omitted or empty webhooks list subscribes to all supported events. Initial registration assigns the subscription ID and secret on the server. Re-registering updates the URI and event list; do not use it to rotate the secret or assume it updates every subscription property.
2. Read back the saved configuration
Call GET /api/Webhook/get-subscription?partnerId=<partnerId> to check the saved URI, event list and server-issued secret. Treat the secret as sensitive server-side configuration. Confirm that a subscription was returned; an HTTP success alone does not prove registration was saved.
Get-registered-webhooks returns event names only. Get-all-subscriptions is restricted to webhook administrators and is not a normal partner setup step.
To change a URI, call update-webhook-uri with webhookUri and the target ID in the query. Register first: updating a missing subscription does not create it. Unregister requires a subscription JSON body and the same target query parameter, and removes the subscription.
3. Verify the signature before processing
Deliveries include the header abp-webhook-signature. Compute HMAC-SHA256 over the exact UTF-8 request body bytes using the saved secret as the UTF-8 key. The header format is sha256= followed by uppercase hexadecimal bytes separated with hyphens. Compare the expected and supplied values using a constant-time comparison.
Do not parse and reserialize the body before verification; whitespace and property-order changes alter the signature. Reject missing or invalid signatures before trusting event contents. The public API's handler and test receiver are not a substitute for verification in your receiver.
4. Read the event envelope
{
"id": "11111111-1111-4111-8111-111111111111",
"webhookEvent": "WB_Application_Created",
"data": {},
"creationTimeUtc": "2026-09-01T00:00:00Z"
}
This illustrates the envelope only. data is a JSON value containing event-specific fields, not a JSON-encoded string. Application-created data may include extraInformation.years as a string. Ignore additional fields that your integration does not need.
Do not use the envelope id alone as a universal deduplication key: current publishers can reuse a target identifier across events. Use an event-specific event ID where supplied and business identifiers/state to make processing idempotent. No delivery ordering or fixed retry schedule is promised by this guide.
5. Test delivery
Call POST /api/Webhook/generate-simulated-webhook?eventName=WB_Application_Created&partnerId=<partnerId> after registration. The selected event must be in the subscription. This sends to the saved receiver, so use a test receiver. Unsupported names are rejected.
Check receipt, signature verification and your response in the receiver. A successful simulation request alone does not prove delivery succeeded. Once the event has been accepted safely, return a successful HTTP response promptly.
Endpoint reference
Event catalogue
These are the current subscription event names. Simulation supports a subset; a registered event can still be rejected by the simulation endpoint.
| Event | Purpose |
|---|---|
WB_Partner_Request | Partner request notifications |
WB_Application_Created | Application created |
WB_Customer_Created | Customer created |
WB_Customer_And_Application_Created | Customer and application created |
WB_Application_Current_Process | Current process updates |
WB_Application_Status_Changed | Application status changes |
WB_Loan_Created | Loan created |
WB_Bank_Transactions_Refresh | Bank transaction refresh |
WB_Communication_Sent | Communication sent |
WB_Loan_Withdrawal_Completed | Loan withdrawal completed |
WB_Send_Secondary_Applicant_Notice | Secondary applicant notices |
WB_Under_Review | Under review notifications |
WB_Send_Sms | SMS send event |
WB_Send_Otp | OTP send event |
WB_Send_Loan_Otp | Loan OTP send event |
WB_Application_Cancelled | Application cancelled |
WB_Send_Two_Factor_Code | Two-factor code sent |
WB_Send_Application_Ready | Application ready notification |
WB_Application_Ready | Application ready |
WB_Loan_Enabled_Or_Disabled | Loan enabled or disabled |
WB_Loan_Closed | Loan closed |
WB_Loan_Opened | Loan opened |
| Method | Route | Inputs | Swagger success |
|---|---|---|---|
POST | /api/Webhook/register | query: partnerId; query: customerId; body: body — WebhookSubscription (required) | 200: Not specified |
POST | /api/Webhook/unregister | query: partnerId; query: customerId; body: body — WebhookSubscription (required) | 200: Not specified |
POST | /api/Webhook/update-all | query: partnerId; query: customerId | 200: Not specified |
POST | /api/Webhook/handler | body: body — WebhookPayload (required) | 200: Not specified |
POST | /api/Webhook/generate-simulated-webhook | query: eventName; query: partnerId; query: customerId | 200: Not specified |
GET | /api/Webhook/get-registered-webhooks | query: partnerId; query: customerId | 200: Not specified |
GET | /api/Webhook/get-subscription | query: partnerId; query: customerId | 200: WebhookSubscription |
GET | /api/Webhook/get-all-subscriptions | None | 200: WebhookSubscriptionSummary[] |
POST | /api/Webhook/update-webhook-uri | query: webhookUri (required); query: partnerId; query: customerId | 200: Not specified |