{
  "openapi": "3.1.0",
  "info": {
    "title": "Autorekisteri machine API",
    "version": "1.0.0",
    "description": "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"
  },
  "servers": [
    {
      "url": "https://api.business.autorekisteri.fi",
      "description": "Production"
    },
    {
      "url": "https://api.business-test.autorekisteri.fi",
      "description": "Test: Traficom test system, test plates only"
    }
  ],
  "security": [
    {
      "oauth2": []
    }
  ],
  "paths": {
    "/v1/lookups": {
      "post": {
        "operationId": "createLookup",
        "summary": "Look up a vehicle",
        "description": "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.",
        "security": [
          {
            "oauth2": [
              "{resourceServer}/lookup.perus",
              "{resourceServer}/lookup.laaja",
              "{resourceServer}/lookup.historia"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LookupRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The query completed. `idempotent-replayed: true` marks an answer from an earlier request with the same key.",
            "headers": {
              "idempotent-replayed": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Lookup"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Problem"
          },
          "401": {
            "$ref": "#/components/responses/Problem"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Problem"
          },
          "409": {
            "$ref": "#/components/responses/Problem"
          },
          "410": {
            "$ref": "#/components/responses/Problem"
          },
          "422": {
            "$ref": "#/components/responses/Problem"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "502": {
            "$ref": "#/components/responses/Problem"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/v1/lookups/{lookupId}": {
      "get": {
        "operationId": "getLookup",
        "summary": "Read back one of your own lookups",
        "description": "The report is kept for 24 hours (a contractual maximum), then `410 RESULT_EXPIRED`.",
        "security": [
          {
            "oauth2": [
              "{resourceServer}/lookup.perus",
              "{resourceServer}/lookup.laaja",
              "{resourceServer}/lookup.historia"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LookupId"
          }
        ],
        "responses": {
          "200": {
            "description": "The lookup",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Lookup"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Problem"
          },
          "403": {
            "$ref": "#/components/responses/Problem"
          },
          "404": {
            "$ref": "#/components/responses/Problem"
          },
          "410": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/v1/lookups/{lookupId}/report.pdf": {
      "get": {
        "operationId": "getLookupPdf",
        "summary": "The report as a PDF",
        "description": "Send `Accept: application/pdf`. Available for 24 hours, like the report.",
        "security": [
          {
            "oauth2": [
              "{resourceServer}/lookup.perus",
              "{resourceServer}/lookup.laaja",
              "{resourceServer}/lookup.historia"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/LookupId"
          }
        ],
        "responses": {
          "200": {
            "description": "The PDF",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Problem"
          },
          "403": {
            "$ref": "#/components/responses/Problem"
          },
          "404": {
            "$ref": "#/components/responses/Problem"
          },
          "410": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    },
    "/v1/usage": {
      "get": {
        "operationId": "getUsage",
        "summary": "Your client's lookups and counts for a month",
        "security": [
          {
            "oauth2": [
              "{resourceServer}/usage.read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "month",
            "in": "query",
            "required": false,
            "description": "`YYYY-MM`, UTC. Defaults to the current month.",
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-(0[1-9]|1[0-2])$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Usage",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Usage"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Problem"
          },
          "401": {
            "$ref": "#/components/responses/Problem"
          },
          "403": {
            "$ref": "#/components/responses/Problem"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "oauth2": {
        "type": "oauth2",
        "description": "`{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.",
        "flows": {
          "clientCredentials": {
            "tokenUrl": "https://arek-prod-client.auth.eu-west-1.amazoncognito.com/oauth2/token",
            "scopes": {
              "{resourceServer}/lookup.perus": "Look up with tier perus; read back own lookups",
              "{resourceServer}/lookup.laaja": "Look up with tier laaja; read back own lookups",
              "{resourceServer}/lookup.historia": "Look up with tier historia; read back own lookups",
              "{resourceServer}/usage.read": "Read own monthly usage"
            }
          }
        }
      }
    },
    "parameters": {
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": false,
        "description": "Your 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`.",
        "schema": {
          "type": "string",
          "pattern": "^[A-Za-z0-9._:-]{1,128}$"
        }
      },
      "LookupId": {
        "name": "lookupId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        }
      }
    },
    "responses": {
      "Problem": {
        "description": "RFC 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`.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          },
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "PaymentRequired": {
        "description": "`PAYMENT_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).",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "RateLimited": {
        "description": "A per-client, per-organisation or service-wide limit. Wait `Retry-After` seconds.",
        "headers": {
          "Retry-After": {
            "schema": {
              "type": "integer"
            }
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "Unavailable": {
        "description": "`LOOKUP_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.",
        "headers": {
          "Retry-After": {
            "schema": {
              "type": "integer"
            },
            "description": "Present on LOOKUP_THROTTLED."
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      }
    },
    "schemas": {
      "LookupRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "registrationNumber",
          "vehicleType",
          "tier"
        ],
        "properties": {
          "registrationNumber": {
            "type": "string",
            "examples": [
              "ABC-123"
            ],
            "description": "Finnish 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."
          },
          "vehicleType": {
            "type": "string",
            "enum": [
              "auto",
              "moottoripyora",
              "moottorityokone",
              "maastoajoneuvo",
              "perakarry",
              "mopo"
            ]
          },
          "tier": {
            "type": "string",
            "enum": [
              "perus",
              "laaja",
              "historia"
            ]
          }
        }
      },
      "Lookup": {
        "type": "object",
        "required": [
          "lookupId",
          "registrationNumber",
          "vehicleType",
          "tier",
          "createdAt",
          "outcome",
          "traficomErrorCode",
          "resultExpiresAt",
          "report"
        ],
        "properties": {
          "lookupId": {
            "type": "string"
          },
          "registrationNumber": {
            "type": "string"
          },
          "vehicleType": {
            "type": "string",
            "enum": [
              "auto",
              "moottoripyora",
              "moottorityokone",
              "maastoajoneuvo",
              "perakarry",
              "mopo"
            ]
          },
          "tier": {
            "type": "string",
            "enum": [
              "perus",
              "laaja",
              "historia"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "outcome": {
            "type": "string",
            "enum": [
              "ok",
              "empty",
              "atjError"
            ],
            "description": "`ok`: report included. `empty`: Traficom did not answer (no report). `atjError`: Traficom answered with `traficomErrorCode`, most often an unknown vehicle."
          },
          "traficomErrorCode": {
            "type": [
              "string",
              "null"
            ]
          },
          "resultExpiresAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "report": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Report"
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "Report": {
        "type": "object",
        "description": "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.",
        "required": [
          "sections",
          "owners",
          "notices",
          "unknownCodes"
        ],
        "properties": {
          "sections": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReportSection"
            }
          },
          "owners": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Owner"
            }
          },
          "notices": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "vehicleStatus": {
            "type": "array",
            "description": "`Ajoneuvon 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.",
            "items": {
              "type": "object",
              "required": [
                "label",
                "value"
              ],
              "properties": {
                "label": {
                  "type": "string"
                },
                "value": {
                  "type": "string"
                }
              }
            }
          },
          "transferNotices": {
            "type": "array",
            "description": "The `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.",
            "items": {
              "type": "object",
              "required": [
                "date",
                "kind"
              ],
              "properties": {
                "date": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "`dd.mm.yyyy`, or null when the register gave none."
                },
                "kind": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              }
            }
          },
          "unknownCodes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "codeSet": {
                  "type": "string"
                },
                "code": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "ReportSection": {
        "type": "object",
        "required": [
          "key",
          "title",
          "fields"
        ],
        "properties": {
          "key": {
            "type": "string",
            "enum": [
              "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": {
            "type": "string"
          },
          "fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReportField"
            }
          },
          "emptyState": {
            "type": "string",
            "description": "Present 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": {
        "type": "object",
        "required": [
          "key",
          "label",
          "value"
        ],
        "properties": {
          "key": {
            "description": "A fixed field key, or a repeated entry `<base>.<n>` (1-based).",
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "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"
                ]
              },
              {
                "type": "string",
                "pattern": "^(muutoskatsastus|paasto|kulutus|akseli|rengas|akselivali|turvavaruste|katsastus|tunnus|vakuutus|matkamittarilukema|kaytto|poisto|akselinJarrut)\\.[1-9][0-9]*$"
              }
            ]
          },
          "label": {
            "type": "string"
          },
          "value": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Owner": {
        "type": "object",
        "required": [
          "title",
          "name",
          "address",
          "deathEstate"
        ],
        "properties": {
          "group": {
            "type": "string",
            "enum": [
              "owner",
              "holder",
              "previous"
            ],
            "description": "A current owner, a current holder, or an ended relationship (historia and kaikki only). Absent on a lookup stored before 2026-10-19."
          },
          "title": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "address": {
            "type": [
              "string",
              "null"
            ]
          },
          "deathEstate": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Usage": {
        "type": "object",
        "properties": {
          "month": {
            "type": "string"
          },
          "total": {
            "type": "integer"
          },
          "totalsByTier": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            }
          },
          "byDayAndTier": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "day": {
                  "type": "string"
                },
                "tier": {
                  "type": "string"
                },
                "count": {
                  "type": "integer"
                }
              }
            }
          },
          "lookups": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "lookupId": {
                  "type": "string"
                },
                "registrationNumber": {
                  "type": "string"
                },
                "vehicleType": {
                  "type": "string"
                },
                "tier": {
                  "type": "string"
                },
                "createdAt": {
                  "type": "string",
                  "format": "date-time"
                },
                "outcome": {
                  "type": "string",
                  "enum": [
                    "pending",
                    "ok",
                    "empty",
                    "atjError",
                    "failed"
                  ]
                }
              }
            }
          }
        }
      },
      "Problem": {
        "type": "object",
        "required": [
          "type",
          "title",
          "status",
          "code"
        ],
        "properties": {
          "type": {
            "type": "string",
            "description": "`about:blank`, except PAYMENT_REQUIRED, whose type is this API's `/docs#payment-required`.",
            "examples": [
              "about:blank",
              "https://api.business.autorekisteri.fi/docs#payment-required"
            ]
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "code": {
            "type": "string",
            "enum": [
              "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"
            ]
          },
          "detail": {
            "type": "string"
          },
          "vehicleType": {
            "type": "string",
            "description": "On INVALID_REGISTRATION_NUMBER for a shape the vehicle type does not have: the type sent."
          },
          "expectedShapes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "On 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."
          },
          "retryAfterSeconds": {
            "type": "integer",
            "description": "On RATE_LIMITED and LOOKUP_THROTTLED: the same value as the Retry-After header."
          }
        },
        "additionalProperties": true
      }
    }
  }
}
