Move Home Organisation CIC Listings API

Upload, update, retrieve and remove residential or commercial listings.

Operations 3

PUT /listings/{reference} Upsert a listing #
GET /listings/{reference} Retrieve a listing #
DELETE /listings/{reference} Remove a listing #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/movehome-org-listings-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

movehome-org-listings-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: RAIA Portal Feed Listings API
  version: 0.1.0
  summary: Vendor-neutral HTTP contract for syndicating property listings, reconciling branch inventory, polling enquiries, and activating portal products.
  description: 'The RAIA Portal Feed API gives implementers a single, vendor-neutral contract

    that covers the same jobs-to-be-done as historical UK portal feed

    integrations (Rightmove Real-Time Data Feed, Rightmove Commercial Listings,

    Zoopla Real-Time Listings, and Zoopla Products).'
  contact:
    name: RAIA Protocol Working Group
    email: protocol@estateaigents.org
    url: https://estateaigents.org
  license:
    name: MIT
    identifier: MIT
servers:
- url: https://feed.example.com/api/raia/portal/v1
  description: Production (implementer-hosted)
- url: https://staging.feed.example.com/api/raia/portal/v1
  description: Staging / sandbox (implementer-hosted)
- url: http://localhost:8787/api/raia/portal/v1
  description: Local development
security:
- OAuth2ClientCredentials:
  - feed.read
  - feed.write
  - products.write
tags:
- name: Listings
  description: Upload, update, retrieve and remove residential or commercial listings.
paths:
  /listings/{reference}:
    parameters:
    - $ref: '#/components/parameters/ListingReference'
    put:
      tags:
      - Listings
      summary: Upsert a listing
      description: 'Upload a new listing or update an existing one. Identity is driven by

        the path `reference`; if the reference is new the listing is created

        (HTTP `201`), otherwise it is updated (HTTP `200`).


        The payload covers both residential and commercial property. Use the

        `residential` body when marketing a single dwelling and the

        `commercial` body when marketing a building (optionally with up to 50

        spaces). Buyers and portals can see the same listing projected through

        the public RAIA property card.'
      operationId: upsertListing
      security:
      - OAuth2ClientCredentials:
        - feed.write
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ListingUpsert'
            examples:
              residentialLetting:
                $ref: '#/components/examples/ResidentialLettingUpsert'
              commercialBuilding:
                $ref: '#/components/examples/CommercialBuildingUpsert'
      responses:
        '200':
          description: Listing updated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListingSaveAction'
        '201':
          description: Listing created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListingSaveAction'
        '202':
          description: 'Accepted for asynchronous processing. Returned when the feed

            implementation queues uploads (mirrors the Rightmove RTDF and

            Zoopla ZPG behaviour where ingestion is asynchronous).

            '
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AsyncAccepted'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          description: The reference conflicts with another existing listing (for example, attempting to re-use a building reference for a space).
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetail'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        5XX:
          $ref: '#/components/responses/ServerError'
    get:
      tags:
      - Listings
      summary: Retrieve a listing
      operationId: getListing
      security:
      - OAuth2ClientCredentials:
        - feed.read
      parameters:
      - $ref: '#/components/parameters/BranchIdHeader'
      responses:
        '200':
          description: Listing found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Listing'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        5XX:
          $ref: '#/components/responses/ServerError'
    delete:
      tags:
      - Listings
      summary: Remove a listing
      description: 'Permanently removes a listing from the feed. The caller must supply a

        `removal_reason` so the receiving portal/system can audit why the

        listing was withdrawn. Removing a building also removes any associated

        spaces.'
      operationId: deleteListing
      security:
      - OAuth2ClientCredentials:
        - feed.write
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ListingRemovalRequest'
            example:
              branch_id: 56726
              removal_reason: SOLD_BY_US
              removed_at: '2026-05-28T06:00:00Z'
      responses:
        '200':
          description: Listing removed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListingRemovalResult'
        '202':
          description: Removal accepted for asynchronous processing.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AsyncAccepted'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        5XX:
          $ref: '#/components/responses/ServerError'
