PUTrooms:write
Replace zones
Replace zones.
Request
PUThttps://api.cymatics.tech/v1/rooms/{room}/zones
Send your key as Authorization: Bearer cym_test_…. Requires the rooms:write scope. Test keys read the simulator; live keys read your paired Cymos.
roomrequiredstring | pathRoom idSDK and CLI: room_id |
Idempotency-Keystring | headerReplays the first response for an identical request within the project and mode. |
Request body
zonesrequiredobject[] | body |
expected_revisionrequiredinteger, ≥ 1 | body |
application/json
{
"zones": [
{
"id": "zone_bed",
"type": "bed",
"frame_id": "frame_bedroom",
"polygon": [
[
0.4,
1.5
],
[
2,
1.5
],
[
2,
3.6
],
[
0.4,
3.6
]
]
}
],
"expected_revision": 1
}Response
200 · application/json
{
"data": {
"object": "zones",
"room_id": "room_bedroom",
"zones": [
{
"id": "zone_bed",
"type": "bed",
"frame_id": "frame_bedroom",
"polygon": [
[
0.4,
1.5
],
[
2,
1.5
],
[
2,
3.6
],
[
0.4,
3.6
]
]
}
],
"revision": 1
},
"meta": {
"request_id": "req_01",
"project_id": "proj_demo",
"livemode": false,
"generated_at": "2026-10-24T23:55:30.000Z"
}
}Errors
429rate_limit_exceeded: Too many requests this minute for the key (or twice that across the project), or too many open streams for the project. Retry after the seconds in Retry-After.quota_exceeded: A live key's project has used its monthly live-hour cap. There is no Retry-After. Don't retry; raise the live-hour cap in the dashboard. Headers: Retry-After, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset.503live_unavailable: This operation has no live data for this project yet (for example, no paired Cymo covers it). Don't retry the same request; pair a Cymo that covers it, or build against a test key.service_unavailable: A dependency, such as API key verification, is unreachable, or the project is busy with another write. Retry after the seconds in Retry-After, with backoff.4XXInvalid request, credential, permission or revision.defaultError with a stable code and request ID.
Every error is a { error, meta } envelope with a stable code. See Errors for each code and whether to retry.
Call it
TypeScript · @cymos/sdk
import { Cymo } from "@cymos/sdk";
const cymo = new Cymo({ apiKey: process.env.CYMO_API_KEY! });
const { data, meta } = await cymo.rooms.zones.replace({
room_id: "room_bedroom",
zones: [
{
id: "zone_bed",
type: "bed",
frame_id: "frame_bedroom",
polygon: [
[
0.4,
1.5
],
[
2,
1.5
],
[
2,
3.6
],
[
0.4,
3.6
]
]
}
],
expected_revision: 1
});terminal · cymatics CLI
$ cymatics rooms zones replace --room-id room_bedroom --input body.json --jsoncurl
curl -X PUT "https://api.cymatics.tech/v1/rooms/room_bedroom/zones" \
-H "Authorization: Bearer $CYMO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"zones":[{"id":"zone_bed","type":"bed","frame_id":"frame_bedroom","polygon":[[0.4,1.5],[2,1.5],[2,3.6],[0.4,3.6]]}],"expected_revision":1}'The SDK takes path parameters and body fields in one object. The CLI reads the body from --input, a JSON file or - for stdin.
MCP tool
replace_zones({
room_id: "room_bedroom",
input: {
zones: [
{
id: "zone_bed",
type: "bed",
frame_id: "frame_bedroom",
polygon: [
[
0.4,
1.5
],
[
2,
1.5
],
[
2,
3.6
],
[
0.4,
3.6
]
]
}
],
expected_revision: 1
}
})The MCP tool replace_zones calls this operation with your key. It takes the request body as input.