For AI agents: the docs index is at https://docs.enrichment-engine.moneyhubenterprise.com/llms.txt. Append .md to any documentation page URL to get its markdown version.
Field reference for user-scoped affordability calculate and result messages on Kafka.
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. A corresponding result is then published to the affordability result topic.
Moneyhub can also configure regular-transaction detection to request affordability automatically after a successful run, so manual calculate publishes are not always required. See List of configurable features.
Request message
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.
asOfDate
String (max 10)
Yes
Calendar date (yyyy-MM-dd) the report should end on. See Dated report.
The message key should be a unique identifier (UUID recommended). It is copied to the corresponding result message.
asOfDate calculates the same report for the 12 months ending on that calendar day, including the whole of that day. It uses the regular series stored for that date, from a dated detection with the same asOfDate. It does not use the current series.
The published report includes transactionsPeriod. On this dated request, transactionsPeriod.endDate is the asOfDate. A calculate request that omits asOfDate still includes transactionsPeriod, and endDate is then the calculation day. See transactionsPeriod.
A report that omits asOfDate continues to use the current series. Regular income on that report is not taken from a dated detection.
The date must be a real calendar date (yyyy-MM-dd). Anything else is rejected and is not treated as today. Historical affordability is off until Moneyhub enables it. While it is off, a calculate message that includes asOfDate is dead-lettered and no report is produced. See Errors and List of configurable features.
Successful calculation results are published to the affordability result topic. Failed messages are sent to the affordability dead-letter topic; see Errors for the general dead-letter envelope shape.
Result message envelope
The Kafka message value is a JSON object:
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).
At least one of userId or accountId is present, matching the calculate request. The message key is copied from the triggering 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. transactionsPeriod records the window actually used. That window ends on asOfDate when the request includes one, and otherwise on the calculation day. Amounts are plain numbers in major currency units (for example, pounds rather than pence).
Missing sections may be omitted when they are not produced for the request. A successful report always includes transactionsPeriod.
Field
Type
Optional
Description
transactionsPeriod
Object
No
Dates the report covers.
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.
transactionsPeriod
endDate (yyyy-MM-dd) is the day the report applies to. When the calculate request includes asOfDate, endDate is that date. When the request omits asOfDate, endDate is the calculation day. endDate is not the time the result message was produced.
startDate (yyyy-MM-dd) is the later of the earliest transaction and 12 months before endDate.
Field
Type
Optional
Description
startDate
String (max 10)
No
Start of the window used (yyyy-MM-dd).
endDate
String (max 10)
No
Day the report applies to (yyyy-MM-dd).
period
Object
No
Length of that window.
transactionsPeriod.period
Field
Type
Optional
Description
months
Integer
No
Length of the window in months.
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).