For AI agents: visit https://docs.enrichment-engine.moneyhubenterprise.com/llms.txt for an index of all pages formatted in Markdown and endpoints in OpenAPI.
Field reference for user-scoped affordability report messages on the Kafka affordability-result topic.
Overview
Affordability reports are produced per user. A user may have multiple accounts (for example, a current account and a credit card); the report aggregates enriched transactions and regular-transaction predictions across all of that user's accounts.
To request a report, publish a message to the affordability calculate topic. The affordability worker reads the user's data from storage, computes the report, and publishes the result to the affordability result topic.
When ENABLE_REGULAR_TRANSACTIONS_REQUEST_AFFORDABILITY_REPORT_ON_COMPLETION is enabled for regular transactions (see Configuration in the regular transactions schema), the regular-transactions worker publishes calculate messages automatically after successful detection; manual publishing is not required in that case.
Request message (affordability-calculate)
Deployment topology
Topic name
Default consumer group ID
Internal broker
affordability-calculate
affordability-calculate
External broker
external-affordability-calculate
external-affordability-calculate
The Kafka message value must be a JSON object:
Field
Type
Optional
Description
userId
String (max 36)
No
User identifier for whom the report is requested.
The message key should be a unique identifier (UUID recommended). It is copied to the corresponding result message.
The affordability worker publishes successful calculation results to the affordability result topic.
Deployment topology
Topic name
Default consumer group ID
Internal broker
affordability-result
affordability-result
External broker
external-affordability-result
external-affordability-result
Topic names are configurable per environment. Failed messages are sent to the affordability dead-letter topic (affordability-dead-letter / external-affordability-dead-letter); see Errors for the general dead-letter envelope shape.
Result message envelope
The Kafka message value is a JSON object produced by the affordability worker after processing an affordability-calculate message:
Field
Type
Optional
Description
userId
String (max 36)
Yes
User identifier from the calculate request (present for user-scoped runs).
accountId
String (max 36)
Yes
Account identifier from the calculate request (present for account-scoped runs).
fullAffordabilityReport
Object
No
The affordability report (schema below). Derived from @mft/affordability-calculator output.
At least one of userId or accountId is present, matching the calculate request. The message key is copied from the triggering affordability-calculate message when present; otherwise a new UUID is generated.
Report object (fullAffordabilityReport)
The report analyses up to 12 months of transaction history across accounts in scope for the request, ending on the calculation date. Amounts are plain numbers in major currency units (for example, pounds rather than pence).
Missing sections may be omitted when the calculator does not produce them.
Field
Type
Optional
Description
income
Object
Yes
Income analysis, including regular income detection.
expenditure
Object
Yes
Expenditure medians by affordability category.
transfers
Object
Yes
Net and outgoing transfer medians.
gambling
Object
Yes
Gambling outflow median.
loans
Object
Yes
Opened loan details and repayment median.
returnedPayments
Object
Yes
Returned or reversed direct-debit activity.
overdrafts
Object
Yes
Overdraft usage per account.
income
Field
Type
Optional
Description
median
Number
Yes
Median monthly income (excluding transfers).
medianIncludingTransfers
Number
Yes
Median monthly income including transfers.
amountConsistency
Number
Yes
Consistency score for income amounts (0–1).
categoriesUsed
Array<Object>
Yes
Income category IDs referenced in the analysis.
longevity
Object
Yes
How long income has been observed.
primaryIncomeAccount
Object
Yes
Account receiving the primary income stream.
regularIncome
Object
Yes
Whether regular income was detected, plus predicted monthly amount.
income.categoriesUsed[]
Field
Type
Optional
Description
uid
String (max 3)
No
Level 2 category ID.
key
String
No
Affordability category key.
income.longevity
Field
Type
Optional
Description
consecutiveIncome
Object
Yes
Longest run of consecutive income months.
incomePeriodLength
Object
Yes
Total span of observed income.
Each longevity sub-object has a months integer field.
income.primaryIncomeAccount
Field
Type
Optional
Description
uid
String (max 36)
No
Account identifier.
income.regularIncome
Field
Type
Optional
Description
isDetected
Boolean
Yes
Whether regular income streams were used in monthly predictions.
predicted
Object
Yes
Aggregated regular income prediction.
income.regularIncome.predicted.monthly
Field
Type
Optional
Description
amount
Number
No
Predicted total monthly regular income.
expenditure
Each category object contains a median amount (negative for outflows).
Field
Type
Optional
Description
cashWithdrawals
Object
Yes
ATM and cash-withdrawal spending.
discretionary
Object
Yes
Discretionary spending.
fixed
Object
Yes
Fixed commitments such as rent and loan repayments.
flexible
Object
Yes
Flexible non-discretionary spending.
nonDiscretionary
Object
Yes
Essential non-discretionary spending.
Expenditure category object
Field
Type
Optional
Description
median
Number
No
Median monthly spend (negative for outflows).
transfers
Field
Type
Optional
Description
median
Number
Yes
Median net monthly transfer amount.
out
Object
Yes
Outgoing transfers.
transfers.out
Field
Type
Optional
Description
median
Number
No
Median monthly outgoing transfers (negative).
gambling
Field
Type
Optional
Description
out
Object
Yes
Gambling stakes.
gambling.out
Field
Type
Optional
Description
median
Number
No
Median monthly gambling spend (negative).
loans
Field
Type
Optional
Description
opened
Object
Yes
Recently opened loans by type and period.
repayments
Object
Yes
Loan repayment median.
loans.opened.details[]
One entry per loan type and loan window (30, 90, 180, and 365 days).
Field
Type
Optional
Description
type
String
No
Loan type: dca/dmp, bnpl, unsecured, hcstc, secured, or unknown.
count
Integer
No
Number of loans opened in the period.
period
Object
No
Loan window (unit: days; value: 30, 90, 180, or 365).
total
Object
No
Aggregated amounts (borrowed, repaid) in major currency units for loans opened in the period.
loans.repayments
Field
Type
Optional
Description
median
Number
No
Median monthly loan repayments (negative).
returnedPayments
Field
Type
Optional
Description
count
Integer
Yes
Total number of returned-payment transactions in the analysis period.
period
Object
Yes
Length of the returned-payments analysis (months).
details
Array<Object>
Yes
Returned-payment counts grouped by category and period.
returnedPayments.details[]
One entry per affordability category and period (30, 90, 180, and 365 days).
Field
Type
Optional
Description
category
String
No
Affordability category key for the returned payments.
count
Integer
No
Number of returned payments in the period.
period
Object
No
Rolling period (unit: days; value: 30, 90, 180, or 365).
total
Object
No
Aggregated returned amount (returned) in major currency units.
overdrafts.usage.details[]
Field
Type
Optional
Description
accountUid
String (max 36)
No
Account identifier.
daysInOverdraft
Integer
No
Total days spent in overdraft in the last 90 days.
daysInUnarrangedOverdraft
Integer
Yes
Days in unarranged overdraft in the last 90 days.
earliestBalanceDate
String
No
Earliest balance date available for overdraft analysis (ISO 8601).
periodsInOverdraft
Array<Object>
No
Contiguous overdraft periods in the last 90 days.
overdrafts.usage.details[].periodsInOverdraft[]
Field
Type
Optional
Description
start
String (max 10)
No
Period start date (yyyy-MM-dd).
end
String (max 10)
No
Period end date (yyyy-MM-dd).
days
Integer
No
Number of days in the overdraft period.
minimumBalance
Number
No
Lowest balance reached during the period.
unarrangedOverdraft
Object
Yes
Unarranged overdraft sub-periods within this period.
unarrangedOverdraft
Field
Type
Optional
Description
days
Integer
No
Total unarranged overdraft days in the parent period.
periods
Array<Object>
No
Contiguous unarranged overdraft sub-periods.
Each periods[] element has start, end, days, and minimumBalance fields (plain-number balances).