Autorekisteri

Autorekisteri machine API v1.0.0

Vehicle-registry lookups for integrations. Authenticate with OAuth 2.0 client credentials, then send the access token as Authorization: Bearer. Every successful lookup is a billed Traficom query attributed to your organisation. Documentation: https://api.business.autorekisteri.fi/docs

Download openapi.json OpenAPI 3.1.0: import into Postman, Insomnia or a client generator.

Integration guide

For developers connecting a system to Autorekisteri's vehicle-registry lookups. The formal contract is openapi.json (OpenAPI 3.1); this guide explains how to use it.

Production Test
API https://api.business.autorekisteri.fi https://api.business-test.autorekisteri.fi
Token URL https://arek-prod-client.auth.eu-west-1.amazoncognito.com/oauth2/token https://arek-test-client.auth.eu-west-1.amazoncognito.com/oauth2/token
Data Traficom production register. Every lookup is billed. Traficom test system, test plates only

1. Get credentials

An administrator of your organisation creates an API client in https://business.autorekisteri.fi → Tili → Rajapinta-asiakkaat and chooses which lookup tiers it may use. The portal shows the client ID, client secret, token URL and API URL once. Store the secret in your secret manager; if it is lost, create a new client and revoke the old one. Your organisation must first be enabled for API access by Autorekisteri.

Use one client per system, so that one can be revoked without stopping the others. Revocation takes effect immediately, including for tokens already issued: every request with the client's tokens then gets 401 CLIENT_REVOKED.

A client can be revoked by an administrator of your organisation, or by Autorekisteri.fi staff (for example when a credential is reported leaked). Your organisation's administrators are e-mailed whenever a client is created or revoked, with the client's name, its tiers, who made the change and when; the mail never contains a client ID or secret. The portal also flags a client nobody has used for 90 days, so that a forgotten credential can be revoked.

2. Get an access token

OAuth 2.0 client credentials, HTTP Basic authentication with the client ID and secret:

curl -s -X POST "$TOKEN_URL" \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'grant_type=client_credentials'
{ "access_token": "eyJ…", "expires_in": 3600, "token_type": "Bearer" }

Without a scope parameter the token carries every scope your client was granted. The token is valid for 60 minutes. Cache it and reuse it until shortly before expires_in; do not request a new token for every lookup.

Scopes, where {api} is the API URL from the table above:

Scope Allows
{api}/lookup.perus lookups with tier: perus
{api}/lookup.laaja lookups with tier: laaja
{api}/lookup.historia lookups with tier: historia
{api}/usage.read GET /v1/usage

Any lookup.* scope also allows reading back your own lookups and their PDFs.

3. Look up a vehicle

curl -s -X POST "$API/v1/lookups" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: order-4711' \
  -d '{"registrationNumber":"ABC-123","vehicleType":"auto","tier":"historia"}'
  • registrationNumber: a Finnish plate (ABC-123, 123-ABC, CD-1234, C-12345). Case and spaces do not matter and a missing hyphen is inserted (abc123 is ABC-123); the plate in every response is the normalised one. The plate's shape must be one the vehicle type has in the register (L a letter, Å, Ä and Ö included; N a digit):

    vehicleType shapes
    auto LL-N … LL-NNNN, LLL-N … LLL-NNN
    perakarry LLL-N … LLL-NNN, LL-NNNN
    moottoripyora LL-N … LL-NNN, NN-LLL
    mopo NN-LLL, LL-NN, LL-NNN
    moottorityokone N-LL … NNN-LL, N-LLL … NNN-LLL
    maastoajoneuvo NNN-LL, NNN-LLL

    CD-N … CD-NNNN and C-N … C-NNNNN are accepted for every type. Anything else is refused with 400 INVALID_REGISTRATION_NUMBER before a query is made or billed; when the plate is a valid shape for some other type, the problem also carries vehicleType and expectedShapes (the list above for that type). Check both the registration number and the vehicle type.

  • vehicleType: auto, moottoripyora, moottorityokone, maastoajoneuvo, perakarry (trailers and caravans) or mopo.

  • tier: perus, laaja or historia.

