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.
| Field | What it is |
|---|---|
added | URLs that were not there before: these are the ones we download |
removed | URLs no longer in the object |
unchanged | The ones that remain. They are not downloaded again |
reordered | The 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
| Code | When |
|---|---|
400 | canonical is missing from the body |
401 | Token missing, expired or invalid |
403 | The property-api-update scope is missing |
404 | That paId does not exist, or it is deleted |
409 | The 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.
Related
- POST /properties — create
- GET /properties — where you get the object to modify
- DELETE /properties/{paId} — delete