# Replace zones

> Replace zones.

`PUT https://api.cymatics.tech/v1/rooms/{room}/zones`

Scope: `rooms:write`

## Request

Send your key as `Authorization: Bearer cym_test_…`. Requires the `rooms:write` scope. Test keys read the simulator; live keys read your paired Cymos.

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `room` (SDK and CLI: `room_id`) | path | `string` | Yes | Room id |
| `Idempotency-Key` | header | `string` | No | Replays the first response for an identical request within the project and mode. |

## Request body

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `zones` | body | `object[]` | Yes |  |
| `expected_revision` | body | `integer, ≥ 1` | Yes |  |

```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`

```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

| Status | Description |
| --- | --- |
| `429` | `rate_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.<br>`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. |
| `503` | `live_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.<br>`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. |
| `4XX` | Invalid request, credential, permission or revision. |
| `default` | Error with a stable code and request ID. |

Every error is a `{ error, meta }` envelope with a stable `code`. See [Errors](https://docs.cymatics.tech/errors) for each code and whether to retry.

## Call it

**TypeScript · @cymos/sdk**

```ts
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**

```sh
$ cymatics rooms zones replace --room-id room_bedroom --input body.json --json
```

**curl**

```sh
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`.