The call is synchronous and usually answers within a few seconds; allow up to 30 seconds before treating it as timed out.

{
  "lookupId": "k3q7…",
  "registrationNumber": "ABC-123",
  "vehicleType": "auto",
  "tier": "historia",
  "createdAt": "2026-10-16T10:15:00.000Z",
  "outcome": "ok",
  "traficomErrorCode": null,
  "resultExpiresAt": "2026-10-17T10:15:00.000Z",
  "report": { "sections": [ … ], "owners": [ … ], "notices": [ … ], "unknownCodes": [] }
}

outcome — check this before reading report

outcome Meaning report What to do
ok Traficom answered present use it
atjError Traficom answered with an error code, most often "no such vehicle" null show traficomErrorCode; check the plate and the vehicle type before a new lookup
empty Traficom did not answer null try again later; do not retry in a loop

All three are HTTP 200, because the query completed and was recorded.

The report

report.sections[] contains { key, title, fields[] }, and each field is { key, label, value }. Program against key. title and label are Finnish display text, and value is a display string ("13.09.2010", "1 598 cm3") or null when the register has no value. Every section and field key is listed in openapi.json. Repeated entries have numbered keys (katsastus.1, katsastus.2, …).

report.owners[] follows the disclosure rules filed with Traficom: a private person's name or address may be withheld, and is then replaced by fixed wording. Each owner's group says whether it is a current owner (owner), a current holder (holder) or an ended relationship (previous, historia only), the grouping Traficom's own report uses. report.notices[] holds restrictions and warnings ("Huom. …"). A section that has nothing to show and says so carries emptyState, the sentence to print in its place.

Retention

The report is kept for 24 hours (resultExpiresAt), then deleted. This is a contractual maximum, so plan on it. Your own copy is subject to your agreement with Traficom.

4. Retries and Idempotency-Key

Each lookup is a billed government query. If a request times out you cannot tell whether it reached Traficom, so send an Idempotency-Key on every lookup, unique to your business transaction (A-Z a-z 0-9 . _ : -, at most 128 characters). Repeat the request with the same key and body:

Situation Answer
first request completed the same 200 again, with header idempotent-replayed: true; no new query
first request still running 409 IDEMPOTENCY_IN_PROGRESS with Retry-After
first request was refused before querying (e.g. rate limit) the lookup now runs
same key, different body 422 IDEMPOTENCY_KEY_REUSED
first request failed (502 LOOKUP_FAILED, or 503 LOOKUP_THROTTLED) 502 LOOKUP_FAILED; use a new key to try again

Keys are remembered for 24 hours.

5. Reading results back, PDF and usage

  • GET /v1/lookups/{lookupId} returns the same object for 24 hours, then 410 RESULT_EXPIRED.
  • GET /v1/lookups/{lookupId}/report.pdf with Accept: application/pdf returns the report as a PDF.
  • GET /v1/usage?month=2026-10 (scope usage.read) returns your client's lookups and per-tier counts for invoice reconciliation.

A client can read only lookups it made itself.

6. Errors

Errors are application/problem+json (RFC 9457):

{ "type": "about:blank", "title": "Tier not permitted for this client", "status": 403, "code": "TIER_NOT_PERMITTED" }

Switch on code; title and detail may change. Errors raised by the API gateway itself (missing or invalid token, missing scope, malformed body, unknown path, throttling, firewall) carry the same body with Content-Type: application/json; parse the body, not the header.