components:
  schemas:
    CommercialBuilding:
      type: object
      required:
      - reference
      - address
      - status
      - primary_classification
      description: 'Commercial building. A building may be marketed on its own (BUILDING

        model) or alongside one or more `spaces` (SPACE model). Maximum of

        50 spaces per building, matching the upstream Rightmove Commercial

        limit.

        '
      properties:
        reference:
          type: string
          pattern: ^[A-Za-z0-9_-]{1,100}$
        address:
          $ref: '#/components/schemas/Address'
        status:
          $ref: '#/components/schemas/ListingStatus'
        published:
          type: boolean
          default: true
        primary_classification:
          $ref: '#/components/schemas/PropertyClassification'
        secondary_classifications:
          type: array
          items:
            $ref: '#/components/schemas/PropertyClassification'
        available_date:
          type: string
          format: date
        let_type:
          type: string
          enum:
          - STANDARD
          - SHORT_TERM
          - LONG_TERM
          - FLEXIBLE
        let_contract_length:
          type: integer
        service_charge:
          type: number
        business_rates:
          type: number
        rent_all_inclusive:
          type: boolean
        condition:
          type: string
          enum:
          - FULL_FIT_OUT
          - PARTIAL_FIT_OUT
          - SHELL_SPACE
        sizing:
          $ref: '#/components/schemas/Sizing'
        pricing:
          $ref: '#/components/schemas/Pricing'
        amenities:
          type: array
          items:
            type: string
          description: Free-form amenity tags such as `WIFI`, `CONCIERGE`, `PARKING`, `AIR_CONDITIONING`.
        auction:
          type: boolean
          default: false
          description: True if the building is being offered via auction (sales only).
        media:
          $ref: '#/components/schemas/Media'
        spaces:
          type: array
          items:
            $ref: '#/components/schemas/CommercialSpace'
          maxItems: 50
    ListingRemovalRequest:
      type: object
      required:
      - removal_reason
      properties:
        branch_id:
          oneOf:
          - type: integer
            format: int64
          - type: string
        removal_reason:
          $ref: '#/components/schemas/RemovalReason'
        removed_at:
          type: string
          format: date-time
          description: When the removal was committed in the source system.
        note:
          type: string
          maxLength: 500
    AsyncAccepted:
      type: object
      required:
      - status
      - request_id
      properties:
        status:
          type: string
          enum:
          - QUEUED
        request_id:
          type: string
          description: Identifier the caller can use to correlate logs.
        polling_url:
          type: string
          format: uri
          description: Optional URL the caller may poll for the final result.
    Furnishing:
      type: string
      enum:
      - FURNISHED
      - PART_FURNISHED
      - UNFURNISHED
      - FURNISHED_OR_UNFURNISHED
    TenureType:
      type: string
      enum:
      - FREEHOLD
      - LEASEHOLD
      - SHARE_OF_FREEHOLD
      - COMMONHOLD
    Address:
      type: object
      required:
      - display_address
      - postcode
      - country
      description: 'Full address for the listing as held by the feed implementer. Note the

        public RAIA property card masks the address to district level until an

        enquiry reaches the `COMMITTED` state — see ADR-211.

        '
      properties:
        display_address:
          type: string
          maxLength: 120
        building_identifier:
          type: string
          maxLength: 100
          description: Number or name of the building.
        address_line_1:
          type: string
          maxLength: 200
        address_line_2:
          type: string
          maxLength: 200
        district:
          type: string
          maxLength: 100
        town:
          type: string
          maxLength: 100
        county:
          type: string
          maxLength: 100
        postcode:
          type: string
          maxLength: 12
          examples:
          - W1D 3QU
        country:
          type: string
          description: ISO 3166-1 alpha-2 country code.
          pattern: ^[A-Z]{2}$
        latitude:
          type: number
          format: float
          minimum: -90
          maximum: 90
        longitude:
          type: number
          format: float
          minimum: -180
          maximum: 180
        uprn:
          type: integer
          format: int64
          description: UK Unique Property Reference Number, where applicable.
        show_map:
          type: boolean
          default: true
    MediaAsset:
      type: object
      required:
      - url
      properties:
        url:
          type: string
          format: uri
          maxLength: 1024
          description: Publicly accessible URL. Brochures must end in `.pdf`.
        description:
          type: string
          maxLength: 200
        order:
          type: integer
          minimum: 0
        etag:
          type: string
          description: 'Optional ETag of the asset at the time it was published. Feed

            consumers SHOULD honour this when revalidating downloads.

            '
    MeasurementType:
      type: string
      enum:
      - GEA
      - GIA
      - NIA
      - IPMS1
      - IPMS2
      - IPMS3_1
      - IPMS3_2
    RemovalReason:
      type: string
      description: Why a listing is being removed. Aligned with both Rightmove Commercial removal reasons and the RTDF action set.
      enum:
      - SOLD_BY_US
      - SOLD_BY_ANOTHER_AGENT
      - LET_BY_US
      - LET_BY_ANOTHER_AGENT
      - WITHDRAWN_FROM_MARKET
      - LOST_INSTRUCTION
      - REMOVED
    CommercialListingInput:
      type: object
      required:
      - transaction_type
      - building
      description: Commercial listing payload.
      properties:
        transaction_type:
          $ref: '#/components/schemas/TransactionType'
        building:
          $ref: '#/components/schemas/CommercialBuilding'
        public_card:
          $ref: '#/components/schemas/PublicCardProjection'
    TransactionType:
      type: string
      enum:
      - SALES
      - LETTINGS
    PropertyType:
      type: string
      description: Residential property sub-type. Use the `commercial` payload for commercial classifications.
      enum:
      - FLAT
      - APARTMENT
      - STUDIO
      - MAISONETTE
      - TERRACED
      - END_TERRACE
      - SEMI_DETACHED
      - DETACHED
      - BUNGALOW
      - COTTAGE
      - TOWNHOUSE
      - LAND
      - OTHER
    ListingUpsert:
      oneOf:
      - $ref: '#/components/schemas/ResidentialListingInput'
      - $ref: '#/components/schemas/CommercialListingInput'
      discriminator:
        propertyName: kind
        mapping:
          residential: '#/components/schemas/ResidentialListingInput'
          commercial: '#/components/schemas/CommercialListingInput'
    ListingStatus:
      type: string
      description: Marketing lifecycle status. Mirrors the public RAIA property card statuses plus the commercial-only `UNDER_OFFER`.
      enum:
      - AVAILABLE
      - UNDER_OFFER
      - SOLD_STC
      - SOLD_STCM
      - RESERVED
      - LET_AGREED
      - OFF_MARKET
      - WITHDRAWN
    CommercialClassification:
      type: string
      description: 'Commercial classification family. The selected sub-type determines

        which optional extension object (e.g. `office`, `industrial`) is

        meaningful.

        '
      enum:
      - OFFICE
      - INDUSTRIAL_AND_LOGISTICS
      - RETAIL
      - LEISURE_AND_HOSPITALITY
      - LAND_AND_DEVELOPMENT
      - OTHER
    Media:
      type: object
      description: Bundles of media for a listing or commercial space.
      properties:
        photos:
          type: array
          items:
            $ref: '#/components/schemas/MediaAsset'
        floor_plans:
          type: array
          items:
            $ref: '#/components/schemas/MediaAsset'
        epcs:
          type: array
          items:
            $ref: '#/components/schemas/MediaAsset'
        epc_graphs:
          type: array
          items:
            $ref: '#/components/schemas/MediaAsset'
        brochures:
          type: array
          items:
            $ref: '#/components/schemas/MediaAsset'
        virtual_tours:
          type: array
          items:
            $ref: '#/components/schemas/MediaAsset'
    Listing:
      type: object
      required:
      - reference
      - branch_id
      - transaction_type
      - status
      - updated_at
      properties:
        reference:
          type: string
        branch_id:
          type: string
          description: Stringified branch identifier for stable JSON consumers.
        transaction_type:
          $ref: '#/components/schemas/TransactionType'
        status:
          $ref: '#/components/schemas/ListingStatus'
        kind:
          type: string
          enum:
          - residential
          - commercial
        residential:
          $ref: '#/components/schemas/ResidentialListingInput'
        commercial:
          $ref: '#/components/schemas/CommercialListingInput'
        public_card_url:
          type: string
          format: uri
          description: URL of the public RAIA property card derived from this listing.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        version:
          type: integer
          description: Monotonically increasing version. Useful for optimistic concurrency.
    ListingSaveAction:
      type: object
      required:
      - reference
      - action
      - updated_at
      description: Returned by upsert operations. Mirrors the upstream `PropertySaveAction` envelope.
      properties:
        reference:
          type: string
        action:
          type: string
          enum:
          - CREATED
          - UPDATED
          - NO_CHANGE
        updated_at:
          type: string
          format: date-time
        version:
          type: integer
        public_card_url:
          type: string
          format: uri
    AreaSizeUnit:
      type: string
      enum:
      - SQFT
      - SQM
      - ACRES
      - HECTARES
    RentFrequency:
      type: string
      enum:
      - MONTHLY
      - YEARLY
      - WEEKLY
    ProblemDetail:
      description: RFC 7807 problem detail. Implementations may add vendor-specific extension members.
      type: object
      properties:
        type:
          type: string
          format: uri
          default: about:blank
        title:
          type: string
        status:
          type: integer
          minimum: 100
          maximum: 599
        detail:
          type: string
        instance:
          type: string
          format: uri
        trace_id:
          type: string
        timestamp:
          type: string
          format: date-time
        validation_errors:
          type: array
          items:
            type: object
            required:
            - field
            - message
            properties:
              field:
                type: string
                examples:
                - building.location.postcode
              message:
                type: string
              code:
                type: string
                examples:
                - MISSING
    PropertyClassification:
      type: object
      required:
      - classification
      - sub_type
      properties:
        classification:
          $ref: '#/components/schemas/CommercialClassification'
        sub_type:
          $ref: '#/components/schemas/CommercialSubType'
    CommercialSubType:
      type: string
      enum:
      - OFFICE
      - SERVICED_OFFICE
      - WAREHOUSE
      - DISTRIBUTION_WAREHOUSE
      - FACTORY_MANUFACTURING
      - SELF_STORAGE
      - TRADE_COUNTER
      - INDUSTRIAL_PARK
      - LIGHT_INDUSTRIAL
      - HEAVY_INDUSTRIAL
      - LAND
      - WOODLAND
      - FARM
      - COMMERCIAL_DEVELOPMENT
      - RESIDENTIAL_DEVELOPMENT
      - SCIENCE_PARK
      - RETAIL_HIGH_STREET
      - RETAIL_OUT_OF_TOWN
      - RETAIL_PROPERTY_SHOPPING_CENTRE
      - SHOP
      - CONVENIENCE_STORE
      - POST_OFFICE
      - HOTEL
      - PUB
      - RESTAURANT
      - BAR
      - CAFE
      - LEISURE_FACILITY
      - CAMPSITE_HOLIDAY_VILLAGE
      - COMM_GUEST_HOUSE
      - HEALTHCARE_FACILITY
      - DENTAL_CARE
      - PHARMACY
      - CARE_HOME_FACILITY
      - CHILDCARE_FACILITY
      - PLACE_OF_WORSHIP
      - GARAGE
      - PETROL_STATION
      - DATA_CENTRE
      - LIFE_SCIENCES_LABS
      - AUTOMOTIVE
      - MIXED_USE
      - STUDENT_HOUSING
      - OTHER
    ResidentialListingInput:
      type: object
      required:
      - transaction_type
      - status
      - property_type
      - address
      - headline
      description: Residential single-dwelling listing payload.
      properties:
        transaction_type:
          $ref: '#/components/schemas/TransactionType'
        status:
          $ref: '#/components/schemas/ListingStatus'
        property_type:
          $ref: '#/components/schemas/PropertyType'
        headline:
          type: string
          maxLength: 200
        description:
          type: string
          maxLength: 10000
        bedrooms:
          type: integer
          minimum: 0
        bathrooms:
          type: integer
          minimum: 0
        reception_rooms:
          type: integer
          minimum: 0
        floor_area_sqm:
          type: number
          minimum: 0
        available_from:
          type: string
          format: date
        asking_price:
          type: number
          minimum: 0
          description: Sales price. Use when transaction_type is SALES.
        asking_rent_pcm:
          type: number
          minimum: 0
          description: Lettings rent per calendar month. Use when transaction_type is LETTINGS.
        rent_frequency:
          $ref: '#/components/schemas/RentFrequency'
        deposit:
          type: number
          minimum: 0
        currency:
          $ref: '#/components/schemas/Currency'
        tenure:
          $ref: '#/components/schemas/TenureType'
        furnishing:
          $ref: '#/components/schemas/Furnishing'
        epc_rating:
          type: string
          pattern: ^[A-G]$
        features:
          type: array
          items:
            type: string
            maxLength: 200
          maxItems: 20
        parking:
          type: array
          items:
            type: string
            enum:
            - OFF_STREET
            - GARAGE
            - ALLOCATED
            - RESIDENTS_PERMIT
            - NONE
        outside_space:
          type: array
          items:
            type: string
            enum:
            - PRIVATE_GARDEN
            - BALCONY
            - TERRACE
            - ROOF_TERRACE
            - NONE
        address:
          $ref: '#/components/schemas/Address'
        media:
          $ref: '#/components/schemas/Media'
        public_card:
          $ref: '#/components/schemas/PublicCardProjection'
    ListingRemovalResult:
      type: object
      required:
      - reference
      - removed_at
      - removal_reason
      properties:
        reference:
          type: string
        removed_at:
          type: string
          format: date-time
        removal_reason:
          $ref: '#/components/schemas/RemovalReason'
    Currency:
      type: string
      description: ISO 4217 currency code.
      pattern: ^[A-Z]{3}$
      examples:
      - GBP
      - EUR
      - USD
      - THB
      - SGD
    Sizing:
      type: object
      properties:
        size:
          type: number
          minimum: 0
        min_size:
          type: number
          minimum: 0
        max_size:
          type: number
          minimum: 0
        unit:
          $ref: '#/components/schemas/AreaSizeUnit'
        measurement_type:
          $ref: '#/components/schemas/MeasurementType'
    PublicCardProjection:
      type: object
      description: 'Optional projection that controls how the listing surfaces on the

        public RAIA property card (`schemas/property.json`). When omitted the

        feed implementation derives sensible defaults from the listing.

        '
      properties:
        raia_id:
          type: string
          pattern: ^prop-[a-z]{2}-[a-z0-9]+-[0-9]+$
          description: External stable RAIA property identifier.
        publish:
          type: boolean
          default: true
        max_data_level:
          type: integer
          minimum: 0
          maximum: 3
          default: 0
        suppress_address:
          type: boolean
          default: true
          description: When true, the public card only exposes district-level location until COMMITTED.
    Pricing:
      type: object
      required:
      - price
      properties:
        price:
          type: number
          minimum: 0
        currency:
          $ref: '#/components/schemas/Currency'
        display_qualifier:
          type: string
          enum:
          - NONE
          - PRICE_ON_APPLICATION
          - GUIDE_PRICE
          - OFFERS_IN_EXCESS_OF
          - OFFERS_IN_REGION_OF
          - FROM
        frequency:
          $ref: '#/components/schemas/RentFrequency'
        rent_obligation:
          type: string
          enum:
          - FULLY_REPAIRING_AND_INSURING
          - INTERNAL_REPAIRING_AND_INSURING
          - INTERNAL_REPAIRING_ONLY
          - NEGOTIABLE
    CommercialSpace:
      type: object
      required:
      - reference
      - name
      - floor_identifier
      - sizing
      - status
      - primary_classification
      properties:
        reference:
          type: string
          pattern: ^[A-Za-z0-9_-]{1,100}$
          description: Unique within the building; must differ from the building reference.
        name:
          type: string
          maxLength: 200
        floor_identifier:
          type: string
          maxLength: 50
        description:
          type: string
          maxLength: 100000
        sizing:
          $ref: '#/components/schemas/Sizing'
        status:
          $ref: '#/components/schemas/ListingStatus'
        pricing:
          $ref: '#/components/schemas/Pricing'
        let_type:
          type: string
          enum:
          - STANDARD
          - SHORT_TERM
          - LONG_TERM
          - FLEXIBLE
        available_date:
          type: string
          format: date
        service_charge:
          type: number
        business_rates:
          type: number
        let_contract_length:
          type: integer
          description: Length of rental contract in months. Lettings only.
        rent_all_inclusive:
          type: boolean
        published:
          type: boolean
        condition:
          type: string
          enum:
          - FULL_FIT_OUT
          - PARTIAL_FIT_OUT
          - SHELL_SPACE
        primary_classification:
          $ref: '#/components/schemas/PropertyClassification'
        secondary_classifications:
          type: array
          items:
            $ref: '#/components/schemas/PropertyClassification'
        media:
          $ref: '#/components/schemas/Media'
        order:
          type: integer
          minimum: 0
        key_features:
          type: array
          items:
            type: string
            maxLength: 300
          maxItems: 10
  responses:
    BadRequest:
      description: Validation error. The body is a `ProblemDetail`.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetail'
    NotFound:
      description: Resource not found.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetail'
    Unauthorized:
      description: Missing or invalid bearer token.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetail'
    Forbidden:
      description: Token is valid but lacks the required scope.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetail'
    TooManyRequests:
      description: Rate limit exceeded. Quotas reset every 60 seconds.
      headers:
        Retry-After:
          schema:
            type: integer
            description: Seconds to wait before retrying.
        X-RateLimit-Limit:
          schema:
            type: integer
        X-RateLimit-Remaining:
          schema:
            type: integer
        X-RateLimit-Reset:
          schema:
            type: integer
            description: Epoch seconds when the quota resets.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetail'
    ServerError:
      description: Unexpected error.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetail'
  parameters:
    BranchIdHeader:
      name: X-RAIA-Branch-Id
      in: header
      required: false
      description: 'Optional branch context for the read. When omitted the response is

        scoped to all branches the caller''s credentials grant access to.

        '
      schema:
        type: string
    ListingReference:
      name: reference
      in: path
      required: true
      description: 'Customer-controlled listing reference. Must be unique per branch. For

        commercial properties with spaces, this is the building reference;

        each space carries its own reference inside the payload.

        '
      schema:
        type: string
        pattern: ^[A-Za-z0-9_-]{1,100}$
        examples:
        - REF_001
        - BLD_LON_001
  examples:
    CommercialBuildingUpsert:
      summary: Commercial building with one space
      value:
        kind: commercial
        transaction_type: LETTINGS
        building:
          reference: BLD_LON_001
          status: AVAILABLE
          published: true
          primary_classification:
            classification: OFFICE
            sub_type: SERVICED_OFFICE
          address:
            display_address: 33 Soho Square, London
            building_identifier: 33 Soho Square
            postcode: W1D 3QU
            country: GB
            latitude: 51.5139
            longitude: -0.1317
          pricing:
            price: 750000
            currency: GBP
            display_qualifier: GUIDE_PRICE
          amenities:
          - WIFI
          - CONCIERGE
          - PARKING
          - AIR_CONDITIONING
          spaces:
          - reference: SPACE_LON_001_FL2
            name: 2nd Floor
            floor_identifier: Floor 2
            sizing:
              size: 5941
              unit: SQFT
              measurement_type: GIA
            status: AVAILABLE
            pricing:
              price: 65
              currency: GBP
              frequency: YEARLY
            primary_classification:
              classification: OFFICE
              sub_type: SERVICED_OFFICE
            key_features:
            - Open plan with private meeting rooms
            - Bike storage and shower facilities
    ResidentialLettingUpsert:
      summary: Residential lettings listing
      value:
        kind: residential
        transaction_type: LETTINGS
        status: AVAILABLE
        property_type: FLAT
        headline: 2-bed flat, Hammersmith W6
        description: Bright two-bedroom flat close to the station.
        bedrooms: 2
        bathrooms: 1
        reception_rooms: 1
        floor_area_sqm: 62
        available_from: '2026-07-01'
        asking_rent_pcm: 2450
        rent_frequency: MONTHLY
        deposit: 2826
        currency: GBP
        furnishing: FURNISHED
        epc_rating: C
        features:
        - Balcony
        - Close to tube
        - Furnished
        - Managed property
        parking:
        - RESIDENTS_PERMIT
        outside_space:
        - BALCONY
        address:
          display_address: 42 King Street, London W6 9TA
          address_line_1: 42 King Street
          town: London
          postcode: W6 9TA
          country: GB
          latitude: 51.4927
          longitude: -0.2228
        media:
          photos:
          - url: https://example-estates.test/media/REF_001/photo-1.jpg
            description: Living room
            order: 0
        public_card:
          raia_id: prop-gb-example-000001
          publish: true
          max_data_level: 3
          suppress_address: true
  securitySchemes:
    OAuth2ClientCredentials:
      type: oauth2
      description: 'Server-to-server OAuth2 client credentials flow. The token endpoint is

        published by the implementer; credentials are issued out-of-band

        during onboarding. Tokens are short-lived Bearer JWTs.

        '
      flows:
        clientCredentials:
          tokenUrl: https://feed.example.com/oauth/token
          scopes:
            feed.read: Read listings, branches, performance and enquiries.
            feed.write: Upsert and remove listings.
            products.write: Request portal product activations.