Unit listings

Update a unit listing

Writes the listing's marketing fields and publishes or unpublishes it. Every field you send replaces what was there; use the images and videos endpoints for the gallery rather than this one.

PUT
https://api.portal.magicdoor.com/company-app/unit-listings/{unitId}

Authorization

Authorizationstringrequired
Bearer token — Send your API token in the Authorization header as Bearer <token>. Requests without a valid token are rejected with 401 Unauthorized.

Path parameters

unitIdstringrequired

Snowflake id of the unit. A unit listing has no id of its own — it is keyed by the unit it markets, so this is also the listing's id.

example: 1830472847398404098

Body

application/json

statusenum<string>

Where the unit stands from a letting point of view.

pendingavailablereservedleasedoccupiedunderMaintenancesoldother
rentalPricenumber

The asking rent. A decimal with at most two places, between 0 and 1,000,000,000,000.

securityDepositnumber

The deposit asked for. Same numeric rules as rentalPrice.

availableFromstring · date

First date a tenant could move in, as YYYY-MM-DD. Read in the company's timezone.

leaseTermenum<string>

The lease length being offered.

monthToMonthhalfYearoneYeartwoYearsthreeYearsother
titlestring

The listing headline, 1 to 150 characters.

descriptionstring

The body copy, up to 2500 characters and not blank. Needs at least 10 characters before the listing can be published.

tagsstring[]

Free-form marketing tags. At most 50.

petPolicyobject

Replaces the pet policy wholesale.

amenitiesobject[]

Replaces the amenity list. At most 30 entries.

termsobject

Extra terms of the offer, as a map of string keys to string values. At most 10 entries.

listedboolean

true publishes the listing, false withdraws it. Leave it out to leave publication as it is.

pinnedboolean

Whether to pin the listing to the top of the property manager's own list.

imagesobject[]deprecated

Legacy gallery replacement — up to 50 entries of { fileId, default, description }, and any image not in the list is removed. Use the unit-listing images endpoints instead.

videosobject[]deprecated

Legacy video replacement — up to 5 entries of { fileId, default, description }, and any video not in the list is removed. Use the unit-listing videos endpoints instead.

Response

200 · The listing in full, after the write.

idstring

The listing's id, which is the same Snowflake as unitId.

portfolioIdstring

The portfolio behind the unit.

propertyIdstring

The property behind the unit.

unitIdstring

The unit this listing markets. Equal to id.

statusenum<string>

Where the unit stands from a letting point of view. This is the listing's own status; it is not derived from whether a lease exists.

pendingavailablereservedleasedoccupiedunderMaintenancesoldother
rentalPricenumber

The asking rent, as a decimal amount. This is the listing's price, separate from the unit's marketRent. Absent when it was never set, and a listing cannot be published without it.

securityDepositnumber

The deposit asked for, as a decimal amount. Absent when it was never set.

availableFromstring · date

The first date a tenant could move in. Absent when it was never set.

leaseTermenum<string>

The lease length being offered. Absent when it was never set.

monthToMonthhalfYearoneYeartwoYearsthreeYearsother
titlestring

The listing headline. Absent when it was never set.

listedstring · date

The date the listing was published. Its absence is what tells you the listing is not live — there is no separate boolean in the response.

updatedstring · date-time

When the listing last changed, as a wall clock in the company's timezone with no offset.

pinnedboolean

Whether a property manager pinned this listing to the top of their own list.

primaryImageobject

The image marked default, or the first one if none is. Absent when the listing has no images.

primaryVideoobject

The video marked default, or the first one if none is. Absent when the listing has no videos.

propertyTypeenum<string>

Copied from the property, so a search can filter on it without a second call.

singleFamilymultiFamilycommercialcondotownHomeother
singleLineAddressstring

The unit's address as one line. Absent when neither the unit nor its property has an address.

recentRentalApplicationsinteger

How many rental applications named this unit in the recent window. Computed.

descriptionstring

The listing body copy, up to 2500 characters. Absent when it was never written, and a listing cannot be published without at least 10 characters here.

descriptionTranslationsobject[]

The description in other languages. Absent when none exist. This endpoint does not write them.

imagesobject[]

The listing gallery, in the order MagicDoor stores it. Absent when there are none.

videosobject[]

The listing's videos. Absent when there are none.

tagsstring[]

Free-form marketing tags. Absent when none were set.

petPolicyobject

What pets are allowed and on what terms. Absent when no policy was set.

amenitiesobject[]

What the unit offers. Absent when none were recorded.

locationAnalysisstring

MagicDoor's write-up of the neighbourhood. Generated, not written by the caller. Absent when none has been produced.

termsobject

Extra terms of the offer, as a map of string keys to string values. Absent when none were set.

unitobject

The unit this listing markets, expanded.

portfolioobject

The portfolio behind the unit, expanded.

propertyobject

The property behind the unit, expanded.

canNotBeListedReasonsobject

Why this listing cannot be published, as a map from field name to a sentence explaining the problem. Keys you may see are rentalPrice (missing or not above zero), description (missing or under 10 characters) and unitActive (the unit is deactivated). Absent entirely when the listing is publishable — that absence is the signal to look for, not an empty object.

400 · A field failed validation — a price with more than two decimal places, a description over 2500 characters, more than 50 tags, more than 30 amenities, or more than 10 terms. The response carries an `errors` member mapping each rejected field name to its message.

401 · The access token is missing, expired, or not for this company.

404 · No unit with that id, or it belongs to another company.

Listing versus unit

The unit holds the facts of the physical space — beds, baths, square feet, floor, marketRent. The unit listing is the public marketing record: title, description, photos, videos, amenities, pet policy, asking rentalPrice, availableFrom. They share an id but have separate lifecycles: editing one does not touch the other, and a unit can exist with no listing at all. listed is what decides whether the listing is published; active on the unit is a different flag entirely.

`listed` is a boolean going in and a date coming back

Send "listed": true to publish and false to withdraw. The response reports listed as the date the listing was published, and leaves it out when the listing is not live. They are the same concept in two shapes, not two different fields.

Check what is blocking publication first

A listing needs a rentalPrice above zero, a description of at least 10 characters, and an active unit. Fetch the listing and read canNotBeListedReasons to see which of those is missing before you try to publish.