Anything marked Live answers today. Anything marked With the engine move is specified here as the contract and is being built as the Registry moves beside its database. Nothing on this page is described as working before it does.
One signed request asks the network. The request fields match the bureau's, so an existing bureau integration keeps its parsing code. What changes is the signature, which no one can forge, and the answer, which comes back already read.
All calls are HTTPS POST with a JSON body, except the health and catalogue reads. Versions change only by path. Fields are added inside a version and never removed or repurposed.
Your X-Road style identity, for example KE/LENDER/3002. Sent in x-interchange-member.
Public key
Ed25519, 32 bytes, hex. Registered with the Interchange; it is how we recognise your signature.
Private key
A 32-byte Ed25519 seed, hex. Generated on your side and never sent to us, so nobody can sign as you, including us. In-portal generation arrives with the engine move.
IP allowlist
The addresses your systems call from. Required for production keys. With the engine move.
Webhook secret
Used to sign the events we send you: report.ready, crunch.completed, cap.reached. With the engine move.
Every member call carries four headers. The signature covers the method, the path, the SHA-256 of the exact body bytes, the timestamp, a random nonce and your member code, so a request cannot be replayed, altered in transit, or sent in another member's name.
Header
Value
x-interchange-member
Your member code.
x-interchange-timestamp
ISO 8601 UTC, e.g. 2026-09-17T08:15:59.212Z. Refused outside a 60-second window (IX004).
x-interchange-nonce
32 random hex characters, fresh for every request.
x-interchange-signature
Ed25519 signature over the canonical string, lowercase hex.
Sent to /api/v1/report. Ecosystem reports are free to a contributing member. Bureau-backed reports carry the bureau's cost and a stated fee, shown as separate lines on the invoice.
Type
Report
Answers
Source
State
1
Identity Verification
Is this ID real, and is it the person in front of me?
Bureau
Live
2
Delinquency Status
Are they in default right now, anywhere in this ecosystem?
Member books
Live
3
Interchange Score
What is the network's number on this person, and why?
Both
Specified
11
Cashflow & Affordability
What can they actually afford to repay each month?
Both
Specified
8
Credit Info
Every credit account on file, and how each one is performing.
Bureau
Live
12
Credit File
Everything on file, read as a decision rather than as a dump.
Both
Live
20
Ecosystem Exposure
Is this borrower, who looks clean to me, servicing loans elsewhere right now?
Member books
Live
21
Intent Signal
Who is this borrower shopping with right now?
Member books
Specified
22
Contactability
When and how do we actually reach this person?
Member books
Specified
23
Cohort Benchmark
How does this borrower compare with their peers across the ecosystem?
Member books
Specified
Interchange report numbers follow the bureau's where the product is the same, and start at 20 where no bureau has an equivalent. Two numbers collide by meaning: Interchange 2 reads live member books, while bureau report 2 is the bureau's own delinquency flag; and Interchange 22 is Contactability, while bureau report 22 is a 12-month account history. That is why bureau products have their own path.
Sent to /api/v1/bureau/report with the bureau's own report_type integer. Every pull returns four things: the document on the Interchange letterhead, the Interchange JSON, the bureau's response exactly as received with its SHA-256, and for account reports a CSV of every account.
Type
Report
What the lender learns
Needs loan context
1
Identity Verification
Whether the ID exists and who it belongs to.
no
2
Delinquency Status
Whether the person is in default now, or has been.
loan_amount, report_reason
3
Metro / Mobile Score
The bureau's score for the person, or the mobile-lending variant.
no
4
PDF Credit Report
The bureau's own printed credit report.
loan_amount, report_reason
5
JSON Credit Report
The full credit file as structured data.
loan_amount, report_reason
6
Identity Scrub
Every contact and address trace lenders have reported.
no
8
Credit Info
Every credit account on file, with the headline score.
loan_amount, report_reason
10
Enhanced Credit Info
Credit Info plus who guarantees the person and who holds a stake in them.
loan_amount, report_reason
11
Credit Info with Income Estimate
Credit Info plus the bureau's modelled monthly income.
loan_amount, report_reason
12
Full Enhanced Credit Info
The complete picture: identity, traces, accounts and a year of score history.
loan_amount, report_reason
13
Minified Credit Info
One line: worst arrears, whether non-performing, total owed.
loan_amount, report_reason
14
Full JSON Report
The older full-file format: identity, traces, accounts, guarantors.
loan_amount, report_reason
16
Credit Accounts Summary
Counts of mobile against generic loans, arrears, NPLs and the monthly instalment.
loan_amount, report_reason
22
Accounts Info (12-month history)not in contract
Month by month status of every account over the last year.
The top-level has_error, api_code and api_code_description keep the bureau's meaning. Everything the bureau said sits under data, restructured but never recomputed. Everything the Interchange worked out from it sits under reading, so the two can never be confused. This is the real sample for bureau report 2:
No consent reference, no answer. A consent is recorded against the borrower's token, never a national ID, and a consent issued for one borrower cannot be used to ask about another (IX104). The scopes a consent can carry:
Every code value the bureau returns is passed through unchanged, so switch statements written against the bureau keep working. The descriptions below are the Interchange's own.
Every error says whose code it is. api_code_source is "interchange" when the Interchange decided, and "bureau" when the bureau produced the code, which is then passed through untouched.
Service available. The bureau's health check is answering.
no
E001
Bureau internal error. The bureau failed internally. Nothing is wrong with the request.
yes
E002
API key missing. The request carried no public key.
no
E003
Key not authorised. The key exists but may not use this service or port.
no
E004
Public key invalid. The public key has expired or been disabled.
no
E005
Wrong content type. The body was not sent as application/json.
no
E006
Body is not valid JSON. The request body could not be parsed.
no
E007
report_type missing. The report_type field was absent.
no
E008
identity_number missing. The identity_number field was absent.
no
E009
identity_type missing. The identity_type field was absent.
no
E010
report_type empty. The report_type field was present but blank.
no
E011
Unknown report type. The report_type value is not one the bureau serves.
no
E012
identity_number empty. The identity_number field was present but blank.
no
E013
identity_type empty. The identity_type field was present but blank.
no
E014
Unknown identity type. The identity_type value is not in the identity type list.
no
E015
Fields do not fit this report. The combination of fields is not valid for the report type asked for.
no
E016
Service not open yet. The bureau has not released this service for use.
no
E017
No record for this ID. On an entitled report this is a thin or unknown file — record it as a finding, not an error. On a dummy ID it proves entitlement for free.
no
E018
Not a test identity. Test keys only answer for the bureau's test IDs.
no
E019
Identity type restricted. This identity type is not open to the account.
no
E020
loan_amount missing. This report type needs loan_amount.
no
E021
loan_amount empty. The loan_amount field was present but blank.
no
E022
loan_amount invalid. loan_amount is not a whole positive number.
no
E023
Timestamp missing. The timestamp header was absent.
no
E024
Timestamp invalid. The timestamp header is not in the expected format.
yes
E025
Clock out of step. The request arrived too long after it was signed. Check the server clock and send a fresh request.
yes
E026
Hash missing. The hash header was absent.
no
E027
Hash does not match. The hash was computed over different bytes, or with the wrong private key.
no
E028
Account not fully set up. The subscription is not yet activated at the bureau.
no
E029
Report not in contract. The subscription does not include this report type. Answered before the subject is looked at.
no
E030
Private key invalid. The private key has been revoked at the bureau.
no
E031
report_reason missing. This report type needs report_reason.
no
E032
report_reason invalid. report_reason is not a number.
no
E033
report_reason not recognised. report_reason is not in the report reason list.
no
E409
Duplicate request. The same request reached the bureau within the last minute. Wait, or use the answer already received.
Learned from live production responses, and handled by the Interchange so your integration does not have to be:
api_code arrives as a number or a string depending on the report. The Interchange always returns a string or null.
E017 on an entitled report is a thin or unknown file. It is an answer, not a failure.
Days in arrears count to the lender's last upload (loaded_at), not to today. The Interchange carries the date with every figure.
An account reported open with a nil balance is settled but not yet re-flagged. It is not counted as live exposure.
Enquiry counters are not real-time. Several pulls on one identity did not move them within half an hour.
For the same person on the same day, the bureau's printed report and its API can list different account counts. Every Interchange figure states which source it came from.
Report 12 nests identity fields inside the verification block while leaving the outer fields empty. The Interchange reads the nested values.