---
title: "Multi-year series for one postal code area"
method: GET
path: "/api/v1/postal-codes/{postalCode}/history"
tags: ["Areas"]
---

# Multi-year series for one postal code area

`GET /api/v1/postal-codes/{postalCode}/history`

## Request

- Base URL: `https://suomiatlas.com`
- URL: `https://suomiatlas.com/api/v1/postal-codes/{postalCode}/history`
- Auth: one of:
  - none
  - HTTP bearer

Time series for every metric of one area. `years` is the shared x-axis and every series is index-aligned to it, with nulls where a figure is missing.

**Two independent free-tier limits apply here; whatever they withhold is named in `locked`, and a response without `locked` withheld nothing.**

1. Without Pro, `years` is cut to the **latest 3 years** and every series shortens with it; `locked` carries `years` (`requires: pro`) with the withheld span in its `reason`. A 3-year window is not a trend — do not describe it as one. Pro returns the full record from 2010.
2. Without Pro or an Area Pass covering this exact area, every dwelling-price metric (`housing_price_m2_*`, `housing_txn_count_*`) has **both** its `values` and its `nationalMedians` replaced by nulls, for all years. The keys stay present; only the `locked` entry `series.housing_*` (`requires: area-pass`) tells this apart from an area with no sales, and it is emitted only when there were sales to withhold. The same callers also get `derivedHistory` in `locked`: `/derived-history` would answer them 402, so do not probe it. Note the asymmetry — the year window needs Pro, while the dwelling-price series and derived history also accept an Area Pass for this area. Pro or the matching Area Pass returns the full series from 2009.

Note the asymmetry: the year window needs Pro, while the dwelling-price series also accepts an Area Pass for this one area.

Example request: https://suomiatlas.com/api/v1/postal-codes/00120/history

## Path parameters

- `postalCode` string, required

## Response `200`

Series, subject to the two limits above.

- PostalCodeHistory
  - `postalCode` string, required
  - `years` integer[], required: The shared x-axis, ascending. **Only the latest 3 entries without Pro**; when the window was cut, `locked` names `years` and its `reason` gives the withheld span.
  - `series` object, required
  - `variableNames` StringMap, required
  - `locked` LockedField[]: Absent — the key is missing, not an empty array — when nothing was withheld for this caller. May name: `years` (`pro`), `series.housing_*` (`area-pass`), `derivedHistory` (`area-pass`, a pointer to `/derived-history`).
    - `field` string, required: Path into this response, e.g. `entries`, `years`, `series.housing_*`, `pollutants[].data.series`, `composites[].components[].percentile`.
    - `requires` 'pro' | 'area-pass', required: `pro`: only a Pro subscription lifts it. `area-pass`: Pro, or an Area Pass for this exact postal code.
    - `reason` string, required: One sentence naming what is withheld. Always ends "The data exists — it is withheld, not missing."
    - `upgrade` string, uri, required

## Other responses

- `404`: No such place, or no data for it. Also what a non-numeric `year` produces, because query-parameter conversion fails before the operation runs.

---

[API](https://skmtc.dev/suomiatlas/apis/suomiatlas-read-api.md) · [All operations](https://skmtc.dev/suomiatlas/apis/suomiatlas-read-api/llms.txt) · [OpenAPI document](https://skmtc.dev/suomiatlas/apis/suomiatlas-read-api/revisions/b2627414938d?raw)
