BETA

PUT /properties/{paId}

It is a FULL REPLACEMENT: you send the whole object, just like on create. Whatever you do not send gets cleared.

That is why the response carries a diff, and the fields that were cleared are listed separately in cleared.

Resource URL

PUT https://property-api.mapaprop.com/property-v1/properties/{paId}

Authentication

Authorization: Bearer <your token>. Requires the property-api-update scope.

curl -X PUT https://property-api.mapaprop.com/property-v1/properties/01M3PTZ8YBMM5DSNW03WP8VD9E \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d @propiedad.json

The body

The same object as create, complete, in canonical:

{
  "canonical": { "…the property object, whole…" }
}

The fields are in The property JSON object.

This is not a PATCH. Sending {"canonical": {"price": 230000}} does not change only the price: it deletes everything else. To change one field, take the object the GET returns, change that field, and send the whole object.

The response

The response carries the clientRef, the same one you sent in the envelope. We return it on all six paths (verify, create, read, list, update and delete) so you can match it against your own database without having to remember which clientRef you asked with.

200 OK. It is the create response — object, portals, summary — plus the acknowledgement and the diff:

{
  "paId": "01M3PTZ8YBMM5DSNW03WP8VD9E",
  "updated": true,
  "updatedAt": "2026-09-29T23:41:02.118Z",
  "status": "active",
  "diff": {
    "property": {
      "price":       { "from": 245000, "to": 230000 },
      "description": { "from": "Departamento de 2 ambientes en el corazón…(1240 ch)", "to": "…(1310 ch)" },
      "toilettes":   { "from": 2, "to": null }
    },
    "assets":  { "added": 2, "removed": 1, "unchanged": 7, "reordered": false },
    "cleared": ["toilettes"],
    "changed": 6
  },
  "images": { "status": "processing", "total": 9, "processed": 7 }
}

diff.property — which fields changed

One per field, with its previous value and the new one. Long text is summarised with its real length (…(1240 ch)) so the response stays readable.

images and blueprint do not appear here: they have their own block.

🔑 diff.cleared — what got cleared

The list of fields that had a value and no longer do. It is the consequence of the full replacement, listed separately so you see it at a glance.

If cleared mentions something you did not mean to clear, send the PUT again with that field included. Nothing has been published yet.

diff.assets — the photos

"assets": { "added": 2, "removed": 1, "unchanged": 7, "reordered": false }

They are compared by URL, not by position. Reordering your photos without changing them gives unchanged and reordered: true — it does not count as new photos.

FieldWhat it is
addedURLs that were not there before: these are the ones we download
removedURLs no longer in the object
unchangedThe ones that remain. They are not downloaded again
reorderedThe same photos in a different order. It matters: the first one is the main one

New images go through the same cycle

If the PUT brings new URLs, images.status goes back to processing and the property is locked while we download them — same as on create. The ones already hosted are not downloaded again.

Errors

CodeWhen
400canonical is missing from the body
401Token missing, expired or invalid
403The property-api-update scope is missing
404That paId does not exist, or it is deleted
409The property is processing its images

A PUT on a deleted property returns 404: it does not bring it back. To have it again, create it anew — you will get a new paId.

What the PUT does NOT do yet

It does not republish on the portals. It stores the property and tells you what changed, but a listing already published on a portal is not updated on its own. That comes with the publishing step.