Schemas and validation
Every object in the contract, every field, and every rule your payload is validated against. 69 schemas, generated from the specification itself.
It is produced directly from openapi.yaml version 1.0,
so it cannot drift from the contract your requests are actually validated against. If a
rule is here, the validator enforces it.
Almost every object sets no unknown fields. A misspelled or extra property
returns 400 naming it in param, rather than being silently
dropped. A silently dropped field is a value you believe you sent and we never
received.
A value that could not be obtained is never given a favourable reading. If
availability is anything but available, the schema forces the
accompanying value and band to null and the accompanying result to
not_evaluated. You cannot construct a payload in which an unobtainable
input scores well, and neither can we.
Envelope#
Assessment#
One assessment of one applicant against one policy version.
Inputs are append-only and results are written once. There is no endpoint that modifies a completed assessment. Re-running a case creates a new assessment carrying previous_assessment_id, which means a re-run can never overwrite the verdict a lender has already acted on, and the history of what was decided when survives intact.
This object carries a conditional rule: some fields are required, or constrained to null, depending on the value of another field. A payload that ignores it is rejected rather than accepted and corrected.
Always true in v1. There is no test environment; the documented examples are the only keyless surface. Carried from the start so that adding one later does not change the shape of a response.
The deadline for input an assessment is waiting on.
Treat this as the deadline to act on, not as a state to wait for. The transition to expired can lag this time. Stop waiting when expires_at passes; do not wait for status to become expired.
Tenant-scoped, not a bare date. Two tenants cannot share a version namespace, so the version string identifies whose policy as well as which one.
Set when this assessment re-runs an earlier one.
Present only when status is failed.
The opaque key-value pairs supplied on the create request, returned verbatim.
Never interpreted, never used in any evaluation, and never a place to put anything the contract has its own field for. Present on the assessment and on every callback carrying it, which is the cleanest way to correlate a result with your own case record without keeping a map of our identifiers.
Absent where the create request carried none.
{
"id": "asm_7NpF4c2wQ9",
"object": "assessment",
"mode": "screening",
"status": "screening",
"country": "EE",
"livemode": true,
"created_at": "2026-07-06T09:14:23Z",
"updated_at": "2026-07-06T09:14:23Z",
"completed_at": null,
"expires_at": null,
"policy_version": "tenant-policy-2026-07",
"previous_assessment_id": null,
"applicant": {
"country": "EE",
"registry_code": "10000000",
"legal_name": "Example Trading OU"
},
"coverage": {
"registry": "live",
"financial_statements": "live",
"tax": "not_supported",
"bureau": "live",
"sanctions": "live",
"legal": "live",
"beneficial_owners": "not_entitled",
"bank_data": "not_consented",
"acquiring": "not_supported",
"bank_labels": "classifier"
},
"result": null
}AssessmentList#
Pass as starting_after to fetch the next page.
AssessmentMode#
Which of the two stages to run.
screening runs the first stage only. Cases that clear it are the only ones that go further.
Which conditions and ratios make up the first stage is declared on the policy version, at GET /v1/policies/{version}. It is a property of the policy, not of the market. What a first stage can actually reach depends on what the market publishes, and that is reported per case in coverage.
Both modes return 202 and deliver by callback, and both return the same response shape. They differ only in how far the evaluation runs.
| Value | Meaning |
|---|---|
screening | |
full |
AssessmentStatus#
Where the assessment is. Terminal states are complete, failed and expired.
result is present if and only if the status is complete, and the schema enforces it.
| Value | Meaning |
|---|---|
screening | Public registry sources are being gathered and the first-stage gates evaluated. |
awaiting_bank_data | Screening finished without a terminal outcome and bank data is required to go further. |
processing | Paid sources and the full policy evaluation are running. |
complete | Terminal. |
failed | Terminal. Processing could not complete. Distinct from a policy rejection, which is a |
expired | Terminal. Required input did not arrive within the window, so the assessment was closed without a result. |
AssessmentResult#
The evaluated output. Written once and never modified.
Every non-ratio condition the policy defines, including those that could not be evaluated. A condition absent from this array was not defined by the policy; a condition that could not be evaluated is present with result: not_evaluated.
Existing credit per subject, as the bureau reports it. Empty where the policy runs no bureau enquiry.
The lender-supplied values this evaluation consumed, echoed raw. Present so a result is reproducible from the result alone, without going back to the request that produced it.
no unknown fieldsInputs#
Applicant#
Who is being assessed, in the identifiers the country's registries actually key on. Which identifiers are required, and their formats, are published per country at GET /v1/countries/{code} rather than fixed here.
ISO 3166-1 alpha-2.
pattern: ^[A-Z]{2}$The national company registration number.
The identifiers a market uses that are not one of the fields above.
Poland keys registry lookups on a tax number, holds its companies on a court register under a second number, and carries a third statistical number; the Baltic markets need none of those.
The accepted keys are exactly the field values that GET /v1/countries/{code} publishes for this country. Any other key is rejected with 400.
What the applicant trades in, each code qualified by its scheme. Supply whichever the lender holds; where none is supplied, Credit Atlas uses the classification the national registry carries for the entity, and an eligibility rule written against a scheme the case has no code for returns not_supported rather than passing by default.
Representative#
One natural person connected to the applicant.
A company may have several, and the contract takes them as a list. A company with two signatories and a separate majority owner is three people, and a policy that runs a personal condition reports its result per person.
Every check evaluated against a person names that person in PolicyCheck.subject.ref, which is why ref is required rather than convenient.
Personal identifiers are accepted only where the country's registry or bureau keys on them, and the assessment records which consent authorised each use. Where a market's beneficial-ownership or bureau source is restricted to entity classes that Credit Atlas does not belong to, the corresponding coverage is not_entitled or lender_supplied, and it is not attempted on the caller's behalf.
Your own identifier for this person, unique within the request. It is echoed on every check evaluated against them and is never interpreted. Use whatever your own case record uses.
pattern: ^[A-Za-z0-9_.:-]{1,64}$How this person is connected to the applicant, in your own vocabulary. Carried through to the audit trail and never parsed.
National personal identifier, where the market's sources require one. Optional everywhere. Policy.borrower_checks.required_identifiers says when a policy needs it.
LoanRequest#
Tenant-defined product identifier.
PartnerData#
The data only the lender holds, because it describes the lender's own relationship with the borrower: how long that relationship has run, what the lender's own lists say about the counterparty, and the commercial data the lender holds from the products it already sells. A lender that also acquires the borrower's card payments holds processed turnover and chargeback behaviour that no registry publishes.
Where this object is absent, indicators defined over lender-held data return not_supported with requires naming what was missing, rather than being silently skipped.
Merchant category code. Note that a code may sit under more than one category in a scheme's own tables, so an exclusion list keyed on it is not a clean lookup and the tenant's policy decides the mapping.
The lender's own list, as the lender resolved it.
The internal_blacklist condition is lender-supplied by definition. The contract takes the outcome of the lender's own lookup, not the list itself.
Omit the object entirely where no lookup was performed: the condition then reports not_supported with requires: [partner_data] rather than passing by default. An absent list is not a clean list.
The outcome of the lender's own beneficial-ownership screening.
Same pattern as internal_list_match. Access to beneficial-ownership registers is restricted to entities with a statutory basis for customer due diligence, so the lender performs the lookup and supplies the outcome.
Supplying this sets coverage.beneficial_owners to lender_supplied, which is a distinct state from live and from not_entitled: it records that the screening happened and that the lender did it.
Omit the object entirely where no screening was performed. The beneficial_owners_screened condition then reports not_evaluated, and if the policy marks it mandatory the outcome is capped. An absent screening is not a clean one.
Consents#
The lender's attestation that it holds the consents its request requires.
Credit Atlas does not capture consent from the borrower and does not present a consent screen. The lender is the controller of that relationship; this object records what the lender attests to holding, with the time it was captured, so the attestation is auditable against the assessment it authorised.
data_processing must be true for any assessment. The others gate specific sources: without bureau_enquiry no bureau is called, and without account_information bank data is refused rather than merely unused, with coverage.bank_data: not_consented.
Must be true. An assessment cannot proceed without it.
PSD2 account-information access for the borrower's bank data.
default: FalseThe lender's own reference for the consent record.
Bank data#
BankDataSubmission#
Bank transaction data for an assessment, submitted by the lender.
The lender initiates the borrower's account-information journey on its own institution agreement and submits the result here.
Volume and currency. A submission carries at most 50,000 transactions across at most 50 accounts, and the request body must not exceed 10 MB. A file larger than this is a sign that the window is wider than any policy needs; narrow the window rather than splitting the submission, because there is exactly one permitted submission per assessment and a partial one cannot be topped up.
Transaction currency does not have to match the currency of the loan request, and accounts in several currencies may be submitted together. Amounts are used as supplied, in the currency each transaction declares; the contract performs no conversion. Where a policy's threshold is stated in one currency and the evidence arrives in another, the indicator reports the currency it measured in and the policy decides whether the comparison is meaningful.
Minimum history is tenant policy, not a fixed number in this contract. It is evaluated against coverage.days_measured, meaning what actually arrived, and never against declared_from/declared_to, which is what the upstream promised.
At most 50,000 items. A submission exceeding this, or exceeding the 10 MB body limit, is rejected with 413 and nothing is stored. The assessment stays in awaiting_bank_data and the corrected submission is still the one permitted submission.
The start of the window the upstream says it covers, where it says so. What was actually measured is reported back in coverage.
BankDataProvider#
Which shape the submitted bank data has. Not a vendor name: the contract cares about one difference only, which is whether transactions arrive categorised.
The schema normalises transport, direction, dates and balances across both shapes. It does not invent categories the upstream never sent.
| Value | Meaning |
|---|---|
labelled | Transactions arrive with a category per row supplied by the provider. |
unlabelled | Transactions arrive as amount, date, counterparty and free text. Categories are present only if a classifier is deployed for this market, and |
BankAccount#
The submitter's identifier for the account. Used to group transactions.
Last four characters only. The full account identifier is not required to compute anything in this contract and is not accepted.
Opaque institution identifier as the submitter's provider issues it.
BankTransaction#
This object carries a conditional rule: some fields are required, or constrained to null, depending on the value of another field. A payload that ignores it is rejected rather than accepted and corrected.
The provider's transaction identifier where one exists. Some feeds issue none, in which case deduplication falls back to account, date and amount. That is weaker, and is why this field is requested whenever available.
Where the upstream distinguishes booking date from value date. Absent from some feeds, which is why both are carried rather than one being assumed.
format: dateUnsigned. Direction is carried separately.
min: 0Null when no categories are available for this market.
Present when category_source is classifier. A provider label carries no confidence because none is published with it.
TransactionDirection#
Normalised direction. Submitted amounts may be signed or unsigned depending on the upstream; direction is always explicit here so that sign conventions cannot silently invert a cash-flow calculation.
| Value | Meaning |
|---|---|
credit | |
debit |
CategorySource#
Where a transaction's category came from. Required whenever a category is present, so that a threshold calibrated on provider labels is never applied unknowingly to classifier output.
| Value | Meaning |
|---|---|
provider | |
classifier |
BankDataCoverage#
How much history the bank data actually spans, declared and measured separately.
Only some upstreams declare a coverage window up front. Where one does, the declared window and the window the transactions actually occupy can differ. A policy requiring a minimum history must be evaluated against what arrived, not against what was promised. Reporting one number for both is how a short file passes a history test it should have failed.
Null where the upstream declares no window.
min: 0Span actually covered by the submitted transactions.
min: 0Financials#
CanonicalKey#
Country-neutral name for a financial statement line item. Fifteen keys carry every ratio this API computes. A market is added by mapping its filing scheme onto these keys. No ratio definition changes.
| Value | Meaning |
|---|---|
cash | Cash and cash equivalents. |
receivables | Trade receivables and prepayments. |
inventory | Inventories. |
current_assets | Total current assets. |
total_assets | Total assets. |
short_term_borrowings | Borrowings falling due within twelve months. |
current_liabilities | Total current liabilities. |
total_liabilities | Total liabilities, current and non-current. |
equity | Total equity. |
revenue | Net sales revenue for the period. |
depreciation_amortisation | Depreciation, amortisation and impairment of fixed assets. |
operating_profit | Operating profit. |
interest_expense | Interest and similar finance costs. |
net_profit | Profit for the reporting period. |
operating_cash_flow | Net cash flow from operating activities. |
LineItem#
This object carries a conditional rule: some fields are required, or constrained to null, depending on the value of another field. A payload that ignores it is rejected rather than accepted and corrected.
Null whenever availability is anything but available.
ISO 4217.
Human-readable explanation, generated from availability and the entity's circumstances. Present whenever availability is not available.
{
"key": "current_assets",
"value": 412300,
"currency": "EUR",
"availability": "available",
"source_ref": {
"scheme": "XX_NATIONAL_REGISTER",
"row": "0000",
"period": "2025"
}
}SourceRef#
Where a value came from, in the source's own terms. Present only when availability is available.
scheme and row are the native identifiers of the filing scheme the value was read from, and are opaque to the contract: ratios are defined on canonical keys, never on scheme rows.
Identifier of the filing or reporting scheme.
The line reference within that scheme, as the scheme labels it.
Reporting period the value was read from.
Availability#
Why a value is or is not present. Applies uniformly to line items, ratios and indicators.
A missing value is a state, not an error. not_filed and source_unavailable are different facts about the borrower, and only one of them is worth retrying.
| Value | Meaning |
|---|---|
available | Obtained. |
not_filed | The entity is legally exempt from filing this, or filed an abridged form that omits it. Not an error, and not a negative signal by itself. |
not_published | No public source exists for this item for this entity type in this country. Typically sole traders, whose financial statements are not published anywhere. |
not_consented | Requires a consent that has not been recorded yet. Usually bank data before the borrower has completed the account-information journey. |
not_entitled | Requires an entitlement or licence that the caller, or Credit Atlas, does not hold for this source in this market. Distinct from a failure: the source is working and the request was well formed, but it may not lawfully be served. |
source_unavailable | The source exists and we are entitled to it, but the call did not succeed. Retryable. |
not_supported | The country adapter does not implement this item yet. Declared in advance via the country capability map, never discovered at runtime. |
Ratio#
This object carries a conditional rule: some fields are required, or constrained to null, depending on the value of another field. A payload that ignores it is rejected rather than accepted and corrected.
Stable identifier for the ratio.
One of current_ratio, quick_ratio, cash_ratio, equity_ratio, net_profit_margin, operating_profit_margin, return_on_assets, operating_cash_flow_ratio, days_sales_outstanding, interest_coverage, debt_service_coverage, debt_to_ebitda
The definition in canonical keys. Stated so an integrator can reproduce the number without reference to any national filing scheme.
Canonical keys this ratio consumes.
One of ratio, percent, days, times
Canonical keys that prevented computation. Empty when availability is available. This is what makes an uncomputed ratio diagnosable rather than merely absent.
The band boundaries applied, from the policy version named on the assessment. Three boundaries produce four bands. Returned only to the tenant that owns the policy.
min items: 3max items: 3{
"key": "current_ratio",
"label": "Current ratio",
"group": "liquidity",
"direction": "higher_is_better",
"formula": "current_assets / current_liabilities",
"inputs": [
"current_assets",
"current_liabilities"
],
"value": 2.08,
"unit": "ratio",
"availability": "available",
"band": "strong",
"missing_inputs": [],
"thresholds": [
0.9,
1.4,
1.8
]
}RatioGroup#
Ratio grouping. The group is reported on every ratio because a policy may apply different rules to different groups; what those rules are is tenant configuration.
| Value | Meaning |
|---|---|
liquidity | |
profitability | |
operating_efficiency | |
credit_risk |
RatioDirection#
Which end of the scale is strong. higher_is_better bands ascending; lower_is_better bands descending. Direction is explicit on every ratio rather than implied by its name.
| Value | Meaning |
|---|---|
higher_is_better | |
lower_is_better |
Band#
Ordinal assessment band, weakest first. Null means the ratio could not be computed, because an input was unavailable or the arithmetic was undefined, such as a zero denominator.
A null band is never treated as a passing band, and is never substituted with a favourable one. Policies that count "poor" ratios must count null separately; it is an absence of evidence, not weak evidence.
| Value | Meaning |
|---|---|
poor | |
fair | |
good | |
strong | |
null |
RatioSummary#
Counts of ratios by band, split by group. Which rule applies to which group is tenant configuration and is not described here.
unavailable is reported alongside poor and never folded into it, and computable is the denominator a poor count is measured against.
The denominator each group's poor count is measured against. It counts ratios that could actually be computed, not ratios that are defined. A rule stated as a count is meaningless without it.
no unknown fieldspoor divided by computable, per group. Which line items an entity must file depends on its size class, so the denominator varies between borrowers and a rule expressed as a rate keeps its meaning at any denominator. EvidenceSufficiency sets the floor below which the rate is not read at all.
Ratios with a non-null band.
Ratios defined for this assessment.
{
"poor": {
"credit_risk": 1,
"other": 3
},
"unavailable": {
"credit_risk": 0,
"other": 1
},
"computable": {
"credit_risk": 3,
"other": 8
},
"poor_rate": {
"credit_risk": 0.333,
"other": 0.375
},
"evaluated": 11,
"total": 12
}Outcome#
PolicyOutcome#
The outcome, the policy version that produced it, and what constrained it.
capped_by says which happened: policy means the rules chose the outcome, evidence means thin evidence forced it. Those need different handling in a queue.
One or more ceiling rules apply: a more favourable value is rejected when the evidence does not support it. The constraint is one-directional, so a less favourable value always remains valid.
The tenant policy version applied. Every outcome is reproducible from it.
evidence when the sufficiency gate capped the outcome below what the policy's rules alone would have produced; policy when the rules themselves determined it; null when nothing capped it.
One of evidence, policy, null
{
"value": "review",
"policy_version": "tenant-policy-2026-07",
"capped_by": "evidence",
"evidence_sufficiency": {
"level": "degraded",
"outcome_ceiling": "review",
"groups": {
"credit_risk": {
"computable": 2,
"defined": 3,
"floor": 3,
"met": false
},
"other": {
"computable": 8,
"defined": 9,
"floor": 8,
"met": true
}
},
"reason": "A ratio in the credit-risk group could not be computed for this entity class."
},
"ratios": {
"poor": {
"credit_risk": 0,
"other": 1
},
"unavailable": {
"credit_risk": 1,
"other": 1
},
"computable": {
"credit_risk": 2,
"other": 8
},
"poor_rate": {
"credit_risk": 0,
"other": 0.125
},
"evaluated": 10,
"total": 12
}
}PolicyOutcomeValue#
The result of applying the lender's own configured policy to the evidence gathered. It is not a creditworthiness decision made by Credit Atlas, and it does not replace one. The lender's analyst retains decision authority.
| Value | Meaning |
|---|---|
approve | The policy's conditions for its most favourable outcome were all met. |
review | The policy routed this to a human, or the evidence was too thin to permit a more favourable outcome. Which of the two it was is in |
reject | The policy's own rejection conditions were triggered by observed values. |
insufficient_evidence | This is not a rejection, and integrators must not map it to one. No conclusion about the subject was reached, because too little could be computed. An entity's filing obligations follow from its size class, so mapping this outcome to a rejection turns an applicant's size into a credit negative. |
EvidenceSufficiency#
The sufficiency gate, evaluated per ratio group and before the policy's decision rules. It can cap an outcome. It can never improve one.
Groups are judged separately rather than on the total, so thin evidence in one group is visible rather than averaged away.
Floors are policy configuration, returned only to the tenant that owns the policy.
One or more ceiling rules apply: a more favourable value is rejected when the evidence does not support it. The constraint is one-directional, so a less favourable value always remains valid.
The most favourable outcome reachable given the evidence. The policy's own rules may land below this; they can never land above it.
Non-ratio conditions the policy marks mandatory that could not be evaluated.
Any entry here forces outcome_ceiling below approve, enforced by the schema. The ceiling constrains only the favourable direction, so reject stays reachable and a condition that did fire still fires on a thin file.
A condition the policy runs per representative or per related company appears here once per subject it could not be evaluated for, written <key>:<ref>, so a reader can tell one unscreened director from three.
Why the level is what it is, naming the group or the condition and the shortfall. Present whenever level is not sufficient.
{
"level": "degraded",
"outcome_ceiling": "review",
"groups": {
"credit_risk": {
"computable": 2,
"defined": 3,
"floor": 3,
"met": false
},
"other": {
"computable": 8,
"defined": 9,
"floor": 8,
"met": true
}
},
"unavailable_mandatory_checks": [],
"reason": "A ratio in the credit-risk group could not be computed for this entity class, so the group is below the floor its rules assume."
}EvidenceLevel#
How much evidence the assessment has, judged before any policy rule is applied to it.
An input that could not be obtained never improves an outcome. Unavailable items leave the denominator the policy's counts are measured against, and this level independently caps what outcome is reachable at all. It can only cap a result, never raise one.
| Value | Meaning |
|---|---|
sufficient | Enough of each group was computable for the policy's rules to carry their intended meaning. The full decision table applies. |
degraded | Computable, but on a materially thinner base than the policy assumes. The outcome is capped, so the most favourable outcome becomes unreachable however good the computed values look. |
insufficient | Too little was computable to support any conclusion about the subject. This is a statement about the evidence, never about the subject. |
EvidenceGroup#
Ratios in this group that could actually be computed.
min: 0Ratios the catalogue defines for this group.
min: 0Minimum computable count this group requires. Tenant configuration.
min: 0Gates#
The assessment's stages and how each one ended, so an analyst can see where a case turned.
Which gates exist is fixed by the contract; what each one does is the policy. Evaluation stops at the first fail, so no further source is consulted once a case has ended.
{
"eligibility": "pass",
"registry": "pass",
"aml": "pass",
"financial": "review",
"monitoring": "pass"
}GateResult#
Per-stage result. not_evaluated is distinct from pass: a gate that never ran because an earlier gate stopped the assessment has not passed anything.
| Value | Meaning |
|---|---|
pass | |
review | |
fail | |
not_evaluated |
SupportableAmount#
The amount the evidence supports, with its own availability.
A capacity of zero and a capacity that could not be computed are opposite findings: a null value means the capacity could not be computed, a zero value means the computed capacity is nothing.
This object carries a conditional rule: some fields are required, or constrained to null, depending on the value of another field. A payload that ignores it is rejected rather than accepted and corrected.
ISO 4217. Explicit, never inferred from the country.
Which computed quantity the cap derives from, named in the contract's own vocabulary so it can be traced to a ratio or an indicator.
{
"value": 84000,
"currency": "EUR",
"availability": "available",
"basis": "debt_service_coverage"
}Checks#
PolicyCheck#
One non-ratio condition, evaluated against one subject: what it observed, what it was compared against, and whether it could be evaluated at all.
Reported for every condition the policy defines, including the ones that could not be evaluated. A condition absent from this array was not defined by the policy.
One condition can appear more than once. A condition the policy runs against each representative produces one entry per person, distinguished by subject. A consumer that assumes key is unique in this array will silently drop all but one of them.
Threshold values are policy configuration, returned only to the tenant that owns the policy.
This object carries a conditional rule: some fields are required, or constrained to null, depending on the value of another field. A payload that ignores it is rejected rather than accepted and corrected.
Which condition this is.
Either one of the contract's own CheckKey values, or a condition this product's policy version declared for itself, written custom.<name>. The fixed vocabulary is what lets two integrators agree on what a condition is called; the custom form is what lets a lender bring a condition the vocabulary does not have.
True when key is a custom.<name> condition. Present so a consumer can separate the contract's own vocabulary from a tenant's own without parsing the key.
Display name. Generated from key; never the only place a fact appears.
Which gate this condition belongs to. Matches a key of gates.
One of eligibility, registry, aml, financial, monitoring
Whether the policy's most favourable outcome depends on this condition being evaluated.
A mandatory condition that could not be evaluated caps the outcome. See EvidenceSufficiency.unavailable_mandatory_checks. A non-mandatory one that could not be evaluated is recorded and does not cap anything.
The value measured. Null whenever availability is not available, enforced by the schema below.
The RatingScale.id that observed and threshold are expressed on, where this condition is a comparison on a scale. Null for conditions that are not, such as a boolean or a bare count.
Present so the comparison can be reproduced. On an ordinal scale the ranking is the position of the value in the scale's grades array; comparing the grades as strings gives the wrong answer and must not be done.
What observed was compared against. Polymorphic by necessity: a floor is a number, a review corridor is a pair, a rating floor is a grade on the scale named in scale, and a condition such as a sanctions result has no threshold at all.
Which evidence produced the observation, in the same vocabulary as evidence.sources[].source.
Display string, generated from the fields above.
{
"key": "sanctions_match",
"subject": {
"kind": "company"
},
"stage": "aml",
"label": "Sanctions screening",
"availability": "not_entitled",
"result": "not_evaluated",
"mandatory": true,
"observed": null,
"threshold": null,
"source": "sanctions.screening",
"message": "Sanctions screening was not performed, because it requires an entitlement that is not in place for this market. This is not a statement that the applicant is clear."
}CheckKey#
The vocabulary of non-ratio conditions a policy may evaluate.
Which of these a given policy actually uses, in what order, and against what boundary is tenant configuration. The vocabulary is fixed by the contract so that two integrators building against it agree on what a condition is called.
A key appearing here is not a promise that the data behind it is obtainable in every market. GET /v1/countries/{code} says where it is, and each check carries its own availability.
| Value | Meaning |
|---|---|
registered_address | Whether the entity is registered in a market the policy admits. |
annual_reports_available | How many periods of filed statements exist. |
industry_eligibility | Whether the borrower's trade category is admitted. Evaluated against the applicant's |
partner_relationship_length | How long the applicant has been a customer of the lender. |
average_monthly_turnover | Turnover over the policy's averaging window. |
chargeback_ratio | Chargebacks as a share of acquiring volume. |
credit_rating | An external rating or score, compared against a floor on a declared scale. The scale is named in |
probability_of_default | An externally supplied default probability, compared against a reject boundary and a review corridor. Two boundaries, not one. Where a market publishes a default probability rather than a graded rating, this is the condition a policy writes instead of |
tax_debt | Outstanding tax debt, usually expressed relative to turnover. |
payment_defaults | Count of historical defaults within a lookback window. A policy may require a default to clear more than one test before it counts, a minimum age and a minimum amount for instance, so the count reported here is the count after the policy's own qualifying rule has been applied. |
active_defaults | Whether any default is currently open. |
legal_proceedings | Court rulings or proceedings on record against the entity. |
sanctions_match | Result of sanctions screening. Where screening cannot lawfully be performed on the caller's behalf, |
beneficial_owners_screened | Whether beneficial owners were identified and screened. Public access to beneficial-ownership registers is restricted in several markets to entities with a statutory basis, so this is frequently |
high_risk_jurisdiction | Exposure to a jurisdiction the policy treats as high risk. |
internal_blacklist | A match against the lender's own list. Lender-supplied by definition. |
revenue_trend | Average monthly revenue over the recent window divided by the average over an earlier window, from bank data. Both windows are policy configuration. Compared against a reject floor and a review corridor. |
ebitda_positive | Whether earnings before interest, tax, depreciation and amortisation are positive. |
CheckResult#
How one condition ended.
not_evaluated is distinct from pass. Sanctions screening that could not be performed is not a statement that the applicant is clear, and the contract will not let it be reported as one.
| Value | Meaning |
|---|---|
pass | |
review | |
fail | |
not_evaluated |
Explainability#
ReasonCode#
Why the outcome is what it is, as data rather than prose.
Every code carries the value observed and the threshold it was compared against and the policy version that set that threshold, so an outcome can be replayed months later against the rules that were in force when it was produced.
message is generated from the structured fields. It is never the only place a fact appears. Anything an integrator might want to act on is a field.
Stable identifier, unique within a policy version.
What was measured, in the contract's own vocabulary: a ratio key, an indicator key, or a named gate input.
The value measured. Null when the code fired on an absence.
What observed was compared against. Polymorphic by necessity: a floor is a number, a review corridor is a pair, a rating floor is a string, and a condition that is simply required is a boolean.
Boundaries are policy configuration, returned only to the tenant that owns the policy.
Which evidence produced the observation, in the same vocabulary as evidence.sources[].source.
The policy version whose threshold this code was evaluated against. Repeated per code rather than only on the assessment, because a code may be carried forward from an earlier evaluation.
Display string, generated from the fields above.
{
"code": "FIN-07",
"severity": "review",
"driver": "debt_service_coverage",
"observed": 0.94,
"threshold": 1.35,
"band": "poor",
"source": "registry.financial_statements",
"policy_version": "tenant-policy-2026-07",
"message": "Debt service coverage below the configured floor."
}ReasonSeverity#
| Value | Meaning |
|---|---|
info | Recorded as a driver but did not constrain the outcome. |
review | Contributed to routing the case to a human. |
reject | Sufficient on its own, under the tenant's policy, to trigger its rejection conditions. |
AnalystQuestion#
A question for the lender's analyst to put to the borrower, generated from the drivers that constrained the outcome.
The API produces the evidence and the questions that evidence raises, and the lender's analyst decides.
text is the question as it should be shown. The structured fields are there so each question can be routed, tracked and closed against the driver that raised it.
The ratio, indicator or gate input that raised it.
The ReasonCode.code this question exists to resolve, when there is one.
What would answer it, stated so the request can be made once.
Indicator#
A single behavioural or fraud signal. Indicators follow the same availability discipline as ratios: one that could not be computed is reported with triggered: null, never triggered: false.
false means the pattern was looked for and is absent. null means nobody looked, and it is never reported as false.
This object carries a conditional rule: some fields are required, or constrained to null, depending on the value of another field. A payload that ignores it is rejected rather than accepted and corrected.
Null whenever availability is not available. Never defaulted to false.
Capabilities this indicator needs. Explains any non-available state.
{
"key": "single_day_turnover_spike",
"label": "Single-day turnover spike",
"category": "fraud",
"availability": "available",
"triggered": false,
"observed": 2.4,
"requires": [
"transaction_amounts"
]
}IndicatorCategory#
What an indicator is about. fraud and lending are derived from bank transaction data; acquiring needs card-level data that only the lender's own acquiring relationship produces.
| Value | Meaning |
|---|---|
fraud | |
lending | |
acquiring |
IndicatorRequirement#
A capability an indicator cannot be computed without. Published on the indicator itself, so the reason an indicator is unavailable in a market can be read in advance.
| Value | Meaning |
|---|---|
transaction_amounts | Amounts and dates only. Available from every bank-data adapter. |
transaction_labels | A category per transaction. Some aggregators supply these; a raw PSD2 feed does not, and no classifier exists for every market. See |
counterparty_names | A named creditor or debtor per transaction. |
counterparty_jurisdiction | The country of the counterparty, which most PSD2 feeds do not carry. |
acquiring_data | Card-level settlement data. Held by the lender when the lender is also the acquirer, and obtainable nowhere else. |
Evidence#
Evidence#
Everything the assessment was built from. Present on every result, including a rejected one.
EvidenceSource#
One source consulted, and what came back.
Stable, country-neutral identifier for the source class. Named third parties do not appear in this field.
Whether this retrieval was chargeable. Reported so a lender can reconcile its own source costs per assessment.
The source's own reference for the retrieval, where it issues one.
StatementsProbe#
What the entity actually filed for a period, established by a capability probe before any statement is fetched.
One probe call per entity turns a missing value into a statement that was never required: not_filed rather than source_unavailable.
Whether the entity filed an abridged form. Where a filing exemption is conditional on the abridged format, an entity that filed in full may carry items its size class would ordinarily omit, so this is probed and never assumed from size class alone.
SizeClass#
The entity's reporting size class, which governs what it is obliged to file and therefore which ratios can exist at all.
The class is established before any statement is fetched, so the ratio set a borrower can produce is known in advance rather than inferred from what came back empty.
| Value | Meaning |
|---|---|
micro | |
small | |
medium | |
large | |
unknown |
Capability#
Coverage#
What was consulted for this assessment, and why anything was not. Returned on every assessment, so no absence has to be inferred from a gap in the output.
This is a record, not a forecast. It says what happened on this case and makes no claim about what a different case in the same market would reach.
Court rulings, insolvency proceedings and enforcement records. Reported separately from registry because the register that holds a company's identity and the register that holds proceedings against it are different registers, on different terms, in every market this contract serves. A policy evaluating legal_proceedings reads this field to learn whether the condition could be evaluated at all.
{
"registry": "live",
"financial_statements": "live",
"tax": "not_supported",
"bureau": "live",
"sanctions": "live",
"legal": "live",
"beneficial_owners": "lender_supplied",
"bank_data": "live",
"acquiring": "not_consented",
"bank_labels": "classifier"
}CoverageState#
Whether a *source* is usable for this assessment. A different enum from Availability, which describes a *value*: a source can be live while a particular value is absent because the entity never filed it.
| Value | Meaning |
|---|---|
live | Implemented, licensed, and called for this assessment. |
lender_supplied | Not retrieved by Credit Atlas. The lender performed the lookup under its own entitlement and supplied the outcome on the request, and the assessment used what it was given. Reported distinctly so the audit trail records which party performed the lookup. |
not_consented | Implemented, but the required consent has not been recorded. |
not_entitled | Implemented, but serving it in this market requires an entitlement that is not in place, and the lender supplied nothing in its place. |
not_supported | Not implemented for this market. |
source_unavailable | Implemented and entitled, but the call did not succeed. |
BankLabelSource#
Where transaction categories come from in this market, or that there are none.
Some account-information providers return a category per transaction. A raw open-banking feed returns a counterparty name, a free-text reference and nothing else. Any indicator defined over categories is unavailable in the second case unless a classifier has been built for that market's language and text.
| Value | Meaning |
|---|---|
provider | The bank-data provider supplies a category per transaction. |
classifier | Categories are derived by a Credit Atlas classifier from unlabelled transaction text. Each category carries a confidence, and |
not_supported | No categories are available in this market. Indicators requiring |
Country#
What a market can do, declared in advance.
A market that is declared but not implemented appears here with status: declared, never absent from the list and never failing at runtime.
What a market reached on any individual case is reported on that assessment, in Assessment.coverage. It is not promised here.
One of live, limited, declared
The rating and score scales this market's sources actually return.
Published per country because markets do not share one. A bureau in one market grades on ordered letters, another returns a number where a higher value is better, a third returns a number where a lower value is better. A policy that names a floor names it on one of these scales, and a consumer that wants to render or re-check the comparison needs the scale to do it.
A market with no rating source publishes an empty array.
The classification schemes an eligibility rule can be written against in this market. A card scheme's merchant categories are global; a national activity classification is not, and the two do not map onto one another cleanly.
CountryList#
IdentifierField#
One identifier a country requires, with the format its registry actually uses. Published so an integrator can validate before sending rather than discovering the format from a 400.
Regular expression the value must match.
Policy#
A tenant's own policy version, as applied.
One version corresponds to one lending product. A lender running several products holds several versions, and policy_version on the assessment is the only thing that selects between them: the rules, the boundaries and the custom inputs all travel together under that one identifier, so an outcome is reproducible from it.
This endpoint returns only the calling tenant's configuration. A tenant can read the policy it owns and no other, and no boundary from any other tenant's policy appears in any field.
Which lending product this version governs, in the lender's own vocabulary. Recorded so two versions can be told apart without decoding the identifier.
Null while current. A superseded version stays readable so past outcomes replay.
format: dateWhat mode: screening evaluates.
The first stage is a property of the policy, not of the market, so it means the same thing in every country the policy covers.
A condition named here that the market cannot reach still reports not_evaluated on the assessment. Declaring a condition does not make its source exist.
Per ratio key, the three boundaries that produce the four bands, in the direction the ratio bands. The caller's own values.
Per condition, the boundary it is compared against.
Keyed by CheckKey or by custom.<name>. The value takes the same shapes as PolicyCheck.threshold: a number for a floor, a pair for a review corridor, a grade for a rating floor on that market's scale, a boolean for a condition that is simply required, or null for one that has no boundary.
Which conditions cap the outcome when they cannot be evaluated. The same list that drives EvidenceSufficiency.unavailable_mandatory_checks.
Minimum computable ratio count per group, as configured.
The ordered rules that map observations to an outcome. First match wins; reaching the end without a match yields review.
Per RatingScale.id, the least favourable value the policy admits on that scale, expressed in that scale's own terms.
A floor is written on one scale and is meaningful only on it. The contract performs no conversion between scales, so a policy operating in several markets carries a floor per market rather than one global grade.
The inputs this product accepts beyond the contract's own fields, and the shape each value must take. Null or empty where this product declares none.
Whether this policy evaluates conditions against the people representing the applicant, and which.
Declared on the policy, not inferred from whether representatives was sent.
Whether this policy screens the companies supplied in related_companies, and with which conditions. Null or enabled: false means related_companies is recorded but not used.
The setting that sends an assessment to awaiting_bank_data.
A full assessment moves to awaiting_bank_data when the policy defines any condition that bank data is the only evidence for, and the first stage has not already reached a terminal outcome. Read this to know, before sending a case, whether it will be asked for bank data.
mode: screening never enters this state whatever this setting says, because the first stage does not run conditions that need bank data.
{
"version": "tenant-policy-bnpl-2026-07",
"country": "EE",
"product": "bnpl",
"effective_from": "2026-07-01",
"effective_to": null,
"screening_stage": {
"checks": [
"registered_address",
"industry_eligibility",
"annual_reports_available"
],
"ratios": [
"current_ratio",
"equity_ratio"
],
"terminal_outcomes": [
"reject"
]
},
"ratio_bands": {
"current_ratio": [
0.9,
1.4,
1.8
],
"equity_ratio": [
0.1,
0.25,
0.4
]
},
"check_thresholds": {
"probability_of_default": [
2.0,
6.0
],
"payment_defaults": 5,
"sanctions_match": null,
"custom.basket_value": 1000
},
"mandatory_checks": [
"sanctions_match",
"registered_address"
],
"evidence_floors": {
"credit_risk": 3,
"other": 8
},
"decision_rules": [
{
"id": "R-01",
"outcome": "reject",
"conditions": [
{
"subject": "check.sanctions_match",
"operator": "eq",
"value": "fail"
}
]
},
{
"id": "R-02",
"outcome": "approve",
"conditions": [
{
"subject": "poor_count.credit_risk",
"operator": "eq",
"value": 0
}
]
}
],
"rating_floors": {
"bureau_alpha_7": "B1",
"bureau_pd_percent": 6.0
},
"custom_inputs": [
{
"name": "basket_value",
"label": "Basket value",
"type": "number",
"unit": "EUR",
"minimum": 0,
"maximum": 5000,
"mandatory": true,
"description": "Value of the transaction being financed."
}
],
"borrower_checks": {
"enabled": true,
"checks": [
"payment_defaults",
"sanctions_match"
],
"required_identifiers": [
"national_id"
]
},
"related_company_checks": {
"enabled": true,
"checks": [
"sanctions_match",
"high_risk_jurisdiction"
]
},
"requires_bank_data": {
"required": true,
"minimum_days": 180,
"conditions": [
"revenue_trend"
]
}
}Events#
Event#
The body of a callback. One shape for every event type; data.object is always the full assessment as it stood when the event fired.
The object is always re-readable at GET /v1/assessments/{id}, which is the recovery path when a callback is missed.
The opaque key-value pairs supplied on the create request, returned verbatim.
Never interpreted, never used in any evaluation, and never a place to put anything the contract has its own field for. Present on the assessment and on every callback carrying it, which is the cleanest way to correlate a result with your own case record without keeping a map of our identifiers.
Absent where the create request carried none.
EventType#
| Value | Meaning |
|---|---|
assessment.screening.completed | |
assessment.bank_data.required | |
assessment.bank_data.received | |
assessment.completed | |
assessment.failed |
Errors#
ErrorResponse#
Error#
Errors follow one shape everywhere, including inside a failed assessment's failure field.
Stable, specific identifier. Switch on this, not on message.
Human-readable. May change; never parse it.
The offending field, dotted from the request root.
Quote this when asking about a specific call.
ErrorType#
| Value | Meaning |
|---|---|
authentication_error | The API key is missing, malformed, revoked or not valid for this environment. |
invalid_request_error | The request was understood and is not acceptable: a malformed field, an unknown country, or an operation that is not legal in the assessment's current state. |
consent_error | A required consent was not attested. Separate from a validation error because the remedy is different: the caller must obtain something from the borrower, not correct a field. |
entitlement_error | The request is well formed but requires an entitlement that is not in place for this source in this market. Separate from an authentication failure, and from a source outage, because it will not resolve by retrying. |
idempotency_error | An |
rate_limit_error | Too many requests. |
api_error | Something failed on our side. Safe to retry. |
Other#
CheckSubject#
Who a condition was evaluated against.
A policy may test a company's rating and, separately, the payment history of each person representing it, so a clean company with one problematic director is distinguishable from the reverse.
A condition evaluated against three representatives produces three entries in checks, one per person, each with its own result. Related companies are reported the same way. Each entry names the ref the request supplied, so a consumer can join a result back to its own record without matching on a name.
This object carries a conditional rule: some fields are required, or constrained to null, depending on the value of another field. A payload that ignores it is rejected rather than accepted and corrected.
One of company, representative, related_company
The ref from representatives or related_companies. Null when kind is company, required otherwise, enforced below.
Echoed for display. Never the only place the identity appears.
CreditExposure#
The credit a subject already carries, as the credit bureau reports it: how many facilities are open, what is outstanding, and what is repaid each month.
One entry per subject the bureau was queried for: the company and, where the policy runs personal conditions, each representative.
monthly_instalments is the sum of the scheduled instalments across every open facility. Revolving facilities carry no instalment, and their use is reported in credit_limit_used. A revolving line is never left out of the totals.
Amounts are in currency, as reported. Exposure is reported for the analyst and for the policy; it is not an input to any ratio.
This object carries a conditional rule: some fields are required, or constrained to null, depending on the value of another field. A payload that ignores it is rejected rather than accepted and corrected.
In the same vocabulary as evidence.sources[].source.
ISO 4217.
Number of open facilities of every type.
min: 0Total outstanding across every open facility, revolving included.
min: 0Total scheduled monthly instalments across every open facility.
min: 0Total limit across open revolving facilities.
min: 0Amount drawn against those limits.
min: 0The open facilities behind the totals, where the bureau itemises them.
Present whenever availability is not available.
{
"subject": {
"kind": "company"
},
"availability": "available",
"source": "bureau.credit_report",
"currency": "EUR",
"open_facilities": 3,
"outstanding_balance": 186400,
"monthly_instalments": 7350,
"credit_limit_total": 40000,
"credit_limit_used": 12600,
"facilities": [
{
"type": "instalment",
"lender_category": "bank",
"outstanding": 141000,
"instalment": 5900,
"limit": null,
"days_past_due": 0,
"opened_on": "2023-03-01",
"maturity_on": "2028-02-29"
},
{
"type": "leasing",
"lender_category": "non_bank",
"outstanding": 32800,
"instalment": 1450,
"limit": null,
"days_past_due": 0,
"opened_on": "2024-09-15",
"maturity_on": "2027-09-14"
},
{
"type": "revolving",
"lender_category": "bank",
"outstanding": 12600,
"instalment": null,
"limit": 40000,
"days_past_due": 0,
"opened_on": "2022-05-10",
"maturity_on": null
}
]
}CreditFacility#
One open credit facility on the bureau report.
One of instalment, revolving, leasing, factoring, other
Whether the facility is with a bank or a non-bank lender. Lenders are not named.
One of bank, non_bank, null
Balance outstanding.
min: 0Scheduled monthly instalment. Null on a revolving facility.
min: 0Credit limit, on a revolving facility.
min: 0Days currently overdue. Zero when the facility is up to date.
min: 0CustomInputDeclaration#
One input a policy version accepts, and the shape a value for it must take.
Published so an integrator can validate before sending rather than discovering the rule from a 400.
The key used in custom_inputs, and the part after the dot in the custom.<name> check key.
One of number, integer, boolean, string, enum
Free text, for display. Never used to convert a value.
Numeric types only. A value below this is rejected, never clamped.
Numeric types only. A value above this is rejected, never clamped.
The complete set of values accepted, where type is enum.
Whether a condition defined over this input caps the outcome when the value is absent. Follows the same rule as PolicyCheck.mandatory.
What the lender means by this input. Recorded, never interpreted.
{
"name": "basket_value",
"label": "Basket value",
"type": "number",
"unit": "EUR",
"minimum": 0,
"maximum": 5000,
"mandatory": true,
"description": "Value of the transaction being financed."
}CustomInputs#
Values for the inputs this policy version declares for itself.
partner_data covers the lender-held facts that are common to lending generally. This object covers the ones specific to one product, that the contract has no field for.
A lender running several products declares a policy version per product, and each version declares the inputs its rules need. Read them back at GET /v1/policies/{version} before sending.
Three rules:
1. Declared or rejected. A name this policy version did not declare, a value of the wrong type, or a number outside the declared range, returns 400 with type invalid_request_error. Nothing is coerced and nothing is ignored. 2. Absence is never favourable. A declared input that is mandatory and absent makes its condition not_evaluated with requires: [custom_inputs], exactly as an absent registry value would. It never passes by default. 3. Values are evidence, not configuration. These are facts about this borrower on this case. The boundaries they are compared against live in the policy version, where every other boundary lives. A caller cannot send a threshold.
Each declared input is reported back as a custom.<name> entry in checks, and the raw values are echoed under result.inputs.custom.
{
"basket_value": 340.0,
"repeat_customer": true,
"settlement_delay_days": 14
}DecisionRule#
One rule in the ordered list that maps what was observed to an outcome.
Rules are evaluated in order and the first one whose conditions all hold decides the outcome. A policy that reaches the end without a match yields review, because falling off the end of a rule list is not evidence of creditworthiness.
The sufficiency gate is applied afterwards and can only lower the result. A rule that yields approve on an insufficient file produces review or insufficient_evidence, and PolicyOutcome.capped_by records that it was the evidence rather than these rules that decided it.
Stable identifier for this rule within the policy version.
The lender's own wording for what this rule is for.
All conditions must hold for the rule to fire. An empty array is a rule that always fires, which is how a policy writes its fallback.
{
"id": "R-01",
"outcome": "reject",
"description": "Any hard stop rejects, whatever the ratios say.",
"conditions": [
{
"subject": "check.sanctions_match",
"operator": "eq",
"value": "fail"
}
]
}IndicatorKey#
The vocabulary of behavioural and fraud signals. New keys may be added within v1, so a consumer should tolerate a key it does not recognise.
| Value | Meaning |
|---|---|
single_day_turnover_spike | Largest single-day inflow against the average day in its month. |
balance_below_zero_days | Days in the window with a negative closing balance. |
payments_to_other_lenders | Repayments to other lenders as a share of turnover. |
collections_activity | Payments to debt collection agencies as a share of turnover. |
round_value_transfers | Round-value incoming payments as a share of turnover or of payment count. |
cash_credits_share | Cash deposits as a share of inflow. |
counterparty_concentration | The largest single counterparty's share of inflow. |
cross_border_counterparties | Transactions with counterparties outside the market, by value. |
chargeback_rate | Chargebacks as a share of acquiring volume. |
refund_rate | Refunds as a share of acquiring volume. |
IndustryCode#
One classification of what the applicant trades in, qualified by the scheme the code belongs to.
The scheme is required because the same digits mean different things in different schemes, and because an eligibility list written against a card scheme's merchant categories cannot be applied to a national activity classification. Note also that within a single scheme a code can sit under more than one trade, so a rule turning solely on a code will misclassify some borrowers in both directions.
Which classification the code belongs to. Published per market in Country.industry_schemes.
The scheme's own description of the code, where the source supplies one.
RatingScale#
An ordered scale that a rating or score in this market is expressed on.
Grades are compared by position, never as strings. On an ordinal scale the first entry in grades is the most favourable and each subsequent entry is less favourable, so a comparison is an index comparison. Comparing grades lexicographically is a defect: it ranks AAA above AA, B above AAA, and it passes a grade that should fail. Producers and consumers both resolve grades through this object.
One or more ceiling rules apply: a more favourable value is rejected when the evidence does not support it. The constraint is one-directional, so a less favourable value always remains valid.
Stable identifier for the scale, referenced by PolicyCheck.scale. Scoped to the source and the market, because two providers in one country may grade differently.
Display name for the scale.
One of ordinal, numeric
Which end of the scale is the favourable one. Required on every scale, including ordinal ones, so that a consumer never has to infer it from the grade names. A default-probability scale and a credit-quality scale run in opposite directions and can otherwise look identical.
One of higher_is_better, lower_is_better
For an ordinal scale, every grade in order from most to least favourable. Position in this array is the only ranking that the contract recognises. Null on a numeric scale.
Lower bound of a numeric scale. Null on an ordinal scale.
Upper bound of a numeric scale. Null on an ordinal scale.
{
"id": "bureau_alpha_7",
"label": "Bureau letter grade",
"kind": "ordinal",
"direction": "higher_is_better",
"grades": [
"A1",
"A2",
"B1",
"B2",
"C1",
"C2",
"D"
],
"min": null,
"max": null,
"notes": "Seven ordered grades, most favourable first. A policy floor names one of them, and every grade below that position fails. Ranking is decided by index, never by comparing the grades as text."
}RelatedCompany#
One company connected to the applicant.
Screened against the conditions the policy lists in related_company_checks, typically sanctions and high-risk jurisdiction. Every check evaluated against it names it in PolicyCheck.subject.ref.
Your own identifier for this company, unique within the request. Echoed on every check evaluated against it and never interpreted.
pattern: ^[A-Za-z0-9_.:-]{1,64}$ISO 3166-1 alpha-2. May differ from the applicant's.
pattern: ^[A-Z]{2}$The company's national registration number in country.
How this company is connected to the applicant, in your own vocabulary. Carried through to the audit trail and never parsed.