Status code Meaning
400 INVALID_BODY, INVALID_REGISTRATION_NUMBER, INVALID_VEHICLE_TYPE, INVALID_IDEMPOTENCY_KEY, INVALID_MONTH fix the request
401 UNAUTHENTICATED missing, expired or invalid token: get a new one
401 CLIENT_REVOKED the client was revoked: ask your administrator for a new one
402 PAYMENT_REQUIRED the organisation's card payment did not go through: see below
403 SCOPE_MISSING, TIER_NOT_PERMITTED the client may not use this tier or route
403 API_NOT_ENABLED, ORGANISATION_DISABLED, NO_CUSTOMER_NUMBER account configuration: contact Autorekisteri
403 FORBIDDEN blocked by the firewall
404 NOT_FOUND no such lookup for this client
409 / 422 IDEMPOTENCY_IN_PROGRESS / IDEMPOTENCY_KEY_REUSED see section 4
410 RESULT_EXPIRED the 24 hours have passed
429 RATE_LIMITED wait Retry-After seconds
502 LOOKUP_FAILED, INTERNAL did not complete; retry later with a new Idempotency-Key
503 LOOKUP_THROTTLED too many lookups in progress at once; Traficom was not asked and nothing is billed. Wait Retry-After seconds and retry with a new Idempotency-Key
503 RATE_LIMIT_UNCONFIGURED service misconfigured: contact Autorekisteri

402 Payment Required

Your organisation's monthly lookups are charged to its payment card on the 1st of the following month. If that charge does not go through, the organisation's admins are warned in the business portal, and after a few days' grace (3 by default) new lookups are paused until the month is paid:

{ "type": "https://api.business.autorekisteri.fi/docs#payment-required", "title": "Payment required", "status": 402, "code": "PAYMENT_REQUIRED", "detail": "…" }

Only POST /v1/lookups stops; reading earlier lookups, reports and usage keeps working. Nothing is sent to Traficom and nothing is billed. An organisation admin updates the card in the business portal (Laskutus), and lookups resume as soon as the payment succeeds, which a new card triggers at once. Retrying the request does not help until then; treat it as a state of your account, not of the request. The type is this page's anchor, on the host you call.

7. Rate limits

Lookups are limited per client, per organisation and service-wide over rolling windows; exceeding a limit answers 429 with Retry-After. Ask Autorekisteri if your expected volume needs higher limits. Fetching tokens is limited separately by the token service, which is another reason to cache them.

8. Moving from the old API

The old endpoint (index.php?option=com_autorekisteripayment&view=api) takes api_pub plus an MD5 auth in the body and answers with Finnish-keyed JSON. This API replaces all of that:

Old New
api_pub + auth = md5(…) Authorization: Bearer <token> from the client-credentials grant
vehicle_type: "Auto", "Perävaunu" vehicleType: "auto", "perakarry"
query_type tier
regno registrationNumber, checked against the vehicle type's plate shapes (section 3)
errors as HTTP 200/400 with {error, description} problem+json with code
yleiset, omistajat, katsastustiedot, … report.sections[].key (see openapi.json)

The two endpoints run in parallel during an agreed transition period.

API reference

Servers

EnvironmentBase URL
Productionhttps://api.business.autorekisteri.fi
Test: Traficom test system, test plates onlyhttps://api.business-test.autorekisteri.fi

Authentication

OAuth 2.0 client credentials. {resourceServer} is the API's own base URL (https://api.business.autorekisteri.fi or the test one). The token URL is shown with your client credentials in the portal.

ScopeAllows
{resourceServer}/lookup.perusLook up with tier perus; read back own lookups
{resourceServer}/lookup.laajaLook up with tier laaja; read back own lookups
{resourceServer}/lookup.historiaLook up with tier historia; read back own lookups
{resourceServer}/usage.readRead own monthly usage

POST /v1/lookups

Look up a vehicle

Synchronous. Answers 200 for every completed query, including when Traficom has no data (outcome: empty) or answers with an error code (outcome: atjError); neither should be retried automatically. Send Idempotency-Key to make a retry after a timeout free of charge.

Scope (any one of): {resourceServer}/lookup.perus {resourceServer}/lookup.laaja {resourceServer}/lookup.historia

Parameters

NameInTypeNotes
Idempotency-KeyheaderstringYour own identifier for this request, 1-128 characters of A-Z a-z 0-9 . _ : -. A repeat within 24 hours returns the first answer without a second query; reusing it for a different request is 422.

