---
title: line_item_list
description: 'List the Line Items of one Campaign Plan, newest first, with what each Line Item created.'
---

Ask the agent which Line Items a Campaign Plan holds. The agent needs the list to find the id and the revision of a Line Item before it changes or reads that Line Item.

> "Which Line Items does the spring sale Campaign Plan have?"

The agent calls `line_item_list`. You see each Line Item with its name, its channel, its audience, its money in the currency of the Campaign Plan, its dates, its status and what it created. The newest Line Item comes first. The agent asks for the next page when more Line Items exist. A row carries no readiness. To check that AdCrunch can build one Line Item, the agent calls [`line_item_get`](/mcp/tools/line-item-get). [`campaign_plan_get`](/mcp/tools/campaign-plan-get) gives the number of Line Items.

[Plan a campaign](/mcp/tools/plan-a-campaign) walks the whole job.

## Reference

List the Line Items of a Campaign Plan, by the slug of the Campaign Plan, newest first. Each Line Item carries its id and its revision: line_item_update and line_item_delete take the revision as base_revision, and the other Line Item tools take the id. Each Line Item carries its name, or null when it has none, and what it already created. Each Line Item carries four derived facts: which provider sells its channel, whether we can execute it at all today, the window it resolves to after inheriting the window of the Campaign Plan, and whether its amount reads as a total or a daily rate. A Line Item here has no readiness: line_item_get gives the readiness of one Line Item. campaign_plan_get gives the number of Line Items. A Campaign Plan is AdCrunch's own planning document — it is **not** a campaign on Meta or Google. For those, use list_campaigns and get_campaign. 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 |
| --- | --- | --- | --- |
| `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`. |
| `campaign_plan_name` | string | yes | The Campaign Plan slug — its stable per-organization handle. |

### Output

A successful call returns this object in `structuredContent`.

