Developers API v1

Start here

Credit Atlas is a credit risk engine for business lending. A company identifier goes in. A scored credit assessment comes out, with every input that produced it. One integration covers Estonia, Latvia and Poland.

What Credit Atlas does#

You send the company you are assessing and the policy version to apply. Credit Atlas gathers the evidence that is publicly and lawfully available about that company, normalises it, computes the ratios and checks the policy names, and returns a structured result: the outcome, and every observation that led to it.

The work happens in the background: a create is accepted immediately and answered later on a signed callback, so nothing in your code waits on a registry having a slow morning. What comes back is a scored assessment rather than a single opaque number: a policy outcome, twelve financial ratios each in a band, every policy check with its own result, and reason codes carrying the value observed and the threshold it was compared against.

How an assessment is built#

  1. Company and borrower data. The identifiers that market uses, the representatives and related companies to screen, and the loan being requested. In Estonia the company identifier is an eight-digit registry code. In Latvia it is a registration number of six, eight, nine or eleven digits. Do not assume eleven. In Poland it is a ten-digit tax identification number.
  2. Public and bureau evidence. From the identifier, Credit Atlas reaches the company registry, the statutory filings, the tax authority, the legal registers, the credit bureau, including the credit each subject already carries, and sanctions screening.
  3. Bank account data. The applicant's account history, obtained by you under your own account-information agreement and submitted to Credit Atlas. You initiate the borrower's journey, so Credit Atlas never stands between you and that relationship.

The policy version#

Every request names a policy_version. It is the rule set applied to the evidence: which checks run, the thresholds they run against, and the extra fields your product sends. One version per lending product, so this one string is the only selector there is.

Versions are configured by Credit Atlas from the rules you supply and issued to you at onboarding. They are never edited in place: a change returns a new identifier, so an outcome can be replayed later against the exact rules that produced it. Read one back at GET /v1/policies/{version}.

Custom inputs

Most products score on something only the lender holds, such as a basket value or a repeat-customer flag. The policy version declares those fields up front, with their type, unit and allowed range. You send them as custom_inputs and they come back as checks alongside every other condition, with the values you sent echoed.

An undeclared name, or a value outside the declared range, returns 400. It is never quietly ignored, because a silently dropped input changes an outcome and nobody notices. A declared input that is mandatory and absent is reported as missing and never read as favourable.

One integration, three markets#

Markets differ in filing scheme, identifier format, rating scale and in what is obtainable at all. Those differences are published as data at GET /v1/countries/{code} rather than written into the request and response shapes, so the shapes never change. Statement line items are normalised to a fixed vocabulary of canonical keys such as current_assets and revenue, and every ratio is defined on those keys. Adding a country is a mapping table on our side, not a new integration on yours.

Read GET /v1/countries/{code} at runtime and branch on what it says. A client that hard-codes one market's identifier pattern, ratio list or rating direction will break when it meets the next market. Rating scales in particular are not comparable between markets, and a floor set in one says nothing about any other. The model page has the detail.

Where the lender decides#

Credit Atlas is an evidence and infrastructure provider. policy_outcome states the result of applying the configured policy to the evidence gathered. It is not a creditworthiness decision made by Credit Atlas, and the lender's analyst retains decision authority.

Every outcome names the policy version that produced it, every reason code carries the value observed and the boundary it was compared against, and analyst_questions arrives as structured data. An outcome you cannot replay months later is not one you can defend.

All endpoints#

Eight operations, and that is the whole surface. Each links to its full reference.

Five callback events carry the work back to you, two of them terminal. The catalogue, the payloads and the signature scheme are on the webhooks page.

Connect#

You are issued a per-tenant key at onboarding, along with the host to send it to and the signing secret for verifying callbacks. Send the key as X-Api-Key on every request. The host is environment-specific and given to you at onboarding rather than published here.

Confirm the key and the host together with GET /v1/countries. It touches no upstream source, so it costs nothing.

Create an assessment#

Pick a mode. screening runs the first stage and stops there. full continues into the rest of the policy and, where it needs it, into bank data. Both return 202. What the first stage contains is declared on the policy version and readable at GET /v1/policies/{version}.

Send an Idempotency-Key on every create. An assessment can trigger a chargeable lookup, so a retry without a key bills twice.

Screen before running in full

Evaluation stops at the first gate that fails, so a case rejected on eligibility never reaches a paid source. A follow-up linked with previous_assessment_id is a full run rather than a resume, so one full assessment is cheaper than a screening one followed by a full one.

Bank consent is collected at create time

consents.account_information defaults to false. Without it attested on the assessment, a later bank-data submission returns 402, and no endpoint adds a consent after the fact. The only remedy is a new assessment.

Collect it from every applicant you send in full mode, not only the ones you expect to reach that stage. It costs nothing when unused.

Receive the callback#

Register one HTTPS endpoint. Every event is delivered to it, signed. Verify the signature over the raw body before parsing, compare in constant time, and reject a stale timestamp. Deduplicate on event.id, because an acknowledgement that times out is retried even though the first delivery arrived. Verification samples are on the authentication page.

Attach bank data#

When assessment.bank_data.required arrives, start the borrower's account-information journey under your own agreement, then post the result back.

Accepted exactly once

This call is legal only while the assessment is in awaiting_bank_data. In every other state, including after a successful submission, it returns 409. To re-evaluate with different data, create a new assessment with previous_assessment_id set.

Read the result#

result is present if and only if status is complete, and the schema enforces it. Six things to read, in the order most integrations need them:

A full worked result for each market ships with the contract, at api/examples/ee/assessment.json and the same path for lv and pl. The full contract is api/openapi.yaml.

FieldWhat it tells you
policy_outcome.value approve, review, reject or insufficient_evidence. Read capped_by alongside it: a review chosen by the rules means something different from one forced by thin evidence
supportable_amount Capacity, with its own availability. A capacity of zero and a capacity that could not be computed are opposite findings
reason_codes Why, as data. Each carries the observed value, the threshold and the policy version
checks Every non-ratio condition, such as a rating floor, a default count, a sanctions result or an eligibility test, each with its own availability. A condition that was never evaluated reports not_evaluated, never pass
credit_exposure The credit the company and each representative already carry, from the bureau: open facilities, outstanding balance, monthly instalments and credit limits
coverage Which sources were consulted, and why any of them were not
Insufficient evidence is not a rejection

insufficient_evidence means no conclusion about the applicant was reached, because too little could be computed. Mapping it to a rejection turns an applicant's size into a credit negative.

Integration checklist#