Pattern: ^[A-Za-z0-9._:-]{1,128}$

Request body

application/json: LookupRequest

Responses

StatusMeaningBody
200The query completed. idempotent-replayed: true marks an answer from an earlier request with the same key.application/json Lookup
400RFC 9457 problem details. Switch on code; title and detail may be reworded. Errors raised by the gateway itself carry the same body as application/json.application/problem+json Problem
application/json Problem
401RFC 9457 problem details. Switch on code; title and detail may be reworded. Errors raised by the gateway itself carry the same body as application/json.application/problem+json Problem
application/json Problem
402PAYMENT_REQUIRED: the organisation's card payment for a past month did not go through and the grace period has passed, so new lookups are paused. Traficom was not asked and nothing is billed. An organisation admin updates the card in the business portal; lookups resume as soon as the payment succeeds. Earlier lookups and reports stay readable. The problem's type is https://api.business.autorekisteri.fi/docs#payment-required (the test tier's own host on test).application/problem+json Problem
403RFC 9457 problem details. Switch on code; title and detail may be reworded. Errors raised by the gateway itself carry the same body as application/json.application/problem+json Problem
application/json Problem
409RFC 9457 problem details. Switch on code; title and detail may be reworded. Errors raised by the gateway itself carry the same body as application/json.application/problem+json Problem
application/json Problem
410RFC 9457 problem details. Switch on code; title and detail may be reworded. Errors raised by the gateway itself carry the same body as application/json.application/problem+json Problem
application/json Problem
422RFC 9457 problem details. Switch on code; title and detail may be reworded. Errors raised by the gateway itself carry the same body as application/json.application/problem+json Problem
application/json Problem
429A per-client, per-organisation or service-wide limit. Wait Retry-After seconds.application/problem+json Problem
502RFC 9457 problem details. Switch on code; title and detail may be reworded. Errors raised by the gateway itself carry the same body as application/json.application/problem+json Problem
application/json Problem
503LOOKUP_THROTTLED: too many lookups are in progress at once, so this one was not started and Traficom was not asked. Nothing is billed. Wait Retry-After seconds and retry with a new Idempotency-Key. RATE_LIMIT_UNCONFIGURED: the service is misconfigured; no Retry-After, contact Autorekisteri.application/problem+json Problem

GET /v1/lookups/{lookupId}

Read back one of your own lookups

The report is kept for 24 hours (a contractual maximum), then 410 RESULT_EXPIRED.

Scope (any one of): {resourceServer}/lookup.perus {resourceServer}/lookup.laaja {resourceServer}/lookup.historia

Parameters

NameInTypeNotes
lookupId requiredpathstring

Responses

StatusMeaningBody
200The lookupapplication/json Lookup
401RFC 9457 problem details. Switch on code; title and detail may be reworded. Errors raised by the gateway itself carry the same body as application/json.application/problem+json Problem
application/json Problem
403RFC 9457 problem details. Switch on code; title and detail may be reworded. Errors raised by the gateway itself carry the same body as application/json.application/problem+json Problem
application/json Problem
404RFC 9457 problem details. Switch on code; title and detail may be reworded. Errors raised by the gateway itself carry the same body as application/json.application/problem+json Problem
application/json Problem
410RFC 9457 problem details. Switch on code; title and detail may be reworded. Errors raised by the gateway itself carry the same body as application/json.application/problem+json Problem
application/json Problem

GET /v1/lookups/{lookupId}/report.pdf

The report as a PDF

Send Accept: application/pdf. Available for 24 hours, like the report.

Scope (any one of): {resourceServer}/lookup.perus {resourceServer}/lookup.laaja {resourceServer}/lookup.historia

Parameters

NameInTypeNotes
lookupId requiredpathstring

Responses

