## Rebuild a card set

`PUT /v1/pages/:pageId/blocks/:blockId/cards`

Replaces ALL content of the first card parent: non-card siblings and other card sets under that parent are deleted. This is native Bitrix24 behavior. source lists templates from the current set: type card with value as its index, or type preset with value as a manifest preset key. values is an object of edit groups; each group maps nodes with @N, where N is a position among all nodes matching that selector after rebuilding. This example creates two cards with different titles. Empty source, unknown selector or index returns 400 before mutation. For simple edits use clone/remove and PATCH nodes.

Requires the `landing` scope; READONLY keys receive 403 before mutation. Page-scoped actions check that the block belongs to the page.

Optional query `scope`: `KNOWLEDGE`, `GROUP` or `MAINPAGE` for that page context; omit for a regular site. IDs must be positive safe integers.

Expanded HTML is capped at 8 MiB; exceeding it returns 413 before mutation. null and unsupported text-node content return 400; unapplied plain text returns 422. Bitrix24 sanitizes rich HTML.

## Examples

### curl — personal key

```bash
curl -X PUT "https://vibecode.bitrix24.com/v1/pages/42/blocks/50/cards" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"selector":".landing-block-card","source":[{"type":"card","value":0},{"type":"card","value":1}],"values":{"first":{".landing-block-node-title@0":"First"},"second":{".landing-block-node-title@1":"Second"}}}'
```

### JavaScript — personal key

```javascript
const response = await fetch("https://vibecode.bitrix24.com/v1/pages/42/blocks/50/cards", {
  method: "PUT",
  headers: {"X-Api-Key": "YOUR_API_KEY", "Content-Type": "application/json"},
  body: JSON.stringify({"selector": ".landing-block-card", "source": [{"type": "card", "value": 0}, {"type": "card", "value": 1}], "values": {"first": {".landing-block-node-title@0": "First"}, "second": {".landing-block-node-title@1": "Second"}}}),
})
const result = await response.json()
if (!response.ok) throw new Error(result.error.message)
console.log(result.data)
```

### curl — OAuth application

```bash
curl -X PUT "https://vibecode.bitrix24.com/v1/pages/42/blocks/50/cards" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"selector":".landing-block-card","source":[{"type":"card","value":0},{"type":"card","value":1}],"values":{"first":{".landing-block-node-title@0":"First"},"second":{".landing-block-node-title@1":"Second"}}}'
```

### JavaScript — OAuth application

```javascript
const response = await fetch("https://vibecode.bitrix24.com/v1/pages/42/blocks/50/cards", {
  method: "PUT",
  headers: {"X-Api-Key": "YOUR_APP_KEY", "Authorization": "Bearer USER_SESSION_TOKEN", "Content-Type": "application/json"},
  body: JSON.stringify({"selector": ".landing-block-card", "source": [{"type": "card", "value": 0}, {"type": "card", "value": 1}], "values": {"first": {".landing-block-node-title@0": "First"}, "second": {".landing-block-node-title@1": "Second"}}}),
})
const result = await response.json()
if (!response.ok) throw new Error(result.error.message)
console.log(result.data)
```

## Response

```json
{
  "success": true,
  "data": {
    "cards": {
      ".landing-block-card": [
        {
          "index": 0,
          "content": "<div class=\"landing-block-card\"><h3 class=\"landing-block-node-title\">First</h3></div>"
        },
        {
          "index": 1,
          "content": "<div class=\"landing-block-card\"><h3 class=\"landing-block-node-title\">Second</h3></div>"
        }
      ]
    }
  }
}
```

A refusal after mutation does not undo the Bitrix24 action. On 422/502 after dispatch, read the block first; retrying clone/add can create another card.

## Errors

| HTTP | Code |
|---|---|
| 400 | INVALID_PARAMS / MISSING_REQUIRED_FIELDS / INVALID_SCOPE |
| 401 | MISSING_API_KEY / INVALID_API_KEY / TOKEN_MISSING |
| 403 | SCOPE_DENIED / WRITE_BLOCKED_READONLY_KEY / BITRIX_ACCESS_DENIED |
| 404 | ENTITY_NOT_FOUND |
| 409 | PORTAL_ADDRESS_CHANGED / LANDING_MODULE_NOT_ENABLED |
| 413 | PAYLOAD_TOO_LARGE |
| 422 | BITRIX_ERROR / BITRIX_NO_EFFECT |
| 429 | RATE_LIMITED |
| 502 | BITRIX_ERROR |
| 503 | SERVICE_UNAVAILABLE |
