Skip to main content
PUT /v1/properties/{provider_id} pushes one property into Maat. The provider_id in the path is your identifier — unique within your integration, never across the platform — which makes the operation idempotent by construction: retrying a timed-out push is always safe, and there is no idempotency header to remember.

Replace, not merge

The payload you send is the whole property. An amenity you omit is removed; a photo you omit is dropped. This mirrors how listings are edited everywhere on Maat, and it is the only version of “update” in which remove this amenity is expressible at all. The practical consequence: build your push from your own catalogue every time, never from a diff.

A property can be accepted and not yet sellable

A property with no price, no photos or no amenities is accepted and held in an incomplete state rather than published at a placeholder price. The response tells you exactly where it stands: Branch on missing, and treat its two photo values differently — they ask for opposite things:
  • photos_processing means wait. Photos are fetched asynchronously, so the first push of a complete property legitimately comes back publishable: false. There is nothing to do; we fetch, process and publish on our own.
  • photos means send more. The property does not have enough usable images.

Photos are URLs, and unchanged URLs are free

You send photo URLs; Maat fetches each one and runs it through the same processing pipeline a host upload goes through. Three rules follow:
  1. URLs must be https, on a public DNS name, with no redirects. Anything else comes back in photos_rejected as url_refused — and the reason never says more than that, by design.
  2. An unchanged URL is never re-fetched, so a nightly catalogue sync costs nothing for the photos that did not change.
  3. Changed image bytes need a new URL. We treat the URL as the identity of the photo; publish edited images at a fresh path.
position: 0 is the cover photo. Per-photo failures are named individually in photos_rejected (url_refused, fetch_failed, unsupported_type, too_large, processing_failed), so one dead CDN path in a thirty-photo push is findable.

The address is where the property is — not how to get in

Send only the address fields in the schema. Delivery detail — building, floor, apartment number, directions to the key box — is deliberately not part of this contract in either direction, because it is private to the host and the confirmed guest. A payload carrying such a field is refused with validation_failed, not silently trimmed.

Taking a property off sale

status: "unlisted" makes the property unsellable on Maat without deleting anything. The response reports unlisted in missing[] alongside any real deficiency, so you always know whether the property is otherwise complete before you re-list it. There is no property deletion in the current contract.

Availability

Live in the sandbox: a sandbox token creates real properties in your sandbox workspace. Against a production workspace the request is authenticated and validated in full, then answers 501 — see the introduction.