Skip to content

Conventions ​

Rules that hold for every endpoint. The API reference gives the exact types and limits of each field.

Requests and responses ​

  • Base URLs: https://partners.sandbox.finto.lt and https://partners.finto.lt. Every path starts with /v1.
  • JSON in UTF-8. Send Content-Type: application/json; application/json; charset=utf-8 is accepted too. Uploads use multipart/form-data.
  • Field names are camelCase, enum values snake_case.
  • Requests are strict: an unknown field is rejected with 422 validation_failed and the field's path, so a typo cannot slip through. An optional field may be left out or sent as null; an empty list counts as not sent.
  • Responses are complete: every documented field is present, and an empty value is null. Ignore fields you do not know: new ones are added without a new version.
  • Enum values you do not know must not break you: new products, income types, document types, closing reasons, event types and error codes may be added (announced 30 days ahead, see the changelog). Treat an unknown product as one you do not offer, an unknown income type as other, an unknown event type by ignoring it, and an unknown error code by its HTTP status.

Values ​

KindFormatExample
MoneyEuros as a JSON number, up to 2 decimals14500, 267.89
PercentageA number of percent, 0 to 200, up to 3 decimals10.78 (10.78 %)
TimestampRFC 3339. Finto sends UTC; you may send any offset2026-11-20T08:14:03Z, 2026-11-24T13:02:00+02:00
DateYYYY-MM-DD, Europe/Vilnius calendar2026-12-04
IdOpaque string up to 64 characters. Store it, do not parse itcmi7q2x4k0001lb08h3k2v9de
ReferenceHuman-readable application number, random, not sequentialP-7KQ2MX

Text you send must not contain control characters (except line breaks in message) or invisible formatting characters such as bidirectional overrides. Text shown to the client (offer.conditions, requirements[].description) must be in plain Lithuanian and must not contain links: give the client your link through offer.continueUrl only.

Authentication ​

http
Authorization: Bearer fnt_live_...
  • The key decides the lender and the environment: fnt_test_ keys work only in the sandbox, fnt_live_ keys only in live.
  • In live, every request must also come from an address on your IP allow-list.
  • Keys expire after at most 12 months (GET /v1/me shows expiresAt); Finto reminds your technical contact 30 days before. Up to two keys are active at once, so you can rotate without downtime.
  • POST /v1/api-key/revoke revokes the key that sends it, immediately. See security.md.

Idempotency ​

Every POST that changes something is safe to retry if you send an Idempotency-Key header. It is required for decisions and uploads, and optional for test events and sandbox calls.

Rule
What a key meansOne intended change. Generate it (a UUID) when you decide to make the change, store it with the change in your system, and reuse it on every retry of that change
ScopeYour lender and environment. A key used once cannot be used for another application, another endpoint or another body
Same key, same requestYou get the original result back: the same body with status 200 instead of 201
Same key, different request422 idempotency_key_reused
Same key while the first request is still running409 idempotency_key_in_progress: wait a second and retry
ErrorsNot stored. After a 4xx or 5xx you may retry with the same key, with or without fixing the request
How bodies are comparedAs JSON values: field order and whitespace do not matter. For uploads: the type, title and the file's SHA-256
How long keys are keptDecisions: as long as the decision exists. Other requests: 24 hours

Do not derive keys from the meaning of a request alone (for example <applicationId>-in_review): you may legitimately send in_review twice, and the second one would silently return the first.

Versions of an application ​

version counts changes you can see, starting at 1: corrected data and documents added for you. Other lenders have their own count; your own uploads do not change it. Every decision you send states the applicationVersion it is based on: the version of the application you fetched.

Order of decisions ​

Finto applies your decisions in the order it receives them, one at a time per application. decidedAt is for display only. If several of your processes may decide on the same application, send previousDecisionId (the decision.id you last saw, null for the first): when it no longer matches, Finto refuses the request with 409 decision_conflict instead of applying a decision made on outdated information.

Lists and cursors ​

  • GET /v1/applications pages with limit (up to 100) and cursor (nextCursor of the previous page).
  • GET /v1/events reads after a sequence (after) and returns lastSequence to store. See webhooks.md.

Limits ​

LimitValue
Requests per key600 per minute (429 rate_limited with Retry-After)
JSON body64 KB
Upload10 MB per PDF; 20 files and 50 MB per application
Decisions50 per application
Test events5 per minute, not retried
Sandbox applications200 per day

Going over a count limit returns 422 quota_exceeded; going over a rate (requests or test events per minute) returns 429 rate_limited.

Request ids ​

Every response has a Finto-Request-Id header (also requestId in error bodies). Log it with your request, and quote it when you contact Finto.

Code generation ​

Generate clients from openapi-3.0.json (OpenAPI 3.0.3). It describes the same API as openapi.json (OpenAPI 3.1, used for the documentation), with two differences that matter for code generators:

  • nullable fields use nullable: true, and files use format: binary;
  • enums that Finto sends and may extend are plain strings with the known values in x-extensible-enum, so a new value cannot make your client throw. Enums you send (DecisionStatus, reasons, requirement types) stay closed.

If you generate from openapi.json with openapi-generator instead, set enumUnknownDefaultCase=true.