Webhooks
Mono-Parser pushes events to your registered webhook URL. All webhook payloads share the same envelope shape:
{
"event": "event.name",
"data": { ... },
"timestamp": "2026-02-20T22:14:35.703Z"
}2xx within 10 seconds. Failed deliveries are retried with exponential backoff.account.linkedaccount.linked
Fired when a bank account is successfully linked via Mono Connect. Enrichment starts automatically after this event — you do not need to do anything yet. Wait for account.enrichment_ready before calling analyze.
{
"event": "account.linked",
"data": {
"applicationId": "357ab3ce-55ce-4f73-82c9-dab3136c7885",
"applicantId": "54cbd45f-bf8e-4add-8d0c-adb5efe705c1",
"accountId": "dbcc78d5-0719-4344-ac0e-e02a1f865bf0",
"institution": "Standard Chartered",
"accountNumber": "0131883461"
},
"timestamp": "2026-02-20T22:04:14.123Z"
}account.enrichment_readyaccount.enrichment_ready
Fired per account when income analysis and statement insights have both completed for that account. If your applicant is linking multiple accounts, you will receive this event once per account. When you are done linking all accounts, call /finalize-linking — we will then fire application.ready_for_analysis as your trigger for /analyze.
{
"event": "account.enrichment_ready",
"data": {
"accountId": "dbcc78d5-0719-4344-ac0e-e02a1f865bf0",
"monoAccountId": "6998da59bdaef66d5e5f3d0d",
"applicantId": "54cbd45f-bf8e-4add-8d0c-adb5efe705c1",
"applicationId": "357ab3ce-55ce-4f73-82c9-dab3136c7885",
"message": "Account enrichment complete. You may now submit this applicant for loan analysis."
},
"timestamp": "2026-02-20T22:07:55.382Z"
}/finalize-linking immediately after this event. For multi-account flows, wait until all accounts fire this event before finalizing.application.ready_for_analysisapplication.ready_for_analysis
Fired after you have called /finalize-linking and all linked accounts on the application are confirmed enriched. This is your definitive signal to call /analyze. Unlike account.enrichment_ready which fires per account, this fires once per application.
{
"event": "application.ready_for_analysis",
"data": {
"applicationId": "357ab3ce-55ce-4f73-82c9-dab3136c7885",
"applicantId": "54cbd45f-bf8e-4add-8d0c-adb5efe705c1",
"accountCount": 1,
"message": "All accounts are enriched. You may now submit for analysis."
},
"timestamp": "2026-02-20T22:08:10.441Z"
}account.enrichment_failedaccount.enrichment_failed
Fired when an account stays in PENDING enrichment status for more than 20 minutes. This is a cleanup safety net — it means our system could not complete income analysis or statement insights for that account within the expected window.
{
"event": "account.enrichment_failed",
"data": {
"accountId": "dbcc78d5-0719-4344-ac0e-e02a1f865bf0",
"monoAccountId": "6998da59bdaef66d5e5f3d0d",
"applicantId": "54cbd45f-bf8e-4add-8d0c-adb5efe705c1",
"reason": "enrichment_timeout",
"message": "Account enrichment did not complete within the expected window. Ask the applicant to re-link their bank account to restart the process."
},
"timestamp": "2026-02-20T22:40:00.000Z"
}POST /api/applications/:id/link-account. This generates a fresh Mono Connect widget URL and restarts the enrichment process for that account.application.failedapplication.failed
Fired when the scoring engine encounters a terminal error it cannot recover from — for example, the applicant has no enriched bank accounts at analysis time, or the analysis service returned an unrecoverable error. The application status is set to FAILED.
{
"event": "application.failed",
"data": {
"applicationId": "357ab3ce-55ce-4f73-82c9-dab3136c7885",
"applicantId": "54cbd45f-bf8e-4add-8d0c-adb5efe705c1",
"status": "FAILED",
"reason": "No accounts with completed enrichment available for analysis"
},
"timestamp": "2026-02-20T22:15:00.000Z"
}/initiate to create a new application for the same applicant.application.abandonedapplication.abandoned
Fired by the cleanup system when an application is inactive too long. There are two abandonment reasons — check the reason field to distinguish them.
reason: no_link
The applicant did not link any bank account within 24 hours of the application being created. The widget URL has expired.
{
"event": "application.abandoned",
"data": {
"applicationId": "357ab3ce-55ce-4f73-82c9-dab3136c7885",
"applicantId": "54cbd45f-bf8e-4add-8d0c-adb5efe705c1",
"reason": "no_link",
"message": "Application abandoned — applicant did not link a bank account within 24 hours."
},
"timestamp": "2026-02-21T22:05:00.000Z"
}reason: no_analyze
The applicant linked their account but /analyze was never called within 7 days. Bank data has been scrubbed from our systems for compliance.
{
"event": "application.abandoned",
"data": {
"applicationId": "357ab3ce-55ce-4f73-82c9-dab3136c7885",
"applicantId": "54cbd45f-bf8e-4add-8d0c-adb5efe705c1",
"reason": "no_analyze",
"message": "Application abandoned — analysis was not submitted within 7 days of account linking. Bank data has been scrubbed."
},
"timestamp": "2026-02-28T22:10:00.000Z"
}/initiate to start a fresh application. The applicant will need to re-link their bank account.application.decisionapplication.decision
The final scored decision. Delivered after analysis completes. See the Decision Object section for a full breakdown of all fields.
{
"event": "application.decision",
"data": {
"applicationId": "357ab3ce-55ce-4f73-82c9-dab3136c7885",
"applicantId": "54cbd45f-bf8e-4add-8d0c-adb5efe705c1",
"status": "COMPLETED",
"score": 720,
"decision": {
"score": 720,
"decision": "APPROVED",
"score_band": "LOW_RISK",
"timestamp": "2026-02-20T22:14:35.576410Z",
"applicant_id": "54cbd45f-bf8e-4add-8d0c-adb5efe705c1",
"approval_details": {
"approved_amount": 500000,
"approved_tenor": 12,
"approved_interest": 5.0,
"monthly_payment": 46667
},
"counter_offer": null,
"risk_factors": [],
"score_breakdown": {
"total": 720,
"cash_flow_health": 180,
"income_stability": 160,
"debt_service_capacity": 140,
"account_behavior": 140,
"credit_history": 100
},
"explainability": {
"primary_reason": "Strong income consistency and healthy cash flow",
"key_strengths": ["Consistent monthly credits", "Low debt-to-income ratio"],
"key_weaknesses": []
},
"eligible_tenors": [6, 12, 18, 24],
"manual_review_reasons": [],
"regulatory_compliance": {
"thin_file": false,
"identity_verified": true,
"credit_bureau_checked": true,
"affordability_assessed": true
}
}
},
"timestamp": "2026-02-20T22:14:35.703Z"
}