---
title: "List mutations"
method: GET
path: "/mutations"
tags: ["Mutations"]
---

# List mutations

`GET /mutations`

## Request

- Base URL: `https://api.adcrunch.dev`
- URL: `https://api.adcrunch.dev/mutations`
- Auth: HTTP bearer

Lists your organization's Mutations, newest first.

One page at a time: `limit` rows at most, 100 by default. When the answer holds `nextCursor`, more rows exist: send it back as `cursor` to get the next page. When it is absent, you have the last page. The cursor is opaque: send it back with no change, and do not build one.

A row that is still `running` is checked against the change itself as the page is read, so a Mutation that finished after its row was written shows its true outcome here.

This is the history read, and it needs `mutation:read`. Starting a Mutation and polling the one you started need `mutation:write`.

## Query parameters

- `cursor` string: 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, required: 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`.

## Response `200`

One page of Mutations, newest first. This one is the last page, so it carries no `nextCursor`.

- object
  - `data` object[], required
    - `action` unknown, required
    - `advertiserId` string, required: The advertiser that was changed.
    - `completedAt` number, nullable, required: When it finished, as a Unix timestamp in milliseconds. Null while it runs.
    - `createdAt` number, required: When it started, as a Unix timestamp in milliseconds.
    - `organizationId` string, required: The organization it belongs to.
    - `priorValue` object, nullable, required: The values that the change replaced, read from the provider just before the change. It uses the field names and the units of action, for example {"dailyBudget": 800}, {"status": "ACTIVE"}, {"bidStrategy": "COST_CAP", "costCap": 4}, {"startTime": "2026-10-01T00:00:00+0200", "endTime": null} or {"name": "Spring sale"}. To undo the change, send the same kind again with these values. A bid change on a campaign also gives the amount of each ad set in adsets: undo it on each ad set. A create and a copy have none.
    - `provider` string, required: The ad platform the advertiser belongs to. It is meta today.
    - `result` unknown, required
    - `status` 'running' | 'complete' | 'errored', required: How it ended, or that it has not.
    - `tool` string, required: Which action was asked for, for example meta_set_status. It is the kind of the action above.
    - `userId` string, required: Who asked for it.
    - `workflowId` string, required: The Mutation id. The same id POST /mutations returned.
  - `nextCursor` string: Send this value as `cursor` to get the next page. It is absent on the last page.

## Other responses

- `400`: The request does not match the schema of this operation: a field is missing or has the wrong type, or the body is not valid JSON. `error` is `invalid_request`, and `issues` names each field. Nothing was changed. Or AdCrunch cannot use the `cursor`: it cannot read it, or the cursor belongs to a different query. Then `error` is `invalid_cursor`. Send the `nextCursor` of the previous page with no change, or omit `cursor` to get the first page.
- `401`: No API key, or one that does not resolve. See the security scheme. `error` is `unauthorized`.
- `402`: The organization has no active subscription. An owner subscribes at `paywallUrl`. `error` is `organization_unentitled`.
- `403`: The caller does not hold `mutation:read`. `error` is `forbidden`.

---

[API](https://skmtc.dev/adcrunch/apis/adcrunch-api.md) · [All operations](https://skmtc.dev/adcrunch/apis/adcrunch-api/llms.txt) · [OpenAPI document](https://skmtc.dev/adcrunch/apis/adcrunch-api/revisions/a420ba80914f?raw)
