Decision Object
The decision field inside the application.decision webhook payload contains the full scoring output. Every field listed here is always present in the response unless marked optional.
| Field | Type | Description |
|---|---|---|
| applicant_id | string | The applicant UUID this decision was issued for. |
| score | number | Overall credit score (350–850). Higher is better. |
| decision | string | APPROVED | REJECTED | MANUAL_REVIEW | COUNTER_OFFER |
| score_band | string | VERY_LOW_RISK | LOW_RISK | MEDIUM_RISK | HIGH_RISK | VERY_HIGH_RISK |
| score_breakdown | object | Points earned per scoring component. See breakdown below. |
| approval_details | object | null | Present when decision is APPROVED. Contains the approved loan terms. See schema below. |
| counter_offer | object | null | Present when decision is COUNTER_OFFER. Contains revised terms the applicant can accept. See schema below. |
| eligible_tenors | array | List of tenor options (in months) for which the applicant qualifies at the approved or offered amount. Empty when decision is REJECTED. |
| risk_factors | array | Signals that negatively influenced the score. Each item has factor, severity, and detail. Empty on clean applications. |
| manual_review_reasons | string[] | Plain-language reasons the application was flagged for human review. Present alongside MANUAL_REVIEW decisions. |
| explainability | object | Human-readable summary with primary_reason, key_strengths[], and key_weaknesses[]. |
| regulatory_compliance | object | Compliance flags: thin_file, identity_verified, credit_bureau_checked, affordability_assessed. |
| timestamp | string | ISO 8601 timestamp of when the decision was issued. |
score_breakdown
Individual points earned per scoring component. Components sum to total. Default weights shown — these shift for thin-file applicants (credit history weight drops to 0%, redistributed to income and cash flow).
| Field | Type | Description |
|---|---|---|
| total | number | Final score (350–850). Sum of baseline (350) and all earned points. |
| credit_history | number | Points from credit bureau data. Weight: 30% (standard) / 0% (thin-file). |
| income_stability | number | Points from income consistency and stream count. Weight: 25% (standard) / 35% (thin-file). |
| cash_flow_health | number | Points from inflow/outflow balance and savings capacity. Weight: 20% (standard) / 30% (thin-file). |
| debt_service_capacity | number | Points from debt-to-income ratio and existing obligations. Weight: 15% (standard) / 20% (thin-file). |
| account_behavior | number | Points from transaction frequency, account age, and activity patterns. Weight: 10% (standard) / 15% (thin-file). |
approval_details
Present when decision is APPROVED. Contains the exact terms to present to the applicant. null for all other decision types.
| Field | Type | Description |
|---|---|---|
| approved_amount | number | Loan amount approved in Naira. Equal to the requested amount unless an affordability cap was applied. |
| approved_tenor | number | Approved repayment period in months. |
| interest_rate | number | Monthly interest rate as a percentage (e.g. 5.0 for 5% per month). |
| monthly_payment | number | Calculated monthly repayment amount in Naira. |
| dti_ratio | number | Debt-to-income ratio at the approved terms. Expressed as a decimal (e.g. 0.28 = 28% of monthly income). |
| conditions | string[] | Any conditions attached to the approval (e.g. salary domiciliation requirements). Empty array when unconditional. |
counter_offer
Present when decision is COUNTER_OFFER. The scoring engine could not approve the original request but found a viable offer within affordability limits. Present this to the applicant as an alternative. null for all other decision types.
| Field | Type | Description |
|---|---|---|
| offered_amount | number | The maximum amount the engine can approve — lower than the originally requested amount. |
| offered_tenor | number | Tenor in months for the counter offer. |
| monthly_payment | number | Calculated monthly repayment at the offered terms. |
| reason | string | Plain-language explanation of why the original amount was reduced (e.g. affordability cap or thin-file income multiple limit). |
risk_factors
Each item in risk_factors describes a specific signal that negatively influenced the decision. Safe to relay to loan officers — not to applicants directly.
{
"factor": "IDENTITY_NAME_MISMATCH",
"severity": "HIGH",
"detail": "Submitted name 'John Doe' does not match account holder 'OJO DANIEL'"
}| Field | Type | Description |
|---|---|---|
| factor | string | Machine-readable code for the risk type (e.g. IDENTITY_NAME_MISMATCH, LOW_AVERAGE_BALANCE, IRREGULAR_INCOME). |
| severity | string | HIGH — may have triggered immediate rejection. MEDIUM / LOW — reduced the score without a hard knockout. |
| detail | string | Human-readable explanation suitable for internal logging or loan officer review. |