# Design System Showcase

A single page rendering every prose, code, admonition, and custom component used throughout the docs. Use this to verify visual consistency, spacing, and dark-mode parity after any design change.

## Headings

The doc title above is the page `h1`. Below are the subsequent heading levels — `h2` shows a bottom-border accent, lower levels stack tighter.

### Third-level heading

#### Fourth-level heading

##### Fifth-level heading

## Paragraphs and inline elements

This is a regular paragraph with **bold text**, *italic text*, ***bold-italic***, and a [hyperlink](https://ideal-postcodes.co.uk). Inline code looks like `AddressFinder.watch()` — a light-blue tint with brand-blue text and a subtle border. A second sentence shows how line-height and colour sit at body weight.

Another paragraph to verify vertical rhythm between blocks. A footnote-style superscript citation isn't a first-class element here, but ~~strikethrough~~ and `⌘K`-style key hints render via raw HTML.

## Lists

### Unordered

* Top-level item one

* Top-level item two with a longer description that wraps onto a second line so we can confirm leading and indentation behave as expected

  * Nested item A
  * Nested item B with **bold** and `inline code`

* Top-level item three

### Ordered

1. First step — pick a starting point

2. Second step — refine inputs

3. Third step — verify output

   1. Sub-step alpha
   2. Sub-step beta

## Blockquote

> Verifying address data at the point of entry eliminates 90% of downstream support tickets and chargeback disputes. The cost of bad data compounds — fix it early.

## Tables

| Field       | Type     | Description                                                              |
| ----------- | -------- | ------------------------------------------------------------------------ |
| `line_1`    | `string` | First line of the address, typically the building number and street name |
| `post_town` | `string` | Postal town as defined by Royal Mail                                     |
| `postcode`  | `string` | UK postcode in standard format                                           |
| `country`   | `string` | ISO 3166-1 alpha-2 country code                                          |

## Horizontal rule

Above and below a horizontal rule there's clear separation.

***

Below the rule, content continues naturally.

## Code blocks

A bash block with a filename title:

terminal

```bash
npm install @ideal-postcodes/address-finder
```

A command continued over several lines. The prompt sits on the first line only:

terminal

```bash
curl -G https://api.ideal-postcodes.co.uk/v1/autocomplete/addresses \
  --data-urlencode "api_key=ak_xxxx" \
  --data-urlencode "query=10 downing street"
```

A JavaScript block, multi-line with syntax highlighting:

app.js

```js
import { AddressFinder } from "@ideal-postcodes/address-finder";

AddressFinder.watch({
  apiKey: "ak_xxxx",
  inputField: "#address-search",
  onAddressRetrieved: (address) => {
    document.querySelector("#line_1").value = address.line_1;
    document.querySelector("#post_town").value = address.post_town;
    document.querySelector("#postcode").value = address.postcode;
  },
});
```

A JSON response example:

response.json

```json
{
  "result": {
    "line_1": "1 Malyons Road",
    "post_town": "Hextable",
    "postcode": "BR8 7RE",
    "country": "England"
  },
  "code": 2000
}
```

## Admonitions

note

**Before you start:** You'll need an API key. Create a free account to get one — 100 lookups included, no credit card required.

tip

**Live tip:** Paste a UK postcode or street name into Address Finder to see real-time autocomplete.

info

This is an informational note with a [link inside it](https://ideal-postcodes.co.uk) to verify link contrast.

warning

Never expose your API key in public-facing code without configuring Allowed URLs in your dashboard. This restricts which domains can use your key.

danger

Hard-deleting an API key invalidates all live integrations using it. Rotate keys first, then delete the old one once traffic has migrated.

## Tabs

**JavaScript**

app.js

```js
import { AddressFinder } from "@ideal-postcodes/address-finder";

AddressFinder.watch({ apiKey: "ak_xxxx", inputField: "#search" });
```

**TypeScript**

app.ts

```ts
import { AddressFinder, type Address } from "@ideal-postcodes/address-finder";

AddressFinder.watch({
  apiKey: "ak_xxxx",
  inputField: "#search",
  onAddressRetrieved: (address: Address) => console.log(address),
});
```

**cURL**

terminal

```bash
curl -X GET "https://api.ideal-postcodes.co.uk/v1/postcodes/SW1A1AA?api_key=ak_xxxx"
```

## OpenAPI Property

The `<Property>` component renders a single OpenAPI schema field — used throughout the data-source docs to document address payload fields. It accepts a `property` name and a `schema` object and renders a card with name, type, description, and a metadata grid (format / default / example / enum values).

### Simple — schema from the spec

Driven directly from `spec.components.schemas`:

`postcode`string

Correctly formatted postcode. Capitalised and spaced. Empty (`""`) where the address has no postcode.

### Inline schema with enum (chip list)

Authors can pass an inline schema instead of pulling from the spec. Enum values render as a chip list:

`country_iso`string

Three-character country code based on ISO Standard 3166.

Example: `GBR`

Values: "GBR", "IRL", "FRA", "DEU", "USA"

### Inline schema with format + default

`created_at`string

Timestamp of address record creation, ISO-8601 with timezone.

Format: `date-time`

Default: `now()`

Example: `2025-04-18T09:21:00Z`

### Missing schema (fallback)

When a referenced schema cannot be resolved, the component falls back to a `Schema not found` state:

`does_not_exist`

Schema not found.

### Complex — `oneOf` rendered as separate cards

The complex variant from `@site/src/components/openapi-complex` expands each branch of an `oneOf` / `anyOf` / `allOf` composition into a fully rendered block, instead of summarising as a variant list. Useful when each branch deserves equal weight:

`longitude`string

Empty string `""` if not available

`longitude`number

Represents longitude

## Response schema

Two ways to render a response body from the OpenAPI spec. **Inline** expands a small body in full; **linked** renders the top level and links out to named schemas instead of inlining them.

### Inline — small body expanded

* `result` Config

  | Field       | Type   | Description                                                                                  |
  | ----------- | ------ | -------------------------------------------------------------------------------------------- |
  | `updatedAt` | string | Timestamp for when the config was created. Example: `2016-01-21T17:14:49.971Z`               |
  | `createdAt` | string | Timestamp for when the config was updated. Example: `2016-01-21T17:14:49.971Z`               |
  | `name`      | string | A unique name to identify the configuration payload. Example: `woocommerce`                  |
  | `payload`   | string | A serialised payload of up to `65536` characters. Example: `{ "removeOrganisation": false }` |

### Linked — large body links to schema pages

The postcode result is an array whose items are a `oneOf` of seven address types. Linked mode collapses each to a typed link rather than inlining \~40 fields per variant:

* `result` AddressListItem\[] Address (list endpoints)

  All addresses listed at the postcode.

  If Eircode is enabled, addresses for the Republic of Ireland will be returned in the English format.

  * `id` string

    Global unique internally generated identifier for an address

  * `dataset` string

    Indicates the provenance of an address.

    Values: "paf", "pafw", "pafa", "mr", "nyb", "usps", "ecaf", "ecad", "ab", "abp", "herewe", "heret", "heresa", "hereo", "herena", "heremeas", "heremea", "herem", "herei", "herehk", "hereee", "hereap", "gnaf", "kadaster", "kartverket", "sdfi", "cannar", "fodbosa", "mois", "upujp", "bev", "ban", "swt"

  * `country_iso` string

    3 letter country code (ISO 3166-1)

    Values: 243 possible values

  * `country_iso_2` string

    2 letter country code (ISO 3166-1)

    Values: 243 possible values

  * `country` string

    Full country names (ISO 3166)

    Values: 248 possible values

  * `language` string

    Language represented by 2 letter ISO Code (639-1)

    Values: 64 possible values

  * `line_1` string

    First address line. Often contains premise and thoroughfare information. For a commercial premise the first line is the full name of the registered organisation. Never empty.

  * `line_2` string

    Second address line. Often contains thoroughfare and locality information. May be empty.

  * `line_3` string

    Third address line. Takes the address elements left after `line_1` and `line_2` are filled; where the address needs more than three lines the remaining elements are joined into `line_3`, comma separated. May be empty.

  * `post_town` string

    The town or city used to route mail to the address. For UK addresses this is the Royal Mail post town, which is a routing instruction rather than the nearest town geographically. Present on every address.

  * `postcode` string

    Correctly formatted postcode. Capitalised and spaced. Empty (`""`) where the address has no postcode.

  * `county` string

    Whatever county data is available for the address. Normally the postal county. If that is not present it falls back to the administrative county, then to the traditional county. May be empty where none of the three is present.

  * `county_code` string

    Short code representing the county or province. May be empty (`""`)

  * `uprn` string

    UPRN stands for Unique Property Reference Number and is maintained by the Ordnance Survey (OS). Local governments in the UK have allocated a unique number for each land or property.

    Up to 12 digits in length.

    Multiple Residence premises currently share the same UPRN as the parent premise.

    May not be available for a small number of Great Britain addresses due to longer update cycles for Ordnance Survey's AddressBase datasets. Returns empty string "" in these instances, as it does for addresses outside the UK.

    Although UPRN takes an integer format, we encode and transmit this data as strings. As a 12 digit number, the UPRN can exceed the maximum safe integer `Number.MAX_SAFE_INTEGER` in most browsers causing this datapoint to be corrupted.

    Take special care when storing UPRN. As a 12 digit identifier, you will need 64 bits to encode every possible UPRN value. This means applications like Excel will corrupt cells containing UPRN values.

  * `udprn` one of

    UDPRN stands for 'Unique Delivery Point Reference Number'. Royal Mail assigns a unique UDPRN code for each premise on PAF. Simple, unique reference number for each Delivery Point. Unlikely to be reused when an address expires.

    Up to 8-digit numeric code. A new UDPRN is automatically assigned to each new Delivery Point added to PAF.

    Returns `0` on a UK dataset that carries no UDPRN for the address, and an empty string `""` on a non-UK address. Use `id` for an identifier present on every address.

    * integer
    * string

  * `umprn` one of

    A small minority of individual premises (as identified by a UDPRN) may have multiple occupants behind the same letterbox. These are known as Multiple Residence occupants and can be queried via the Multiple Residence dataset. Simple, unique reference number for each Multiple Residence occupant.

    Note: this will be an empty string `""` when not used.

    * string
    * number

  * `postcode_outward` string

    The first part of a postcode is known as the outward code. e.g. The outward code of ID1 1QD is ID1. Enables mail to be sorted to the correct local area for delivery. This part of the code contains the area and the district to which the mail is to be delivered, e.g. 'PO1', 'SW1A' or 'B23'.

    Empty (`""`) where the address has no UK postcode.

  * `postcode_inward` string

    The second part of a postcode is known as the inward code. e.g. The inward code of ID1 1QD is 1QD.

    The number identifies the sector in the postal district. The number is followed by 2 letters. The letters then define one or more properties in that sector.

    Empty (`""`) where the address has no UK postcode.

  * `dependant_locality` string

    A locality that qualifies the thoroughfare. Used where the same thoroughfare name occurs more than once in a post town and no dependant thoroughfare distinguishes them. May be empty.

  * `double_dependant_locality` string

    Supplements dependant locality. Supplied where the dependant locality itself occurs twice in the same locality. May be empty.

  * `thoroughfare` string

    Also known as the street or road name. May be empty.

  * `dependant_thoroughfare` string

    Supplements thoroughfare. Used where a thoroughfare name occurs twice in the same post town, to identify the address uniquely. May be empty.

  * `building_number` string

    Number identifying the premise on a thoroughfare or dependant thoroughfare. May be empty.

  * `building_name` string

    Name of a residential or commercial premise. May be empty.

    Examples:

    * The Manor
    * 1-2
    * A
    * 12A
    * K
    * Victoria House

  * `sub_building_name` string

    Identifies a unit where a premise is split into flats, apartments or business units. Cannot be present without either building\_name or building\_number. E.g. Flat 1, A, 10B. May be empty.

  * `po_box` string

    PO Box number for the address, occasionally a combination of numbers and letters. Allocated to Large User postcodes only. May be empty.

  * `department_name` string

    Supplements organisation name to identify a department within the organisation. May be empty.

  * `organisation_name` string

    Name of the business or organisation at this address. May be empty.

  * `postcode_type` string

    Royal Mail postcode user type. UK addresses only.

    * `S` small user. The postcode identifies a group of delivery points. There are on average 19 delivery points per postcode, and never more than 100
    * `L` large user. The postcode is assigned to a single address, either because of the volume of mail it receives or because a PO Box or Selectapost service is set up

    Empty (`""`) where not applicable.

    Values: "S", "L", ""

  * `su_organisation_indicator` string

    `Y` where an organisation is present at a small user postcode. Empty (`""`) otherwise. UK addresses only.

  * `delivery_point_suffix` string

    Two-character code (the first numeric, the second alphabetical) which, added to the postcode, uniquely identifies a delivery point. May be reused once a delivery point is deleted, though not until every remaining code in the range has been allocated. Always `1A` for a large user postcode, since each large user has its own postcode. Empty (`""`) where not available.

  * `premise` string

    A pre-computed string which sensibly combines building\_number, building\_name and sub\_building\_name. Those three fields hold raw dataset values and can be difficult to parse if you are unaware of how they work together, so we also provide this single, simple premise string. Ideal if you want to pull premise information and thoroughfare information separately instead of using our address lines data.

  * `administrative_county` string

    The current administrative county to which the postcode has been assigned.

    A Unitary Authority name, where one is present. If there is no Unitary Authority, the County name is used. This information is not static, because County boundaries may change due to administrative changes.

    Source: ONS. May be empty.

  * `postal_county` string

    Postal counties were used for the distribution of mail before the Postcode system was introduced in the 1970s. The Former Postal County was the Administrative County at the time. This data rarely changes. May be empty.

  * `traditional_county` string

    Traditional counties are provided by the Association of British Counties. It is historical data, and can date from the 1800s. May be empty.

  * `district` string

    The current district/unitary authority to which the postcode has been assigned. May be empty.

  * `ward` string

    The current administrative/electoral area to which the postcode has been assigned. May be empty for a small number of addresses.

  * `longitude` Longitude

    The longitude of the address or postcode (WGS84).

    Can be a positive or negative decimal. E.g. -0.1283983

    Returns an empty string if no location data is available.

    * string
    * number

  * `latitude` Latitude

    The latitude of the address or postcode (WGS84).

    Can be a positive or negative decimal. E.g. `51.5083983`.

    Returns an empty string if no location data is available.

    * string
    * number

  * `eastings` Eastings

    Eastings reference using the [Ordnance Survey National Grid reference system](https://en.wikipedia.org/wiki/Ordnance_Survey_National_Grid).

    Northern Ireland Eastings uses the [Irish Grid Reference System](https://en.wikipedia.org/wiki/Irish_grid_reference_system).

    Metres from origin. E.g. `550458`

    Returns an empty string if no location data is available. Otherwise a number is returned.

    * string
    * number

  * `northings` Northings

    Northings reference using the [Ordnance Survey National Grid reference system](https://en.wikipedia.org/wiki/Ordnance_Survey_National_Grid)

    Northern Ireland Northings uses the [Irish Grid Reference System](https://en.wikipedia.org/wiki/Irish_grid_reference_system)

    Metres from origin. E.g. `180458`

    Returns an empty string if no location data is available. Otherwise a number is returned

    * string
    * number

  * `native` one of optional

    The raw dataset record backing this address. On these two endpoints it is returned for AddressBase (`ab`, `abp`) and non-UK datasets only, never for the PAF family. Use any other endpoint for a PAF native record.

    * AddressBase Core Address
    * AddressBase Premium Address
    * USPS Address
    * Ireland ECAD Address [Full guide](/docs/data/ecad.md)
    * Ireland ECAF Address [Full guide](/docs/data/ecaf.md)
    * HERE Address [Full guide](/docs/data/here.md)
    * Australia G-NAF Address [Full guide](/docs/data/gnaf.md)
    * Netherlands Kadaster Address [Full guide](/docs/data/kadaster.md)
    * Norway Kartverket Address [Full guide](/docs/data/kartverket.md)
    * Denmark SDFI Address [Full guide](/docs/data/sdfi.md)
    * Canada NAR Address [Full guide](/docs/data/cannar.md)
    * Belgium FOD BOSA Address [Full guide](/docs/data/fodbosa.md)
    * South Korea MOIS Address [Full guide](/docs/data/mois.md)
    * Japan UPU Address [Full guide](/docs/data/upujp.md)
    * Austria BEV Address [Full guide](/docs/data/bev.md)
    * France BAN Address [Full guide](/docs/data/ban.md)
    * Switzerland and Liechtenstein Address [Full guide](/docs/data/swt.md)

## API reference components

Each `/docs/api/*` page is hand-authored MDX that renders one OpenAPI operation from `@ideal-postcodes/openapi` via the spec-driven components in `src/components/openapi.tsx` (`Parameters`, `ResponseLinked`, `RequestSamples`, `ResponseSample`, `Property` — the shared `@atlas/docs` renderers bound to this app's spec). They render inline anywhere, so the `<Property>` card above is the same primitive the endpoint pages use.

To eyeball a full page, open a real endpoint — e.g. [Lookup Postcode (`GET /postcodes/{postcode}`)](/docs/api/postcodes.md). Things to watch for after any `src/css/custom.css` change:

* **Method/path bar** (`.apidoc__header`, `.apidoc__method`, `.apidoc__method--get`/`--post`/...) — the coloured verb pill and monospace path.
* **Parameter table** (`.atlas-params`) — the compact `Parameter / Type / Description` table with example/default/enum inline; styles live in `packages/docs/src/openapi/styles.css`.
* **Response schema rows** — rendered by `<ResponseLinked>` / `<Property>`; the shared card styles live in `packages/docs/src/openapi/styles.css`, remapped onto `--idpc-*` tokens one class deeper in `custom.css`. The schema fold chevron (`.atlas-schema__details`) is excluded from the generic `<details>` styling in `custom.css`.
* **Sidebar method pills** (`.api-method.get`/`.post`/... `> .menu__link::before`) — the small verb badge on API sidebar items; colours mirror `.apidoc__method--*`.

When something looks off, the fix belongs in `src/css/custom.css` (page-level classes) or the token remap for shared-component classes — never in the page MDX, which only composes components.

## Details / collapsible

UPRN (Unique Property Reference Number) is included on every retrieved address. Access it via `address.uprn` in the `onAddressRetrieved` callback. See the [UPRN guide](https://ideal-postcodes.co.uk/documentation/uprn) for usage.

The Address Finder supports over 240 countries via global geocoding. UK addresses use Royal Mail PAF data; international addresses use HERE.

## Buttons

Custom buttons exist for in-page CTAs. They live outside the markdown defaults.

[Primary button](#headings)[Secondary button](#headings)

## API hub cards

The grid pattern used on API landing pages:

### [Address Finder](#headings)

[Real-time autocomplete suggestions ranked by relevance.](#headings)

* [](#headings)
  [](#headings)[Get started](#headings)
* [Configuration](#headings)

### [Postcode Lookup](#headings)

[All UK addresses for any postcode, instantly.](#headings)

* [](#headings)
  [](#headings)[Get started](#headings)
* [Field binding](#headings)

### [Address Cleanse](#headings)

[Standardise and complete any address input.](#headings)

* [](#headings)
  [](#headings)[Get started](#headings)
* [Bulk processing](#headings)

## Logo container

The integration-logo pattern with a featured badge:

New![Shopify Plus](/img/shopify-plus-logo.svg)![Shopify Plus](/img/shopify-plus-logo-dark.svg)

![WooCommerce](/img/woocommerce-logo.svg)

![HubSpot](/img/hubspot-logo.svg)

![Magento](/img/magento.svg)

## Long-form prose

A final stretch of regular prose to verify hanging punctuation, descender clearance, and inter-paragraph spacing over a longer read.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris a lorem at velit hendrerit pellentesque. Donec id mauris vel arcu vestibulum aliquet. Sed quis nibh sit amet purus laoreet egestas. Integer eget velit sed leo placerat venenatis.

Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Quisque vitae dolor sed dolor lacinia placerat. Suspendisse potenti.

Curabitur tincidunt lorem sit amet metus ultrices, nec faucibus turpis pharetra. Cras vestibulum mauris ac tortor cursus, vel volutpat sapien laoreet. Phasellus eget dapibus felis.
