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

# Ad Groups Pagination

> Offset-based pagination for the GET /ad-groups endpoint

<Note>
  This page is also available in [Ukrainian](/guides/ad-groups-pagination-uk).
</Note>

## Overview

`GET /ad-groups` now returns a **paginated response** instead of a flat array.
Use `offset` and `limit` query parameters to page through results.

<Warning>
  **Breaking change** — the response shape changed. FE code that treats the
  response as an array must be updated to read `.results`.
</Warning>

***

## Response format

The endpoint now returns an object with pagination metadata:

```json theme={null}
{
  "results": [
    {
      "id": 123456,
      "name": "My Ad Group",
      "campaign_id": 789,
      "campaign_name": "Campaign A",
      "status": "ENABLED",
      "type": "SEARCH_STANDARD",
      "metrics": { ... }
    }
  ],
  "total": 142,
  "limit": 50,
  "offset": 0
}
```

| Field     | Type              | Description                        |
| --------- | ----------------- | ---------------------------------- |
| `results` | `AdGroupSchema[]` | Current page of ad groups          |
| `total`   | `int`             | Total count after search filtering |
| `limit`   | `int`             | Echoed `limit` value               |
| `offset`  | `int`             | Echoed `offset` value              |

***

## Query parameters

| Parameter | Type  | Default | Description             |
| --------- | ----- | ------- | ----------------------- |
| `limit`   | `int` | `50`    | Maximum items per page  |
| `offset`  | `int` | `0`     | Number of items to skip |

These work alongside existing parameters (`search`, `exclude_removed`, etc.).

***

## Usage examples

<Tabs>
  <Tab title="First page (default)">
    ```
    GET /api/v1/google-ads/{customer_id}/ad-groups
    ```

    Returns the first 50 ad groups with `total` reflecting the full count.
  </Tab>

  <Tab title="Second page">
    ```
    GET /api/v1/google-ads/{customer_id}/ad-groups?offset=50&limit=50
    ```

    Skips the first 50 results and returns the next 50.
  </Tab>

  <Tab title="Search + pagination">
    ```
    GET /api/v1/google-ads/{customer_id}/ad-groups?search=brand&offset=0&limit=20
    ```

    `total` reflects the number of ad groups matching "brand", not the total
    number of ad groups.
  </Tab>
</Tabs>

***

## Frontend integration

Update your API call to handle the new response shape:

```typescript theme={null}
// Before (flat array)
const adGroups = await api.get<AdGroup[]>("/ad-groups", { params });

// After (paginated object)
const { results, total, limit, offset } = await api.get<{
  results: AdGroup[];
  total: number;
  limit: number;
  offset: number;
}>("/ad-groups", { params: { ...params, offset: page * pageSize, limit: pageSize } });

const totalPages = Math.ceil(total / limit);
```

***

## Notes

* The **CSV endpoint** (`GET /ad-groups/csv`) is not affected — it still returns
  a flat CSV file.
* `total` always reflects the count **after** search filtering but **before**
  pagination slicing.