| Field | Type | Always present | Description |
| --- | --- | --- | --- |
| `lineItems` | array of object | yes | The Line Items on this page, newest first. Each one has what it already created and no readiness: `line_item_get` gives the readiness of one Line Item. |
| `lineItems[].advertiserId` | string or null | yes | The ad account that the Line Item runs through, `acc_…`, or `null`. |
| `lineItems[].ageMax` | number or null | yes | The highest age, or `null` for no upper bound. |
| `lineItems[].ageMin` | number or null | yes | The lowest age, or `null` for no lower bound. |
| `lineItems[].budget` | number or null | yes | The amount in whole units of the currency of the Campaign Plan, or `null` when it is not set. `unit` tells how to read it. |
| `lineItems[].campaignPlanId` | string | yes | The id of the Campaign Plan that holds the Line Item, `cpl_…`. |
| `lineItems[].channel` | one of `meta`, `tiktok`, `snapchat`, `google_search`, `google_pmax`, `google_display`, `youtube`, `programmatic_display`, `linkedin`, `x` | yes | What the Line Item buys, in planning words. A channel is not a provider. |
| `lineItems[].countries` | array of string | yes | ISO 3166-1 alpha-2 codes. An empty list means that the geography is not decided. |
| `lineItems[].createdAt` | number | yes | Milliseconds since the Unix epoch, UTC. |
| `lineItems[].createdBy` | string | yes | The user who added the Line Item, `usr_…`. |
| `lineItems[].effectiveEndDate` | string or null | yes | The end that applies: the end date of the Line Item, else the end date of the Campaign Plan. `null` when neither has one. |
| `lineItems[].effectiveStartDate` | string or null | yes | The start that applies: the start date of the Line Item, else the start date of the Campaign Plan. `null` when neither has one. |
| `lineItems[].endDate` | string or null | yes | The end date of the Line Item itself, or `null` when the Line Item uses the end date of the Campaign Plan. |
| `lineItems[].executable` | boolean | yes | `true` when AdCrunch can create objects for this channel today. It is not a promise that a create succeeds. |
| `lineItems[].executions` | array of object | yes | The provider objects that the Line Item created, as `line_item_record_execution` recorded them. The list does not tell whether the Line Item is complete. |
| `lineItems[].executions[].advertiserId` | string | yes | The ad account that holds the object, `acc_…`. |
| `lineItems[].executions[].createdAt` | number | yes | When AdCrunch recorded the object, in milliseconds since the Unix epoch, UTC. |
| `lineItems[].executions[].entityId` | string | yes | The id of the object on the provider, with no prefix. The entity tools, such as `list_campaigns` and `get_ad`, use the same id. |
| `lineItems[].executions[].entityType` | string | yes | The word of the provider for the level of the object, such as `campaign`, `adset` or `ad`. |
| `lineItems[].executions[].id` | string | yes | The id of the record, `exe_…`. |
| `lineItems[].executions[].mutationId` | string or null | yes | The `mutationId` of the change that created the object, or `null` when the record names none. |
| `lineItems[].executions[].provider` | one of `meta`, `gads`, `tiktok`, `x`, `openai`, `snapchat`, `dv360` | yes | The provider of the object. |
| `lineItems[].gender` | one of `all`, `men`, `women` or null | yes | The gender of the audience, or `null` when it is not decided. `null` executes as `all`. |
| `lineItems[].id` | string | yes | The id of the Line Item, `lni_…`. |
| `lineItems[].name` | string or null | yes | A short label of the Line Item, at most 60 characters, or `null` for no name. It is not unique, and it is not a handle: nothing looks a Line Item up by it. |
| `lineItems[].objective` | one of `awareness`, `engagement`, `leads`, `sales`, `traffic`, `app_promotion` | yes | What the Line Item is for. |
| `lineItems[].personaId` | string or null | yes | The Persona that explains the audience, `psn_…`, or `null`. The countries, the ages and the gender are what execute. |
| `lineItems[].provider` | one of `meta`, `gads`, `tiktok`, `x`, `openai`, `snapchat`, `dv360` or null | yes | The provider that sells the channel, or `null` when AdCrunch has no integration for it. |
| `lineItems[].revision` | number | yes | The revision of the Line Item. It increments when the Line Item changes. Send it as `base_revision` to `line_item_update` or `line_item_delete`. |
| `lineItems[].startDate` | string or null | yes | The start date of the Line Item itself, or `null` when the Line Item uses the start date of the Campaign Plan. |
| `lineItems[].status` | one of `draft`, `validated` | yes | `validated` when a person validated the Line Item in the AdCrunch console, alone or with the approval of the Campaign Plan. It is a record, not a gate: the provider write tools do not check it. A real change to the Line Item returns it to `draft`. |
| `lineItems[].targetMetric` | one of `cpa`, `cpc`, `cpm`, `roas` or null | yes | The metric of the target, or `null` for no target. `cpa`, `cpc` and `cpm` are costs: lower is better. `roas` is a return: higher is better. A target blocks nothing: approval and readiness do not read it. |
| `lineItems[].targetValue` | number or null | yes | The value of the target: whole units of the currency of the Campaign Plan for `cpa`, `cpc` and `cpm`, a ratio for `roas`. `null` for no target. |
| `lineItems[].unit` | one of `total`, `daily` | yes | How to read `budget`. `total` when the Line Item has an effective end date: the budget is for the whole period. `daily` when it has none: the budget is for each day. |
| `lineItems[].updatedAt` | number or null | yes | When the Line Item last changed, or `null` when it never changed. |
| `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.

- `not_found`
- `invalid_cursor`
- `organization_unentitled`
- `forbidden`
- `invalid_request`
- `internal_error`

### Scope

The token must hold `campaign_plan: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
{
  "campaign_plan_name": "spring-sale",
  "limit": 20
}
```

The result, in `structuredContent`:

```json
{
  "lineItems": [
    {
      "advertiserId": "acc_1203456789012345",
      "ageMax": 44,
      "ageMin": 25,
      "budget": 2500,
      "campaignPlanId": "cpl_4e1a08",
      "channel": "meta",
      "countries": [
        "FR",
        "BE"
      ],
      "createdAt": 1768435200000,
      "createdBy": "usr_5d2b71",
      "effectiveEndDate": "2026-05-31",
      "effectiveStartDate": "2026-03-01",
      "endDate": null,
      "executable": true,
      "executions": [
        {
          "advertiserId": "acc_1203456789012345",
          "createdAt": 1772409600000,
          "entityId": "120210000000000",
          "entityType": "campaign",
          "id": "exe_7a4c12",
          "mutationId": "mut_k3x9q2v7m4n8p1r5t6w0y2z4",
          "provider": "meta"
        }
      ],
      "gender": "all",
      "id": "lni_2d9e77",
      "name": "France and Belgium, parents",
      "objective": "sales",
      "personaId": "psn_8c4a20",
      "provider": "meta",
      "revision": 2,
      "startDate": null,
      "status": "validated",
      "targetMetric": "cpa",
      "targetValue": 24.5,
      "unit": "total",
      "updatedAt": 1769040000000
    }
  ]
}
```
