---
title: "Discover the collecting council and required address input for a UK postcode"
method: GET
path: "/addresses"
---

# Discover the collecting council and required address input for a UK postcode

`GET /addresses`

## Request

- Base URL: `https://whenisbins.com/v1`
- URL: `https://whenisbins.com/v1/addresses`
- Auth: one of:
  - none
  - HTTP bearer

Start here when the user wants their household bin collection dates.
Follow required_input and input_options; ask the user to resolve missing
information or ambiguous choices before submitting a lookup. Discovery
does not select a property on the user's behalf.
Postcode-only by design: a bare postcode is street-level public
data, which keeps this endpoint CDN-cacheable. Returns the
collecting council and the property list as the council's own
checker words it, when we hold it.

## Query parameters

- `postcode` string, required
- `q` string

## Headers

- `If-None-Match` string

## Response `200`

Council resolved; currently serviceable candidate list.

- CandidateList
  - `postcode` string, required: Normalised form.
  - `council` CouncilWithWait, required
    - `id` string, required: GSS code — the canonical, rename-proof council identity.
    - `name` string, required
    - `lookup_url` string, uri: The council's own bin-day checker page, when known (https only). The honest fallback for the citizen on every wait and failure — the same page a served Schedule reports as `source_url`.
    - `missed_bin_url` string, uri, nullable: Council-specific HTTPS operational missed-collection reporting page, from the approved verified reporting registry. Null when unavailable; never substituted with the checker, broader problem or formal complaint route. Returned on council discovery, lookup and schedule council objects. Read the council's current reporting window, disruptions, exclusions and evidence requirements. Too early? Keep the details and, with permission, follow up when the window opens and before it closes. If you cannot, give the owner the council link and saved details. Check-in consent is not permission to submit. Get separate permission to report and share personal details with the council. Check for an existing report in the council account or by reference if you have access; otherwise ask the owner. After a timeout or no confirmation, reconcile before retrying. Deduplicate by property + due date + waste stream (bin type). Only claim success when the council confirms it; keep its reference and next steps. Do not promise a return collection: some streams have none. WhenIsBins supplies dates and a link; it does not schedule check-ins or submit reports. See the guide for the full check-in and reporting rules.
    - `missed_bin_checked_at` string, date, nullable: Registry verification date (YYYY-MM-DD) for the published reporting route, not the schedule retrieval time or a live availability check. Null when missed_bin_url is null. Approved links remain published until reviewed and withdrawn or updated, even when their review date has passed.
    - `expected_wait_seconds` integer, nullable, required: Route-aware recent cold-visit p90, rounded up to seconds. When at least half of observations succeed through a fast deterministic route, this is that route's p90; after a fast miss it is promoted to at least 120 for the browser handoff. Poor success below 0.7 also selects the handoff. Null until five timed cold observations exist in the rolling 84-day window. While the route maintainer's control plane holds the council's active deterministic route healthy, the deterministic-stage estimate is instead the p90 of recent cold successes on the fast routes alone (null below five such successes), whatever the blended history or success rate says. A lookup parked for the residential worker after a council bot-blocked the web host is estimated from that worker's own deterministic stage timing (pickup plus execution, p90) from its first recent sample; with none it shows the handoff.
    - `success_rate` number, double, nullable, required: Share of recent cold observations whose outcome is `success`. Null until five cold observations exist in the rolling 84-day window. Cache hits are never included.
  - `required_input` 'none' | 'property_id' | 'property' | 'street' | 'road_and_locality' | 'street_and_property' | 'settlement' | 'settlement_or_road' | 'normal_weekday' | 'normal_weekday_and_locality' | 'property_type', required: The next field this council's checker needs after the postcode. `none` means exactly that: this council's own checker resolves the collection from the postcode alone - it names the settlement or round itself - so nothing further should be asked, and POST /lookups accepts the postcode by itself. A `property` may still be sent and is still matched strictly; it is simply not required. Read this value for each lookup rather than keeping a council's former input contract: South Lanarkshire now requires a property (or a listed property_id), following its property-checker redesign.
  - `postcode_representative` 'automatic' | 'opt_in' | 'unavailable': Whether a labelled same-postcode neighbour's schedule may answer when the exact property is not listed. `opt_in` = only after the citizen explicitly consents, by sending `allow_postcode_representative`; `automatic` = this council is measured homogeneous, so the labelled answer is served without asking; `unavailable` = measured high-harm, and every tier refuses the neighbour answer. Present only at property granularity, where the neighbour concept applies.
  - `candidates_source` 'council' | 'unavailable', required: `council` = the list came from the council's own checker. `unavailable` = no list is currently held; POST free-text `property` instead. Commercial address data is never republished through this field.
  - `candidates` Candidate[], required: The council's own list. Normally at most 14 days old; when nothing fresher can be had (no live fetch, or it produced no list) a copy up to 45 days old is returned rather than nothing.
    - `id` string, required: Opaque service token — echo back as `property_id`; never parse it or assume it is a council UPRN.
    - `label` string, required: The property exactly as the council's checker words it.
  - `unavailable_candidates` UnavailableCandidate[]: Present only when the list holds any. Never pickable.
    - `id` string, required
    - `label` string, required: The property exactly as the council's checker words it.
    - `reason` 'no_service_record', required
  - `source_notice` SourceNotice: What the service already knows about the council's own checker, said at the postcode step rather than after an address has been chosen. For `council_site_maintenance` and `council_not_supported`, POST /lookups refuses a FRESH lookup with the same `problem` while the notice stands; a schedule already held is still served, which is why this is a notice on a 200 and not a refusal. `council_site_unavailable` refuses nothing: the council's route is currently failing (held broken or quarantined, or a measured success rate under 0.7 with no healthy route), so a lookup may be slow and may fail. Show `detail` on the address screen and let the citizen carry on.
    - `problem` 'council_site_maintenance' | 'council_not_supported' | 'council_site_unavailable', required: The problem a fresh lookup would be refused with, or is currently likely to end with.
    - `detail` string, required
  - `input_options` InputOptions: The council's OWN collection units for the field it asks for, when that council resolves bin days by road or area rather than per property. It exists so the citizen picks the council's wording instead of guessing it; a picked row is still matched by the same strict address rules as typed text, and ambiguity is still a refusal. Absent whenever no picker can be offered - which includes councils answered from the postcode alone, any moment the list cannot be read, and a `q` that matches nothing. Absent means the ordinary free-text journey. One exception: where a council's whole road list is held (City of Edinburgh, and Nuneaton and Bedworth), a `q` matching nothing is still an answer - `total` is 0 and `options` is empty - and for Edinburgh `not_listed_help` says where a road that is not listed may be served instead.
    - `field` 'street' | 'locality', required: Which POST /lookups field the chosen `value` fills.
    - `shape` 'short_list' | 'type_to_narrow' | 'area_contents', required: How the list behaves. `short_list` = a council search returns a handful of records. `type_to_narrow` = the whole list exists at once and must be filtered before it is rendered. `area_contents` = the row is an area, made recognisable by what the council lists inside it.
    - `extra_fields` string[]: Other fields this council's input contract still needs beside the chosen row (for example a house number where the council keys a street but reports per building).
    - `query` string: Echo of the `q` that produced these rows.
    - `total` integer: How many of the council's records matched `q`, before the row cap.
    - `row_limit` integer: The most rows this endpoint will ever return.
    - `needs_more_query` boolean: `true` when more records matched than may be rendered. `options` is then empty on purpose: ask for more of the name rather than showing a list nobody can read.
    - `not_listed_value` string: Sentinel `value` for the picker's final row ("none of these"). Submitting it means the citizen wants ordinary address entry; it is never sent to a council.
    - `options` InputOption[], required
      - `value` string, required: The council's own text, submitted back verbatim in the request field named by `input_options.field`. Not an opaque id: this is the key the council's own checker uses.
      - `label` string, required: The unit as the council words it - the row's title.
      - `detail` string: The council's own supporting text for this row, when it has one: an area's list of the roads and villages inside it, or a record's number range. Present only for shapes where the label alone is not recognisable.
      - `hint` string: OUR plain-language explanation of the row, emitted only where the run can evidence it (a classified-road segment proven to be this postcode's road). Never a guess and never council text.
    - `not_listed_help` object: The council-specific line for a citizen whose road or area is not in the list, with the council's own page to follow. Present only for councils that have one (City of Edinburgh: homes on communal bins are not in its road list).
      - `text` string, required
      - `link_text` string, required
      - `url` string, uri, required

## Other responses

- `304`: A 304 means stored content is unchanged, not that the council re- verified the date. The content matches the `If-None-Match` ETag. No body.
- `400`: Malformed input (e.g. `invalid_postcode`).
- `401`: Supplied bearer token is malformed, unknown or revoked, or a token is missing during a token-only hold (`unauthorized`).
- `404`: Postcode is valid but outside coverage (not a UK collecting council we know).
- `405`: The path exists but not with this method. Every resource below answers exactly one method; the `Allow` header names it.
- `422`: Council resolved but explicitly unsupported (`council_not_supported`) — refused at the postcode step so no address screen is shown for a lookup that could only fail. Same body as the POST /lookups refusal: the council (with its own page when known) and, optionally, `council_note`.
- `429`: Request, provider or new-work allowance exceeded; optional limit_scope and token_request_url explain the limit.
- `500`: An unexpected fault on our side (`server_error`). Nothing is implied about whether the work started; retry with the same `Idempotency-Key` where one applies.
- `503`: Required service configuration, a dependency, or shared lookup admission is temporarily unavailable (`service_unavailable`).

---

[API](https://skmtc.dev/whenisbins/apis/whenisbins-uk-bin-collection-api-for-apps-and-ai-agents.md) · [All operations](https://skmtc.dev/whenisbins/apis/whenisbins-uk-bin-collection-api-for-apps-and-ai-agents/llms.txt) · [OpenAPI document](https://skmtc.dev/whenisbins/apis/whenisbins-uk-bin-collection-api-for-apps-and-ai-agents/revisions/6e4a960474a4?raw)
