# List upcoming agenda hits

`GET /api/v1/public/upcoming-agenda-hits` - [human page](https://aicdapi.com/api-reference#listUpcomingAgendaHits)

**Release status.** Available

Returns upcoming hits for one topic in meeting-time order. Send `topicSlug`
or its legacy alias `topic`: the request must carry one of them, and `topicSlug` wins
when both are present. A missing or uncovered topic is a 400, so the example request
below sends a topic.

Cursor pagination is the default. The legacy `page` parameter remains
available through page 100. Do not send `cursor` and `page` together.
Cursor responses contain `hits` and `nextCursor`, plus `totalCount` when
`count=true`. Legacy page responses retain `hits`, `totalCount`, `page`,
and `pageSize`. Every successful response includes `meta.pagination`.

Each hit carries `matchId`: that is the id `GET /api/v1/public/agenda-hits/{matchId}`
takes, and the recent-hits list does not return ids. An empty `hits` array is a
normal answer — no upcoming classified hit for that topic in the public coverage
set right now — and a backend failure returns the same empty page with HTTP 200.
Neither is proof that no body meets.


**Authentication.** No credentials. This endpoint is public.

### Parameters

| Field | Type | Required | Bounds | Description |
| --- | --- | --- | --- | --- |
| `query topicSlug` | string | no | length 1..∞ | Normalized topic slug. A request needs this or its legacy alias `topic`; `topicSlug` takes precedence when both are sent. |
| `query topic` | string | no | length 1..∞ | Legacy alias for `topicSlug`. Accepted on its own; `topicSlug` takes precedence when both are sent. |
| `query cursor` | string | no | length 1..200 | Opaque cursor returned by the previous response. Do not parse or modify it. |
| `query page` | integer | no | >= 1, <= 100 | Legacy one-based page number. Omit it to use cursor pagination. |
| `query count` | boolean | no |  | Set to true to include `totalCount` in a cursor response. Omit otherwise. |

### Example request

```bash
curl -X GET 'https://aicdapi.com/api/v1/public/upcoming-agenda-hits?topicSlug=zoning'
```

### Response 200

Upcoming agenda hits.

| Field | Type | Required | Bounds | Description |
| --- | --- | --- | --- | --- |
| `data` | object | yes |  | One page of upcoming hits. A cursor request returns `hits` and `nextCursor`, plus `totalCount` when `count=true`; a legacy `page` request returns `hits`, `totalCount`, `page`, and `pageSize`. |
| `data.hits` | object[] | yes | max 10 items | Upcoming classified hits for the requested topic in meeting-time order. An empty array means no upcoming classified hit for that topic right now; a backend failure returns the same empty page, so it is not proof that a body has no meetings. |
| `data.nextCursor` | string \| null | no |  | Cursor responses only. Null when the last page was returned. |
| `data.totalCount` | integer | no | >= 0 | Legacy `page` responses, and cursor responses that ask for `count=true`. |
| `data.page` | integer | no | >= 1, <= 100 | Legacy `page` responses only. |
| `data.pageSize` | integer | no |  | Legacy `page` responses only. |
| `meta` | object | yes |  |  |
| `meta.pagination` | object (PaginationMeta) | yes |  |  |

### Errors

| Status | `error.code` | Description |
| --- | --- | --- |
| **400** | `invalid_parameter` | A path or query parameter is invalid or unsupported. |
| **429** | `rate_limited` | More than 120 requests were made by this client IP in 60 seconds. |
| **500** | `internal_error` | The request could not be completed because of an internal error. |

### Behaviour

- **Pagination.** Cursor pagination by default, using the meeting time, classification time, and hit id as a keyset seek. A deprecated page parameter switches to offset pagination and is limited to page 100 with a fixed page size of 10. The cursor is not bound to the topic filter.
- **Limits.** 120 requests per 60 seconds per client IP, counted separately for each public endpoint and keyed on the first X-Forwarded-For entry. The allowance is not shared between public endpoints: exhausting one leaves the others available. If the limiter's own store fails, the request is allowed through rather than refused.
- **Retry-After.** Sent on 429 only, as whole seconds.
