openapi: 3.1.0
info:
    title: Nederland Postcode API
    description: |
        Address validation and lookup API for Dutch addresses.
        Validate postcodes, retrieve complete address information,
        and integrate address autocomplete functionality into your website or application.

        The API includes access to energy label data for Dutch
        residential and commercial properties, as well as district
        (wijk) lookups via `attributes[]=district`.

        ## Base URL
        The base URL for all API requests is `https://api.nederlandpostcode.nl/`.

        ## Authentication
        All requests require authentication via a Bearer token in the `Authorization` header.

        ```
        Authorization: Bearer npa_live_xxx
        ```

        Tokens have a prefix indicating the environment:
        - `npa_live_` — production token
        - `npa_test_` — test token (only works for postal codes `1015CN` and `1118BN`)
    version: 1.0.0
    contact:
        name: Support
        url: https://nederlandpostcode.nl/contact
externalDocs:
    description: API Documentation (Dutch) - Website
    url: https://nederlandpostcode.nl/documentatie

servers:
    - url: https://api.nederlandpostcode.nl

security:
    - BearerAuth: []

tags:
    - name: Addresses
      description: Look up Dutch addresses by postcode, house number and optional addition.
    - name: Energy Labels
      description: Retrieve current and historical energy labels for Dutch properties.
    - name: Coordinates
      description: Find the nearest address(es) by geographic coordinates.
    - name: Quota
      description: Check current API usage and limits.

components:
    securitySchemes:
        BearerAuth:
            type: http
            scheme: bearer
            description: Get a free test token at https://nederlandpostcode.nl/registreren

    schemas:
        Address:
            type: object
            properties:
                postcode:
                    type: string
                    example: '1118BN'
                number:
                    type: integer
                    example: 800
                addition:
                    type: string
                    nullable: true
                    example: null
                street:
                    type: string
                    example: 'Schiphol Boulevard'
                city:
                    type: string
                    example: 'Schiphol'
                municipality:
                    type: string
                    example: 'Haarlemmermeer'
                province:
                    type: string
                    example: 'Noord-Holland'
                country:
                    type: string
                    example: 'Nederland'
                coordinates:
                    $ref: '#/components/schemas/Coordinates'
                details:
                    $ref: '#/components/schemas/AddressDetails'

        Coordinates:
            type: object
            properties:
                latitude:
                    type: number
                    format: float
                    example: 52.30528553688755
                longitude:
                    type: number
                    format: float
                    example: 4.750645160863609

        AddressDetails:
            type: object
            description: Additional fields returned when requested via `attributes[]`.
            properties:
                district:
                    type: object
                    description: District the address belongs to.
                    properties:
                        official:
                            type: string
                            example: 'Schiphol'
                        name:
                            type: string
                            example: 'Schiphol'
                function:
                    type: string
                    description: Function of the location (e.g. woonfunctie, kantoorfunctie).
                    example: 'kantoorfunctie'
                location_status:
                    type: string
                    description: Status of the location object.
                    example: 'verblijfsobject in gebruik'
                property_status:
                    type: string
                    description: Status of the building/property.
                    example: 'pand in gebruik'
                surface_area:
                    type: integer
                    description: Surface area of the property in square meters.
                    example: 120
                construction_year:
                    type: integer
                    description: Year the property was constructed.
                    example: 1990

        EnergyLabel:
            type: object
            properties:
                inspection_date:
                    type: string
                    example: '02-08-2022'
                valid_until_date:
                    type: string
                    example: '02-08-2032'
                construction_type:
                    type: string
                    example: 'utiliteitsbouw'
                building_type:
                    type: string
                    nullable: true
                    example: null
                energy_label:
                    type: string
                    example: 'A+++'
                max_energy_demand:
                    type: number
                    format: float
                    example: 98.4
                max_fossil_energy_demand:
                    type: number
                    format: float
                    example: 55.48
                min_renewable_share:
                    type: number
                    format: float
                    example: 55.3

        AddressWithEnergyLabels:
            type: object
            properties:
                postcode:
                    type: string
                    example: '1118BN'
                number:
                    type: integer
                    example: 800
                addition:
                    type: string
                    nullable: true
                    example: null
                street:
                    type: string
                    example: 'Schiphol Boulevard'
                city:
                    type: string
                    example: 'Schiphol'
                energy_labels:
                    type: array
                    items:
                        $ref: '#/components/schemas/EnergyLabel'

        Quota:
            type: object
            properties:
                used:
                    type: integer
                    description: Number of API requests used in the current billing period.
                    example: 1042
                limit:
                    type: integer
                    description: Maximum number of API requests allowed in the current billing period.
                    example: 10000

        ValidationError:
            type: object
            properties:
                message:
                    type: string
                    example: 'The postcode field is required. (and 1 more error)'
                errors:
                    type: object
                    additionalProperties:
                        type: array
                        items:
                            type: string
                    example:
                        postcode:
                            - 'The postcode field is required.'
                        number:
                            - 'The number field is required.'

        ErrorMessage:
            type: object
            properties:
                message:
                    type: string

        RateLimitError:
            type: object
            properties:
                message:
                    type: string
                    example: 'Rate limit exceeded.'
                quota:
                    type: object
                    properties:
                        strategy:
                            type: string
                            enum: [per_minute, per_month]
                            example: 'per_minute'
                        limit:
                            type: integer
                            example: 60