StatusMeaningBody
200The PDFapplication/pdf string (binary)
401RFC 9457 problem details. Switch on code; title and detail may be reworded. Errors raised by the gateway itself carry the same body as application/json.application/problem+json Problem
application/json Problem
403RFC 9457 problem details. Switch on code; title and detail may be reworded. Errors raised by the gateway itself carry the same body as application/json.application/problem+json Problem
application/json Problem
404RFC 9457 problem details. Switch on code; title and detail may be reworded. Errors raised by the gateway itself carry the same body as application/json.application/problem+json Problem
application/json Problem
410RFC 9457 problem details. Switch on code; title and detail may be reworded. Errors raised by the gateway itself carry the same body as application/json.application/problem+json Problem
application/json Problem

GET /v1/usage

Your client's lookups and counts for a month

Scope (any one of): {resourceServer}/usage.read

Parameters

NameInTypeNotes
monthquerystringYYYY-MM, UTC. Defaults to the current month.

Pattern: ^\d{4}-(0[1-9]|1[0-2])$

Responses

StatusMeaningBody
200Usageapplication/json Usage
400RFC 9457 problem details. Switch on code; title and detail may be reworded. Errors raised by the gateway itself carry the same body as application/json.application/problem+json Problem
application/json Problem
401RFC 9457 problem details. Switch on code; title and detail may be reworded. Errors raised by the gateway itself carry the same body as application/json.application/problem+json Problem
application/json Problem
403RFC 9457 problem details. Switch on code; title and detail may be reworded. Errors raised by the gateway itself carry the same body as application/json.application/problem+json Problem
application/json Problem

Schemas

LookupRequest

FieldTypeNotes
registrationNumber requiredstringFinnish registration number. Case and spaces do not matter and a missing hyphen is inserted. Its shape must be one the vehicle type has in the register (INTEGRATION.md section 3); otherwise 400 INVALID_REGISTRATION_NUMBER.

Example: ABC-123

vehicleType requiredstring

One of: auto moottoripyora moottorityokone maastoajoneuvo perakarry mopo

tier requiredstring

One of: perus laaja historia

Lookup

FieldTypeNotes
lookupId requiredstring
registrationNumber requiredstring
vehicleType requiredstring

One of: auto moottoripyora moottorityokone maastoajoneuvo perakarry mopo

tier requiredstring

One of: perus laaja historia

createdAt requiredstring (date-time)
outcome requiredstringok: report included. empty: Traficom did not answer (no report). atjError: Traficom answered with traficomErrorCode, most often an unknown vehicle.

One of: ok empty atjError

traficomErrorCode requiredstring | null
resultExpiresAt requiredstring | null (date-time)
report requiredReport | null

Report

The same structure the portal and the PDF render. Keys are stable identifiers; title and label are the Finnish display text and value a display string (dates as dd.mm.yyyy, units appended). Owner data follows the disclosure rules filed with Traficom.

FieldTypeNotes
sections requiredarray of ReportSection
owners requiredarray of Owner
notices requiredarray of string
vehicleStatusarray of objectAjoneuvon tila and, for a vehicle out of traffic or off the register, Rekisterikilvet palautettu, drawn above the report. Absent on a lookup stored before 2026-10-19.
vehicleStatus[].label requiredstring
vehicleStatus[].value requiredstring
transferNoticesarray of objectThe Luovutusilmoitustiedot block: each notice of a sale or handover the register holds, as its kind and date only. The buyer is never included. Absent on a lookup stored before 2026-10-19.
transferNotices[].date requiredstring | nulldd.mm.yyyy, or null when the register gave none.
transferNotices[].kind requiredstring | null
unknownCodes requiredarray of object
unknownCodes[].codeSetstring
unknownCodes[].codestring

ReportSection

FieldTypeNotes
key requiredstring
24 allowed values

tietojaAjoneuvosta omistajatJaHaltijat tietojaKatsastuksista moottori rekisterointitodistus muutoskatsastukset turvavarusteet paastot kulutus kori massaJaMitat akselivalit renkaat akselit jarrut kytkenta rakenne omistushistoria katsastushistoria vakuutushistoria kayttohistoria poistot tunnushistoria matkamittarilukemat

