# Read the current state of up to 100 records

`POST /api/v1/data/batch` - [human page](https://aicdapi.com/api-reference#readCivicRecords)

**Release status.** Limited availability

Missing and removed IDs are absent; compare response IDs with the request. Total IDs across all requests must not exceed 100. JSON body cap is 65536 bytes.

**Authentication.** Customer API key: `Authorization: Bearer aicd_...`. A browser session does not authenticate this endpoint. Required scope: `civic:read`.

### Request body



| Field | Type | Required | Bounds | Description |
| --- | --- | --- | --- | --- |
| `requests` | object[] | yes | min 1 items, max 100 items |  |
| `requests.resource` | one of 11 values | yes |  |  |
| `requests.ids` | string[] | yes | min 1 items, max 100 items |  |

Example request body:

```json
{
  "requests": [
    {
      "resource": "agenda_items",
      "ids": [
        "5c2f0d18-0b1a-4a3f-9f1e-2b7c9a4d6e01"
      ]
    }
  ]
}
```

### Example request

```bash
curl -X POST 'https://aicdapi.com/api/v1/data/batch' \
  -H "Authorization: Bearer $AICD_API_KEY" \
  -H 'Content-Type: application/json' \
  --data '{"requests":[{"resource":"agenda_items","ids":["5c2f0d18-0b1a-4a3f-9f1e-2b7c9a4d6e01"]}]}'
```

### Response 200

Current records.

| Field | Type | Required | Bounds | Description |
| --- | --- | --- | --- | --- |
| `data` | object | yes |  |  |
| `data.items` | object[] | yes |  |  |

### Errors

| Status | `error.code` | Description |
| --- | --- | --- |
| **400** | `invalid_parameter` | Invalid parameter, duplicate query field or malformed JSON. |
| **401** | `unauthorized` | Missing, invalid, expired or revoked credential. |
| **403** | `billing_channel_unset`, `billing_entitlement_required`, `forbidden` | Customer lacks the required grant. |
| **404** |  | Snapshot does not exist, belongs to another customer, or expired. |
| **410** |  | Cursor is older than the retained replay floor; start a new snapshot. |
| **413** | `request_too_large`, `response_too_large` | Request or response exceeds its size cap; reduce the page limit. |
| **429** | `rate_limited` | A per-account request, burst or export allowance was exhausted, or the account-wide abuse ceiling was reached. The abuse ceiling is account-wide, is not charged against the paid quota, and is charged after the identity lookup and before a revoked, expired, unpaid, or scope-denied rejection is decided. |
| **500** | `internal_error` | Unexpected operation failure; the response contains no private database details. |
| **503** | `authentication_unavailable`, `feed_unavailable` | Authentication, limit store or feed state is unavailable. |
| **504** | `timeout` | Database statement or request deadline exceeded. |

### Behaviour

- **Limits.** Counted against the per-account minute and burst allowances. A paid subscription uses its plan's own limits, which the public usage limits help lists and the account console shows. An account with no paid plan is limited by the stored account defaults, which the account console also shows. A separate account-wide abuse limit also applies to recognized subscription keys, counted separately for usable keys and for revoked or expired ones, so a compromised key you rotate does not reduce the new key's capacity. It is charged before a denial is decided and is not charged against your paid quota.
- **Retry-After.** Sent on 429 only, as whole seconds.
- **Caching.** Customer responses must not be cached.