paths:
    /v1/address:
        get:
            summary: Retrieve address data based on postal code and house number
            description: |
                Returns addresses matching the given postal code and house number, optionally filtered by house number addition.
                Always returns a list of matching addresses (even if there is only one). If no match is found, an empty list is returned with status code `200`.

                If the `addition` parameter is omitted, all addresses for the given postcode and house number are returned.
                If `addition` is provided but empty, only addresses without an addition are returned.

                Use `attributes[]` to request additional fields such as coordinates, district, etc.
            operationId: getAddress
            tags:
                - Addresses
            parameters:
                - name: postcode
                  in: query
                  required: true
                  description: Postal code without spaces (e.g. 1015CN)
                  schema:
                      type: string
                      example: '1118BN'
                - name: number
                  in: query
                  required: true
                  description: House number
                  schema:
                      type: integer
                      example: 800
                - name: addition
                  in: query
                  required: false
                  description: House number addition (e.g. A). If omitted, all additions are returned. If provided but empty, addresses without addition are returned.
                  schema:
                      type: string
                      example: 'A'
                - name: 'attributes[]'
                  in: query
                  required: false
                  description: |
                      Additional fields to include in the response. Can be specified multiple times.
                      - `coordinates` — Latitude and longitude of the address
                      - `district` — District the address belongs to
                      - `function` — Function of the location (e.g. woonfunctie, kantoorfunctie)
                      - `location_status` — Status of the location object
                      - `property_status` — Status of the building/property
                      - `surface_area` — Surface area in square meters
                      - `construction_year` — Year of construction
                  schema:
                      type: array
                      items:
                          type: string
                          enum:
                              - coordinates
                              - district
                              - function
                              - location_status
                              - property_status
                              - surface_area
                              - construction_year
                  style: form
                  explode: true
            responses:
                '200':
                    description: Request successful. Returns a list of matching addresses (may be empty).
                    content:
                        application/json:
                            schema:
                                type: object
                                properties:
                                    data:
                                        type: array
                                        items:
                                            $ref: '#/components/schemas/Address'
                            examples:
                                single_address:
                                    summary: Single address with coordinates and district
                                    value:
                                        data:
                                            - postcode: '1118BN'
                                              number: 800
                                              addition: null
                                              street: 'Schiphol Boulevard'
                                              city: 'Schiphol'
                                              municipality: 'Haarlemmermeer'
                                              province: 'Noord-Holland'
                                              country: 'Nederland'
                                              details:
                                                  district:
                                                      official: 'Schiphol'
                                                      name: 'Schiphol'
                                                  function: 'kantoorfunctie'
                                              coordinates:
                                                  latitude: 52.30528553688755
                                                  longitude: 4.750645160863609
                                multiple_addresses:
                                    summary: Multiple addresses (same postal code + house number, different additions)
                                    value:
                                        data:
                                            - postcode: '1015CN'
                                              number: 10
                                              addition: 'A'
                                              street: 'Keizersgracht'
                                              city: 'Amsterdam'
                                              municipality: 'Amsterdam'
                                              province: 'Noord-Holland'
                                              country: 'Nederland'
                                            - postcode: '1015CN'
                                              number: 10
                                              addition: 'B'
                                              street: 'Keizersgracht'
                                              city: 'Amsterdam'
                                              municipality: 'Amsterdam'
                                              province: 'Noord-Holland'
                                              country: 'Nederland'
                                            - postcode: '1015CN'
                                              number: 10
                                              addition: 'C'
                                              street: 'Keizersgracht'
                                              city: 'Amsterdam'
                                              municipality: 'Amsterdam'
                                              province: 'Noord-Holland'
                                              country: 'Nederland'
                                            - postcode: '1015CN'
                                              number: 10
                                              addition: 'D'
                                              street: 'Keizersgracht'
                                              city: 'Amsterdam'
                                              municipality: 'Amsterdam'
                                              province: 'Noord-Holland'
                                              country: 'Nederland'
                                no_address:
                                    summary: No address found
                                    value:
                                        data: []
                '401':
                    description: Unauthorized. Invalid or missing API token.
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/ErrorMessage'
                '404':
                    description: Unknown API endpoint.
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/ErrorMessage'
                '422':
                    description: Invalid request. Check the provided parameters.
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/ValidationError'
                '428':
                    description: Missing required headers (e.g. X-API-Beta).
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/ErrorMessage'
                '429':
                    description: Too many requests in a short period of time.
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/RateLimitError'

    /v1/coordinates:
        get:
            summary: Find the nearest address by geographic coordinates
            description: |
                Returns the nearest address(es) to the given latitude and longitude, sorted by distance (closest first).
                Use the `limit` parameter to retrieve multiple nearby addresses.
                The response includes the coordinates of the returned address(es) by default.
            operationId: getCoordinates
            tags:
                - Coordinates
            parameters:
                - name: latitude
                  in: query
                  required: true
                  description: Latitude of the location to search near.
                  schema:
                      type: number
                      format: float
                      example: 52.30528553688755
                - name: longitude
                  in: query
                  required: true
                  description: Longitude of the location to search near.
                  schema:
                      type: number
                      format: float
                      example: 4.750645160863609
                - name: limit
                  in: query
                  required: false
                  description: Maximum number of addresses to return. Must be between 1 and 10. Defaults to 1.
                  schema:
                      type: integer
                      minimum: 1
                      maximum: 10
                      default: 1
                      example: 1
            responses:
                '200':
                    description: Request successful. Returns a list of addresses sorted by distance.
                    content:
                        application/json:
                            schema:
                                type: object
                                properties:
                                    data:
                                        type: array
                                        items:
                                            $ref: '#/components/schemas/Address'
                            example:
                                data:
                                    - postcode: '1118BN'
                                      number: 800
                                      addition: null
                                      street: 'Schiphol Boulevard'
                                      city: 'Schiphol'
                                      municipality: 'Haarlemmermeer'
                                      province: 'Noord-Holland'
                                      country: 'Nederland'
                                      coordinates:
                                          latitude: 52.30528553688755
                                          longitude: 4.750645160863609
                '401':
                    description: Unauthorized. Invalid or missing API token.
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/ErrorMessage'
                '404':
                    description: Unknown API endpoint.
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/ErrorMessage'
                '422':
                    description: Invalid request. Check the provided parameters.
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/ValidationError'
                '428':
                    description: Missing required headers (e.g. X-API-Beta).
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/ErrorMessage'
                '429':
                    description: Too many requests in a short period of time.
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/RateLimitError'

    /v1/energy-label:
        get:
            summary: Retrieve energy label based on postal code and house number
            description: |
                Returns the current and historical energy labels for a given address.
                If the combination of postal code and house number yields no result or multiple addresses, a `422` is returned.
                Use the `addition` parameter to disambiguate when multiple addresses share the same postcode and house number.
            operationId: getEnergyLabel
            tags:
                - Energy Labels
            parameters:
                - name: postcode
                  in: query
                  required: true
                  description: Postal code without spaces (e.g. 1118BN)
                  schema:
                      type: string
                      example: '1118BN'
                - name: number
                  in: query
                  required: true
                  description: House number
                  schema:
                      type: integer
                      example: 800
                - name: addition
                  in: query
                  required: false
                  description: House number addition (e.g. A)
                  schema:
                      type: string
                      example: 'A'
            responses:
                '200':
                    description: Request successful. Returns the address with its associated energy labels.
                    content:
                        application/json:
                            schema:
                                type: object
                                properties:
                                    data:
                                        type: array
                                        items:
                                            $ref: '#/components/schemas/AddressWithEnergyLabels'
                            example:
                                data:
                                    - postcode: '1118BN'
                                      number: 800
                                      addition: null
                                      street: 'Schiphol Boulevard'
                                      city: 'Schiphol'
                                      energy_labels:
                                          - inspection_date: '02-08-2022'
                                            valid_until_date: '02-08-2032'
                                            construction_type: 'utiliteitsbouw'
                                            building_type: null
                                            energy_label: 'A+++'
                                            max_energy_demand: 98.4
                                            max_fossil_energy_demand: 55.48
                                            min_renewable_share: 55.3
                '401':
                    description: Unauthorized. Invalid or missing API token.
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/ErrorMessage'
                '404':
                    description: Unknown API endpoint.
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/ErrorMessage'
                '422':
                    description: No address found, or multiple addresses found for the given combination.
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/ErrorMessage'
                            examples:
                                not_found:
                                    summary: No address found
                                    value:
                                        message: 'No address found for the given postcode and number.'
                                multiple_found:
                                    summary: Multiple addresses found
                                    value:
                                        message: 'Multiple addresses found for the given postcode and number.'
                '428':
                    description: Missing required headers (e.g. X-API-Beta).
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/ErrorMessage'
                '429':
                    description: Too many requests in a short period of time.
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/RateLimitError'

    /quota:
        get:
            summary: Retrieve current API usage and quota
            description: |
                Returns the number of API requests used in the current billing period, the monthly limit, and the date on which the quota resets.
            operationId: getQuota
            tags:
                - Quota
            responses:
                '200':
                    description: Request successful. Returns current quota usage and limit.
                    content:
                        application/json:
                            schema:
                                type: object
                                properties:
                                    data:
                                        $ref: '#/components/schemas/Quota'
                            example:
                                data:
                                    used: 1042
                                    limit: 10000
                '401':
                    description: Unauthorized. Invalid or missing API token.
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/ErrorMessage'
                '404':
                    description: Unknown API endpoint.
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/ErrorMessage'
                '429':
                    description: Too many requests in a short period of time.
                    content:
                        application/json:
                            schema:
                                $ref: '#/components/schemas/RateLimitError'