title requiredstring
fields requiredarray of ReportField
emptyStatestringPresent only on a section that has nothing to show and states so, as Traficom's own report does (Ei aiempia omistajatietoja., Ei liikennekäytöstäpoistoja.).

ReportField

FieldTypeNotes
key requiredstring | stringA fixed field key, or a repeated entry <base>.<n> (1-based).
70 allowed values

ajoneuvo ajoneuvolaji vari istumapaikkojenLkm valmistenumero kayttoonotettu ensirekisteroity kaytto vakuutusyhtio matkamittarilukema seuraavaKatsastus maaraaikaiskatsastettu iskutilavuus kayttovoima nettoteho rektod1tulostuspvm rektod1jnro rektod2tulostuspvm rektod2jnro tyyppihyvaksyntanro variantti versio kaupallinenNimi tyyppikoodi tyyppinimi valmistaja valmistenumeronSijainti rakennettuAjoneuvo katsastuspaikka moottorinTunnus moottorinNumero sylinterit ahdin valijaahdytin huippunopeus sahkohybridi sahkohybridinluokka paastotaso meluPaikallaan meluKierrosluku meluOhiajossa joutokayntinopeus polttoainesailio pakokaasunPuhdistus vaihteisto vaihteidenLkm valmistajanKilvenSijainti kilvenMalli ovienLkm ovienSijainti tehostettuOhjaus ajovakaudenHallinta akselienLkm korityyppi istuimetKuljVieressa jarrujenTehostamistapa omamassa teknSuurSallKokmassa tieliikSuurSallKokmassa modulinKokonaismassa pituus leveys korkeus yhdistelmanSuurSallMassa massaJarruitta massaJarruin massaJarruittaValmSall massaJarruinValmSall rengastiedot tuontimaa

label requiredstring
value requiredstring | null

Owner

FieldTypeNotes
groupstringA current owner, a current holder, or an ended relationship (historia and kaikki only). Absent on a lookup stored before 2026-10-19.

One of: owner holder previous

title requiredstring
name requiredstring
address requiredstring | null
deathEstate requiredstring | null

Usage

FieldTypeNotes
monthstring
totalinteger
totalsByTiermap of integer
byDayAndTierarray of object
byDayAndTier[].daystring
byDayAndTier[].tierstring
byDayAndTier[].countinteger
lookupsarray of object
lookups[].lookupIdstring
lookups[].registrationNumberstring
lookups[].vehicleTypestring
lookups[].tierstring
lookups[].createdAtstring (date-time)
lookups[].outcomestring

One of: pending ok empty atjError failed

Problem

FieldTypeNotes
type requiredstringabout:blank, except PAYMENT_REQUIRED, whose type is this API's /docs#payment-required.

Example: about:blank

title requiredstring
status requiredinteger
code requiredstring
24 allowed values

NOT_FOUND METHOD_NOT_ALLOWED UNAUTHENTICATED CLIENT_REVOKED ORGANISATION_DISABLED API_NOT_ENABLED SCOPE_MISSING TIER_NOT_PERMITTED INVALID_BODY INVALID_REGISTRATION_NUMBER INVALID_VEHICLE_TYPE INVALID_IDEMPOTENCY_KEY IDEMPOTENCY_KEY_REUSED IDEMPOTENCY_IN_PROGRESS NO_CUSTOMER_NUMBER RATE_LIMITED RATE_LIMIT_UNCONFIGURED RESULT_EXPIRED INVALID_MONTH LOOKUP_FAILED LOOKUP_THROTTLED PAYMENT_REQUIRED INTERNAL FORBIDDEN

detailstring
vehicleTypestringOn INVALID_REGISTRATION_NUMBER for a shape the vehicle type does not have: the type sent.
expectedShapesarray of stringOn INVALID_REGISTRATION_NUMBER for a shape the vehicle type does not have: the shapes it has, L a letter and N a digit. CD- and C- plates are accepted for every type.
retryAfterSecondsintegerOn RATE_LIMITED and LOOKUP_THROTTLED: the same value as the Retry-After header.