> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zenoo.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Bulk Operations

> Process multiple alerts in a single request with partial success handling and detailed error reporting.

# Bulk Operations

Bulk endpoints allow you to perform actions on multiple records in a single API call. This is useful for high-volume alert processing, batch assignment, and workflow automation.

## Available bulk operations

| Endpoint                      | Method | Description                      |
| ----------------------------- | ------ | -------------------------------- |
| `/v1/alerts/bulk/resolve`     | POST   | Resolve multiple alerts          |
| `/v1/alerts/bulk/acknowledge` | POST   | Acknowledge multiple alerts      |
| `/v1/alerts/bulk/assign`      | POST   | Assign multiple alerts to a user |
| `/v1/alerts/bulk/escalate`    | POST   | Escalate multiple alerts         |

## Bulk resolve

Resolve multiple alerts with the same action and notes:

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST "https://api.zenoo.com/v1/alerts/bulk/resolve" \
    -H "Authorization: Bearer your-api-key" \
    -H "Content-Type: application/json" \
    -d '{
      "alert_tokens": ["alt_001", "alt_002", "alt_003"],
      "action": "Approve",
      "notes": "Batch: confirmed formatting differences in name fields."
    }'
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://api.zenoo.com/v1/alerts/bulk/resolve",
      headers={
          "Authorization": "Bearer your-api-key",
          "Content-Type": "application/json",
      },
      json={
          "alert_tokens": ["alt_001", "alt_002", "alt_003"],
          "action": "Approve",
          "notes": "Batch: confirmed formatting differences in name fields.",
      },
  )
  result = response.json()
  print(f"Succeeded: {result['summary']['succeeded']}")
  print(f"Failed: {result['summary']['failed']}")
  ```

  ```javascript Node.js theme={null}
  const response = await fetch("https://api.zenoo.com/v1/alerts/bulk/resolve", {
    method: "POST",
    headers: {
      Authorization: "Bearer your-api-key",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      alert_tokens: ["alt_001", "alt_002", "alt_003"],
      action: "Approve",
      notes: "Batch: confirmed formatting differences in name fields."
    })
  });
  const result = await response.json();
  console.log(`Succeeded: ${result.summary.succeeded}`);
  console.log(`Failed: ${result.summary.failed}`);
  ```
</CodeGroup>

## Bulk acknowledge

Claim multiple alerts for review:

```bash theme={null}
curl -X POST "https://api.zenoo.com/v1/alerts/bulk/acknowledge" \
  -H "Authorization: Bearer your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "alert_tokens": ["alt_004", "alt_005", "alt_006"]
  }'
```

## Bulk assign

Assign multiple alerts to a specific analyst:

```bash theme={null}
curl -X POST "https://api.zenoo.com/v1/alerts/bulk/assign" \
  -H "Authorization: Bearer your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "alert_tokens": ["alt_007", "alt_008", "alt_009"],
    "assignee": "user_analyst01"
  }'
```

## Bulk escalate

Escalate multiple alerts to a manager:

```bash theme={null}
curl -X POST "https://api.zenoo.com/v1/alerts/bulk/escalate" \
  -H "Authorization: Bearer your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "alert_tokens": ["alt_010", "alt_011"],
    "escalate_to": "user_manager01",
    "reason": "Complex corporate structure requires senior review."
  }'
```

## Partial success handling

Bulk operations use **partial success** semantics. The API processes each record independently and returns per-record results. The HTTP status code indicates the overall outcome:

| HTTP Status | Meaning                                                |
| ----------- | ------------------------------------------------------ |
| `200`       | All records processed successfully                     |
| `207`       | Partial success -- some records succeeded, some failed |
| `400`       | Request validation failed (e.g., empty array)          |
| `422`       | All records failed                                     |

### Response format

```json theme={null}
{
  "summary": {
    "total": 3,
    "succeeded": 2,
    "failed": 1
  },
  "results": [
    {
      "token": "alt_001",
      "status": "success",
      "new_status": "Resolved"
    },
    {
      "token": "alt_002",
      "status": "success",
      "new_status": "Resolved"
    },
    {
      "token": "alt_003",
      "status": "error",
      "error": {
        "code": "invalid_transition",
        "message": "Alert is already resolved."
      }
    }
  ]
}
```

### Error codes

| Error Code           | Description                                        |
| -------------------- | -------------------------------------------------- |
| `not_found`          | Alert token does not exist                         |
| `invalid_transition` | Alert is in a state that does not allow the action |
| `permission_denied`  | User lacks permission for the action               |
| `already_resolved`   | Alert is already resolved                          |

## Request limits

| Constraint                   | Limit                  |
| ---------------------------- | ---------------------- |
| Max alerts per request       | 100                    |
| Max concurrent bulk requests | 5                      |
| Rate limit                   | 60 requests per minute |

<Warning>
  Exceeding the per-request limit returns a `400 Bad Request` with the message: "Maximum 100 alert tokens per bulk request." Split larger batches into multiple requests.
</Warning>

## Best practices

<Tip>
  **Idempotency**: Bulk resolve and acknowledge are idempotent for already-processed records. Re-submitting a token that was already resolved returns a `success` result (not an error). This makes retries safe.
</Tip>

1. **Keep batches under 100 records.** Larger batches increase the chance of partial failures and make retries more complex.

2. **Handle partial success.** Always check the `summary.failed` count and inspect individual `results` for errors. Do not assume all records succeeded.

3. **Use consistent actions.** Bulk resolve applies the same action and notes to all alerts. If different alerts need different actions, split them into separate requests.

4. **Retry only failed records.** On partial failure, extract the failed tokens and retry only those:

```python theme={null}
result = response.json()
failed_tokens = [
    r["token"] for r in result["results"] if r["status"] == "error"
]
if failed_tokens:
    # Retry only the failed records
    retry_response = requests.post(
        "https://api.zenoo.com/v1/alerts/bulk/resolve",
        headers=headers,
        json={"alert_tokens": failed_tokens, "action": "Approve", "notes": "Retry batch."},
    )
```

## Audit trail

Every record in a bulk operation generates its own audit trail entry. Bulk operations also create a single `BULK_OPERATION` summary event that references the total count and action performed.

## Next steps

* [Alert Review Quickstart](/use-cases/alert-review). Step-by-step alert triage.
* [Pagination](/guides/pagination). Navigate large result sets.
* [Alert Management](/guides/alert-management). Full alert lifecycle reference.
