---
title: list_asset_groups
description: List the asset groups of your Google Ads Performance Max campaigns, as AdCrunch stores them.
---

Ask for the asset groups of your Performance Max campaigns. A Performance Max campaign has no ad groups and no ads. Its asset groups hold its assets.

> List the asset groups of my Performance Max campaigns.

The agent lists the asset groups of each Performance Max campaign. You see the name, the status and the campaign of each asset group. [Read your accounts](/mcp/tools/read-your-accounts) shows the full job.

## Reference

**Available on:** [![Google Ads](/providers/gads.svg)](https://docs.adcrunch.dev/connect/providers)

List the asset groups of your Google Ads ad accounts. An asset group is where a Performance Max campaign keeps its assets. A Performance Max campaign has no ad groups and no ads: its asset groups are its only children. Only Google Ads has asset groups, so an ad account of another provider lists none. Send `campaignId` to list the asset groups of one campaign. An asset group has no budget of its own: its `budgetLevel` is `campaign`, and list_campaigns gives the budget. It reads what AdCrunch stored at the last ingestion, not what the provider holds now. To ask the provider now, use gads_list_asset_groups. Without `advertiserId`, it lists the asset groups of each ad account of your organization. Use list_advertisers to find the ids of your ad accounts. The row that AdCrunch stored last comes first. The answer holds at most `limit` rows (default 100, maximum 500). When it carries `nextCursor`, more rows exist: call this tool again with the same arguments and `cursor` set to that value. When it carries no `nextCursor`, you have every row.

### Input

| Argument | Type | Required | Description |
| --- | --- | --- | --- |
| `advertiserId` | string | no | List one ad account, prefixed `acc_`. Omit it to list every ad account of your organization. An ad account that your organization does not own gives an empty list. list_advertisers gives the ids. |
| `ids` | array of string | no | List only these ids. An id is the bare id that the provider gives, the `id` of a row. |
| `provider` | one of `meta`, `tiktok`, `snapchat`, `gads`, `dv360`, `x`, `openai` | no | List the ad accounts of one provider. Omit it to list every provider. |
| `status` | one of `ACTIVE`, `PAUSED`, `DELETED`, `ARCHIVED` | no | List one status, the same for each provider. TikTok `ENABLE` and `DISABLE` are `ACTIVE` and `PAUSED` here. |
| `cursor` | string, at least 1 character | no | The `nextCursor` of the previous page. Omit it to get the first page. Send it with no change, and with the same filters as the request that answered it: a cursor from a different query gets a 400 `invalid_cursor`. Do not build or change a cursor. |
| `limit` | integer, 1 to 500 | no | The greatest number of rows on the page, from 1 to 500. The default is 100. A greater value gets a 400, with `error` of `invalid_request`. Default: `100`. |
| `campaignId` | string | no | List only what this campaign holds. Send the bare id that the provider gives: the `id` of a row of list_campaigns, and the `campaignId` of each row here. |

### Output

A successful call returns this object in `structuredContent`.

| Field | Type | Always present | Description |
| --- | --- | --- | --- |
| `assetGroups` | array of object | yes | The asset groups that match, as AdCrunch stored them. An empty array means that no asset group matches, that your organization does not own the advertiser, or that the provider has no asset group. |
| `assetGroups[].advertiserId` | string | yes | The advertiser that owns it, prefixed `acc_`. |
| `assetGroups[].createdAt` | number or null | yes | When AdCrunch first stored this row. **Null when the row was read live**: AdCrunch holds no copy of it. `createdAt`, `updatedAt` and `deletedAt` are AdCrunch’s own times, so all three are null together on a live row. |
| `assetGroups[].createdTime` | number or null | yes | When the provider created the entity. This is the provider’s own time, so a live row carries it. Null where the provider reports none. |
| `assetGroups[].currency` | string or null | yes | The account currency, ISO 4217. Every row of one advertiser carries the same one. Null when AdCrunch does not know it yet. |
| `assetGroups[].deletedAt` | number or null | yes | When AdCrunch marked the row deleted. A listing never carries a deleted row, so this is null. |
| `assetGroups[].id` | string | yes | The id the provider gives, with no prefix. It is unique for one provider and one type, and it may legitimately recur across two types or two providers. |
| `assetGroups[].name` | string | yes | The name at the provider. |
| `assetGroups[].path` | string | yes | The ancestors and this entity, ids joined by `/`, oldest first. This is what makes a subtree one string comparison. |
| `assetGroups[].provider` | string | yes | The ad platform: `meta`, `tiktok` or `gads`. Those three are the providers whose entities AdCrunch reads, and https://docs.adcrunch.dev/connect/providers says how deep each one goes. |
| `assetGroups[].status` | one of `ACTIVE`, `PAUSED`, `DELETED`, `ARCHIVED` | yes | The status, normalized across the providers. TikTok `ENABLE` and `DISABLE` read here as `ACTIVE` and `PAUSED`. |
| `assetGroups[].updatedAt` | number or null | yes | When AdCrunch last rewrote this row. Null if it never changed. |
| `assetGroups[].updatedTime` | number or null | yes | When the provider last edited the entity. Null where the provider reports none. |
| `assetGroups[].budgetLevel` | one of `campaign`, `ad_group` or null | yes | Where the budget of this entity’s campaign lives. `campaign` when the campaign carries it — Meta Advantage campaign budget, TikTok Campaign Budget Optimization, and every Google Ads campaign. `ad_group` when each ad group carries its own. Null on a TikTok campaign whose payload does not say. |
| `assetGroups[].campaignId` | string or null | yes | The campaign it belongs to, as the bare id its provider gives. Null only when the stored path of the row names no campaign. |
| `assetGroups[].type` | string | yes | The type the provider uses, kept as the provider writes it: `asset_group`. Only Google Ads has an asset group. The resource names the concept, and the row keeps the provider’s own word, because a Meta `adset` and a Google Ads `ad_group` are not the same object. |
| `nextCursor` | string | no | Send this value as `cursor` to get the next page. It is absent on the last page. |

### Failure codes

A failed call has `isError` set, and `structuredContent.error` holds one of these codes. [Errors](/mcp/errors) describes the shape of a failed call.

- `invalid_cursor`
- `forbidden`
- `invalid_request`
- `internal_error`

### Scope

The token must hold `observe:read`. [Auth & scopes](/mcp/auth) lists each scope.

### Annotations

A client reads these hints. A hint that the tool does not declare has the default value of the MCP specification.

- **Read-only.** The tool changes nothing.
- **Closed world.** The tool reads and writes the data of AdCrunch only.

### Example

The arguments:

```json
{
  "campaignId": "20993874561"
}
```

The result, in `structuredContent`:

```json
{
  "assetGroups": [
    {
      "advertiserId": "acc_4829301756",
      "budgetLevel": "campaign",
      "campaignId": "20993874561",
      "createdAt": 1789610000000,
      "createdTime": null,
      "currency": "EUR",
      "deletedAt": null,
      "id": "6390218745",
      "name": "Performance Max — winter",
      "path": "20993874561/6390218745",
      "provider": "gads",
      "status": "ACTIVE",
      "type": "asset_group",
      "updatedAt": null,
      "updatedTime": null
    }
  ]
}
```
