---
title: line_item_record_execution
description: 'Record one provider object that a Line Item created, so that the Campaign Plan shows what came from where.'
---

Ask the agent to record which object on Meta came from which Line Item. Nothing records it for you, so the agent does it after each create.

> "Record the campaign that you just created against the Meta Line Item of the spring sale Campaign Plan."

When [`get_mutation_status`](/mcp/tools/get-mutation-status) gives the id of the new campaign, the agent calls `line_item_record_execution` with that id. Then, when you read the Campaign Plan, the Line Item shows the campaign in what it created. A second record of the same object adds nothing. The agent reports "3 objects created", and never "complete", because nobody declares how many objects a Line Item must create.

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

## Reference

Record one provider object this Line Item created — call it after each create, with the native provider id. Only you know which objects belong to which line, so nothing records this for you. Almost nothing is refused: the object already exists, and an unrecorded one is worse than a late record. Recording the same object twice is harmless. Note that "how many objects a line should produce" was never declared, so a surface can say "3 objects created" but never "complete".

### Input

| Argument | Type | Required | Description |
| --- | --- | --- | --- |
| `advertiser_id` | string | yes | The ad account the object was created in. |
| `campaign_plan_name` | string | yes | The Campaign Plan slug — its stable per-organization handle. |
| `entity_id` | string | yes | The native provider id, exactly as the provider returned it — unprefixed, which is what makes it match get_entity and list_entities. |
| `entity_type` | string | yes | The provider's own word for the level: campaign, adset, ad. Use the provider's vocabulary, not a normalized one. |
| `line_item_id` | string | yes | The Line Item id, as returned by campaign_plan_get. |
| `mutation_workflow_id` | string | no | The workflow id the create returned, when you have it. It links this record to the attempt without either duplicating the other. |
| `provider` | one of `meta`, `tiktok`, `snapchat`, `gads`, `dv360`, `x`, `openai` | yes |  |

### Output

A successful call returns this object in `structuredContent`.

| Field | Type | Always present | Description |
| --- | --- | --- | --- |
| `alreadyRecorded` | boolean | yes | `true` when the Line Item had a record of the same object. Then AdCrunch adds no record, and `execution` is the first one. |
| `execution` | object | yes | One provider object that the Line Item created. It is a fact, not a status: the object can be paused or archived since. |
| `execution.advertiserId` | string | yes | The ad account that holds the object, `acc_…`. |
| `execution.createdAt` | number | yes | When AdCrunch recorded the object, in milliseconds since the Unix epoch, UTC. |
| `execution.entityId` | string | yes | The id of the object on the provider, with no prefix. `get_entity` and `list_entities` use the same id. |
| `execution.entityType` | string | yes | The word of the provider for the level of the object, such as `campaign`, `adset` or `ad`. |
| `execution.id` | string | yes | The id of the record, `exe_…`. |
| `execution.mutationWorkflowId` | string or null | yes | The `workflowId` of the change that created the object, or `null` when the record names none. |
| `execution.provider` | one of `meta`, `gads`, `tiktok`, `x`, `openai`, `snapchat`, `dv360` | yes | The provider of the object. |

### 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`
- `advertiser_not_owned`
- `forbidden`
- `invalid_request`
- `internal_error`

### Scope

The token must hold `campaign_plan:write`. [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.

- **Writes.** The tool can change data.
- **Destructive.** The tool can make a change that you cannot undo. A client can ask you to confirm before it calls the tool.
- **Idempotent.** A second call with the same arguments changes nothing more.
- **Closed world.** The tool reads and writes the data of AdCrunch only.

### Example

The arguments:

```json
{
  "advertiser_id": "acc_1203456789012345",
  "campaign_plan_name": "spring-sale",
  "entity_id": "120210000000000",
  "entity_type": "campaign",
  "line_item_id": "lni_2d9e77",
  "mutation_workflow_id": "b3d1f0c4-6a2e-4a1f-9f77-2c0d1e5a8b94",
  "provider": "meta"
}
```

The result, in `structuredContent`:

```json
{
  "alreadyRecorded": false,
  "execution": {
    "advertiserId": "acc_1203456789012345",
    "createdAt": 1772409600000,
    "entityId": "120210000000000",
    "entityType": "campaign",
    "id": "exe_7a4c12",
    "mutationWorkflowId": "b3d1f0c4-6a2e-4a1f-9f77-2c0d1e5a8b94",
    "provider": "meta"
  }
}
```
