Credit bureau enquiry and CCR integration¶
| ID | MOD-128 |
| System | SD05 |
| Repo | bank-credit |
| Build status | Deployed |
| Deployed | Yes |
| Last commit | 19b0610 |
Purpose¶
Integrates with external credit reporting bureaus to retrieve credit reports and scores for applicants and existing customers. Supports comprehensive credit reporting (CCR) in AU and standard credit reporting in NZ. Acts as the single integration point for all bureau calls, enforcing consent, managing duplicate enquiry suppression, and routing to the correct bureau by jurisdiction.
Regulatory context¶
Australia — CCR regime. The Comprehensive Credit Reporting regime, enacted under the Privacy Act 1988 and the Credit Reporting Code, requires participating credit providers to report repayment history information to bureaus and entitles them to receive the same in return. Positive and negative data are both reported and received. The regime mandates that enquiry consent is obtained before placing a bureau call, and that the type of enquiry (credit assessment, account review, collection) is disclosed.
New Zealand. The Credit Reporting Privacy Code 2004 (under the Privacy Act 2020) governs credit reporting in NZ. Consumer credit reporters must obtain consent before accessing a credit report. Enquiry purposes are constrained: credit assessment, account review, and collection are the permitted purposes. Adverse credit information — missed payments, defaults, judgements, bankruptcies — is the primary content. NZ does not operate a CCR regime (no positive repayment history is reported); however, some lenders are in the early stages of voluntary positive reporting under the new Privacy Act framework.
Bureau coverage¶
| Jurisdiction | Bureaus supported |
|---|---|
| AU | Equifax AU, Experian AU, illion |
| NZ | Centrix, Equifax NZ |
The tenant configuration (credit.bureau_config) specifies which bureau(s) to call per jurisdiction and the priority order for multi-bureau strategies. The default is single-bureau primary with a fallback, configurable per product type.
Duplicate enquiry suppression¶
A bureau call creates a "hard enquiry" on the customer's credit file, which is visible to other lenders and can marginally affect the customer's credit score. Unnecessary duplicate enquiries are harmful to the customer and can indicate a poorly controlled credit process to regulators.
The module enforces a 30-day suppression window: if a bureau report for the same customer and the same enquiry type already exists in credit.bureau_enquiries with created_at within the last 30 days, the module returns the cached report rather than placing a new bureau call. The suppression window is configurable per product type — it may be shortened for high-velocity credit products.
Data model¶
-- credit.bureau_enquiries
CREATE TABLE credit.bureau_enquiries (
enquiry_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
customer_id UUID NOT NULL,
application_id UUID, -- null for account review enquiries
jurisdiction TEXT NOT NULL CHECK (jurisdiction IN ('NZ','AU')),
bureau TEXT NOT NULL, -- 'equifax_au', 'experian', 'illion', 'centrix', 'equifax_nz'
enquiry_purpose TEXT NOT NULL CHECK (enquiry_purpose IN ('credit_assessment','account_review','collection')),
consent_reference UUID NOT NULL, -- reference to the consent record
request_at TIMESTAMPTZ NOT NULL DEFAULT now(),
response_at TIMESTAMPTZ,
response_status TEXT CHECK (response_status IN ('success','no_file','bureau_error','timeout')),
credit_score INT,
bureau_reference TEXT,
report_payload JSONB, -- encrypted at rest; never logged in plaintext
adverse_flags TEXT[], -- ['default','judgement','bankruptcy','missed_payments']
suppressed BOOLEAN NOT NULL DEFAULT false, -- true if returned from cache
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
report_payload is stored encrypted at rest and is never written to application logs. Access to the raw payload is restricted to the credit decisioning engine (MOD-029) and authorised back-office credit assessors. Adverse flag codes are stored as structured arrays separately from the full payload to allow downstream filtering without requiring decryption.
Key operations¶
Consent check¶
Before placing any bureau call, the module checks that a consent record exists in the consent management layer for the customer, with purpose = 'credit_bureau_enquiry' and created_at within the consent validity window (typically the current credit application session). If no valid consent exists, the call is blocked and an error is returned to the calling module. The consent record reference is stored on the enquiry.
Bureau call routing¶
The module selects the bureau based on the account's jurisdiction and the tenant's bureau configuration. For AU credit assessment: the primary bureau (e.g. Equifax AU) is called first. If the primary bureau returns no_file or errors, the fallback bureau (e.g. illion) is called. For NZ: typically Centrix for consumer lending, Equifax NZ for mortgage applications — configurable by product type.
Duplicate suppression¶
Before placing a live call, the module checks for a non-suppressed enquiry for the same customer_id and enquiry_purpose in the suppression window. If found, it returns the existing report with suppressed = true. This reduces hard enquiry count on the customer's file and avoids unnecessary bureau API costs.
Report delivery¶
On successful response, the report payload is stored encrypted, adverse flags are parsed and stored in structured format, and the credit score (if returned) is stored. The enquiry status is set to success or no_file. The calling module (MOD-029) receives the structured adverse flags and score — not the raw payload — via the internal API. The raw payload is only accessible to authorised credit assessors via the back-office panel.
Adverse finding disclosure¶
If adverse_flags is non-empty and the bureau data contributed to an unfavourable credit decision, MOD-050 is called to include the adverse finding summary in the pre-decision disclosure provided to the applicant. The applicant's right to access their credit report from the bureau is disclosed in the same communication.
Requirements¶
FR-577 — Consent enforcement: the module must verify that a valid bureau enquiry consent record exists before placing any call to a bureau API; if consent is absent or expired, the call must be blocked and an error returned to the calling module — no bypass path may exist.
FR-578 — Duplicate enquiry suppression: the module must check for an existing bureau report for the same customer and enquiry purpose within the 30-day suppression window before placing a new call; if a recent report exists, it must be returned from cache with suppressed = true rather than placing a duplicate hard enquiry.
FR-579 — Multi-bureau fallback: for AU credit assessments, the module must support a primary and fallback bureau configuration per product type; if the primary bureau returns no_file or a timeout, the module must automatically route to the fallback bureau without manual intervention.
FR-580 — Adverse finding disclosure: if an enquiry returns non-empty adverse_flags and those flags contribute to an unfavourable credit decision, the module must call MOD-050 to deliver an adverse action disclosure to the applicant before the decision is communicated, including the bureau name, the nature of the adverse information, and the applicant's right to access their credit report.
Module dependencies¶
Depends on¶
| Module | Title | Required? | Contract | Reason |
|---|---|---|---|---|
| MOD-009 | eIDV & document verification | Required | contract/api/ |
Applicant identity must be verified via eIDV before a bureau enquiry is placed — bureau calls require a confirmed identity to prevent misuse. |
| MOD-045 | Secrets & key management | Required | — | Bureau API credentials (Equifax, Experian, illion, Centrix) are stored and rotated via the secrets and key management module. |
| MOD-104 | AWS shared infrastructure bootstrap | Required | — | AWS shared infrastructure provisioned by MOD-104 (EventBridge buses, S3, KMS, Kinesis, Cognito) is required before this module can be deployed. |
| MOD-103 | Neon database platform bootstrap | Required | — | Neon database and schema provisioned by MOD-103 must exist before this module can read or write Postgres. |
Required by¶
| Module | Title | As | Contract |
|---|---|---|---|
| MOD-027 | Affordability calculator | Hard dependency | — |
| MOD-028 | Credit score & risk rating | Hard dependency | — |
| MOD-029 | Pre-approval engine | Hard dependency | — |
Policies satisfied¶
| Policy | Title | Mode | How |
|---|---|---|---|
| CRE-003 | Credit Decisioning & Scorecard Policy | GATE |
A credit enquiry must be completed and the bureau response recorded before the credit decision engine (MOD-029) can proceed to assessment — no decision is made without current bureau data. |
| PRI-001 | Privacy Policy | GATE |
Bureau enquiries are made only with the applicant's explicit consent, recorded in the consent management layer before any call is placed to the bureau API. |
| CON-004 | Product Disclosure & Sales Practice Policy | LOG |
Adverse bureau findings (score, adverse flags, bureau name) are captured on the enquiry record and returned structured to the caller; the calling decisioning module (MOD-029) is responsible for invoking MOD-050 to deliver disclosure to the applicant. |
| REP-010 | Credit reporting & bureau submission | LOG |
All bureau enquiries — request, response, bureau reference, and consent record — are logged for regulatory examination and to support hardship review processes. |
Capabilities satisfied¶
(No capabilities mapped)
Part of SD05 — Credit Decisioning & Loan Platform
Compiled 2026-05-22 from source/entities/modules/MOD-128.yaml