---
title: "Submit or update a feed listing"
method: PUT
path: "/listing-feed/listings/{externalRef}"
tags: ["Listing feed"]
---

# Submit or update a feed listing

`PUT /listing-feed/listings/{externalRef}`

## Request

- Base URL: `https://platform-api.homejourney.sg/v1`
- URL: `https://platform-api.homejourney.sg/v1/listing-feed/listings/{externalRef}`
- Auth: HTTP bearer

Submits a listing with its CEA salesperson and marketing authority when the authenticated client has `listings.write`. Every new listing and every change other than price, availability, last seen, expiry and unit count waits for a Homejourney reviewer, and the route answers `202`; a published listing stays live meanwhile. Price and availability changes to a published listing apply at once and answer `200`. A salesperson who is not current on the CEA register, or not registered under the agency licence, is refused with `422` before review. An organization may have 200 listings in review; beyond that the route answers `429` `review_queue_full`. Each status change sends `listing_feed.status_changed`. Live keys need `listings.write` and a live licensed estate agency organization with a feed source, created when live access is approved; otherwise the route answers `403` `listing_feed_not_admitted`. A sandbox key writes only sandbox storage: salesperson `R000001A` publishes, `R000002B` is rejected with `photos_unclear`, `R000003C` answers `salesperson_not_under_agency`, `R000004D` answers `salesperson_not_current`, and any other number stays in review. External URL: `/v1/listing-feed/listings/{externalRef}`. Current Next.js implementation path: `/api/platform/v1/listing-feed/listings/[externalRef]`. This mutating route requires `Idempotency-Key`.

## Path parameters

- `externalRef` string, required

## Headers

- `X-Correlation-Id` string
- `Idempotency-Key` string, required

## Request body

- ListingFeedPutRequest: The MLS listing fields, the CEA salesperson who markets the listing, and the authority. A change to only `price`, `partner_availability_status`, `partner_last_seen_at`, `partner_expires_at` or `available_units_count` on a published listing applies without review; any other change is a new revision.
  - `title` string
  - `development_name` string
  - `address` string
  - `unit` string
  - `postal_code` string
  - `district` string
  - `price` number
  - `bedrooms` integer
  - `bathrooms` integer
  - `square_feet` number
  - `property_type` 'HDB' | 'Condominium' | 'Landed' | 'Commercial'
  - `status` 'For Sale' | 'For Rent'
  - `description` string
  - `images` string[]
  - `latitude` number
  - `longitude` number
  - `available_from` string, date
  - `furnishing_level` string
  - `tenure` string
  - `built_year` integer
  - `lease_duration_months` integer
  - `subletting_type` string
  - `house_rules` string[]
  - `included_amenities` string[]
  - `partner_availability_status` 'available' | 'limited' | 'unavailable'
  - `partner_last_seen_at` string, date-time
  - `partner_expires_at` string, date-time
  - `available_units_count` integer
  - `salesperson_registration_no` string, required: Current on the CEA register and registered under the agency licence.
  - `authority` ListingFeedAuthority, required: The agency's attestation of its marketing authority. The agency keeps the agreement; Homejourney stores this attestation.
    - `authority_type` 'exclusive_marketing' | 'non_exclusive_marketing' | 'estate_agency_agreement', required
    - `authority_reference` string, required
    - `authority_signed_on` string, date, required
    - `authority_expires_on` string, date, required: Not before `authority_signed_on` or today in Singapore. The listing leaves search when it passes.
    - `owner_consent_to_advertise` true, required
    - `media_rights_confirmed` true, required
    - `attestation_version` string, required

## Response `200`

A price or availability change applied to the published listing.

- ListingFeedListingResponse
  - `listing` ListingFeedListing, required
    - `object` 'listing_feed_listing', required
    - `external_ref` string, required: The partner's own listing reference.
    - `status` 'in_review' | 'published' | 'rejected' | 'withdrawn' | 'expired', required: A published listing stays `published` while a later revision is in review, rejected or expired; `revision_status` reports that revision.
    - `listing_id` string, uuid, nullable, required: The Homejourney listing, once published.
    - `revision` integer, nullable, required
    - `revision_status` 'in_review' | 'approved' | 'rejected' | 'superseded' | 'expired' | 'null', nullable, required
    - `reason_codes` string[], required: Why the latest revision was rejected.
    - `hidden_reasons` string[], required: Why a published listing is not currently shown in search.
    - `updated_at` string, date-time, required
  - `livemode` boolean, required
  - `request_id` string, required

## Other responses

- `202`: The listing revision waits for review.
- `400`: Request validation failed.
- `401`: Missing or invalid platform API key.
- `403`: Credential, environment, or scope is not allowed.
- `404`: Platform API feature or resource is not available.
- `409`: Idempotency key is in progress or conflicts with an earlier request body.
- `422`: The request is well formed but cannot be accepted, such as a salesperson who is not current or not under the agency licence.
- `429`: Rate limit exceeded.
- `500`: Unexpected platform API failure.

---

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