Developers API v1

API reference

Eight operations across seven paths. Every one of them is listed here; there is no undocumented surface.

Requests and responses#

ConventionDetail
Base URLhttps://{host}/v1. The host is issued at onboarding
AuthenticationX-Api-Key header on every request. Details
Content typeapplication/json on every request body and response
IdempotencyIdempotency-Key on every POST. Keys retained 24 hours
Correlation400 and 500 responses carry Request-Id. Quote it when asking us about a call
Unknown fieldsRejected, not ignored. A misspelled field returns 400 naming it in param
TimestampsRFC 3339, UTC, e.g. 2026-07-06T09:14:22Z
MoneyAlways a value and an explicit currency. Never a bare number
One success shape for creates

POST /v1/assessments returns 202 and nothing else. There is no inline-result response to branch on, in either mode. The outcome arrives on a callback, and the GET endpoints are the recovery path.

Errors#

Every error has the same shape: a type you can branch on, a code carrying the specificity, a human message, the offending param where one applies, and a doc_url.

TypeHTTPWhen, and what to do
authentication_error401Key missing, malformed or revoked. Do not retry
invalid_request_error400, 404, 409Malformed field, unknown country, or an operation illegal in the current state. Fix and resend
consent_error402A required consent was not attested. The remedy is with the borrower, not the payload
entitlement_error403Well formed, but your tenant is not entitled to a country or source the request needs. Retrying will not help. Not used for a market-wide gap, which caps the outcome instead of refusing the request
idempotency_error409A key was reused with a different body. Use a new key, or resend the original body
rate_limit_error429Back off using Retry-After. Expected, not exceptional
api_error500Our side. Safe to retry with the same idempotency key

Create an assessment#

POST /v1/assessments

Starts an assessment of one applicant against one policy version. Returns 202 in both modes.

Body

FieldRequiredNotes
modeRequiredscreening or full
policy_versionRequiredA policy version belonging to you. One version per lending product
applicantRequiredCountry and the identifiers that market uses. Secondary identifiers go in additional_identifiers
consentsRequiredWhat the borrower agreed to, and when. You attest, we record
representativesOptionalOne entry per person the policy screens. Each carries its own ref, which every check on that person reports back in subject
related_companiesOptionalCompanies connected to the applicant that the policy screens, such as a parent or a company sharing a director. Each carries its own ref, reported back in subject
requestOptionalAmount, currency, term. Required for a supportable amount to mean anything
partner_dataOptionalData only the lender holds, such as relationship length or an internal list result. Several eligibility and fraud signals cannot compute without it
custom_inputsConditionalWhatever the policy version declares. An undeclared name or an out-of-range value returns 400, never a silent pass
previous_assessment_idOptionalSet when re-evaluating a case. Links the new assessment to the old one
metadataOptionalOpaque string pairs, echoed back everywhere. Never interpreted, never used in evaluation

Responses

CodeMeaning
202Accepted and running. status is screening, result is null
400Malformed, or an identifier that does not match the published pattern for the country
402A required consent was not attested
403Your tenant is not entitled to something the request needs, such as a country or a source your keys do not reach. A source unavailable in the market for everyone does not return 403: the assessment runs and the outcome is capped instead
409Idempotency key reused with a different body
429Rate limited

List assessments#

GET /v1/assessments

Cursor-paginated, newest first, scoped to you. This is the recovery path after an outage: the consumer that missed a callback is the one that does not have the id.

Query parameterNotes
statusOne of the six lifecycle states
countryTwo-letter code
created_afterRFC 3339. The parameter to use after an outage
limit1 to 100, default 25
starting_afterA next_cursor from a previous page. Opaque, so do not parse it

Retrieve an assessment#

GET /v1/assessments/{id}

The full envelope: status, coverage, the inputs as submitted, and result once there is one. Safe to poll, though callbacks are the intended path.

Retrieve the result#

GET /v1/assessments/{id}/result

Just the evaluated output. Returns 409 while the assessment is still running, rather than an empty object.

A complete worked result for each market ships with the contract: api/examples/ee/assessment.json, api/examples/lv/assessment.json and api/examples/pl/assessment.json. Each is a full envelope carrying every ratio, check, indicator, credit exposure entry and reason code that market can produce, and each is validated against this specification on every build.

Attach bank data#

POST /v1/assessments/{id}/bank-data

The single permitted append to an assessment. Legal only in awaiting_bank_data; 409 in every other state, including after a successful submission.

FieldRequiredNotes
providerRequiredlabelled or unlabelled, meaning whether transactions arrive with a category. Not a vendor name
accountsRequiredOne entry per account, with its currency. At most 50. We never ask for a full account number
transactionsRequiredAmounts unsigned, with an explicit direction. At most 50,000, and the body must stay under 10 MB
declared_from ยท declared_toOptionalThe window your upstream says it covers. We measure the window that actually arrived and report both back in coverage
Amounts are unsigned and direction is explicit

Sign conventions differ between upstreams, and an inverted sign is invisible in a cash-flow total. Send the magnitude and say debit or credit.

List countries#

GET /v1/countries

Every market the contract declares, with what each one can do. A market whose adapter is not built appears here with status: declared, never absent and never present-but-failing at runtime.

Example response: api/examples/countries.json.

Retrieve a country#

GET /v1/countries/{code}

Identifier schema, rating scales and industry schemes for one market. Read it before sending a case: the identifiers a market keys on and the scales its sources grade on are not the same in any two markets, and a floor written on one market's scale means nothing on another's.

Example responses: ee, lv, pl.

What runs at the first stage is not published here. It is a property of the policy version and is read from GET /v1/policies/{version}.

Retrieve a policy version#

GET /v1/policies/{version}

The policy configuration, as it was applied: the band boundaries per ratio, the thresholds per condition, the evidence floors, the ordered decision rules, the rating floor per market, the custom inputs the product declares, and which conditions make up the first stage.

Every outcome names the policy_version that produced it, and superseded versions stay readable for as long as any assessment cites them, so a decision taken months ago can be replayed against the rules that took it.

Tenant-scoped. You read the policies you own and no others; no boundary belonging to any other tenant appears in any field of any response.

Versions are configured by Credit Atlas from the rules you supply. A change is requested through your account contact and returns a new version identifier. Existing versions are never edited in place.