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

# Activity and audit logs

> Review API calls and record changes for debugging, compliance and operational visibility.

Activity keeps two complementary records for your account:

* **Calls**: each admitted API request, REST or MCP, including reads, failures and denials, with its
  outcome, latency, workload and correlation ids.
* **Changes**: the meaningful create, update, delete, archive, execute, activate and deactivate actions
  on your records (advertisers, campaigns, creatives, media buys, packages, products, catalogs and more).

Use Calls to debug what an agent attempted. Use Changes to confirm what actually changed.

Both records are scoped to your account. Calls made through MCP and REST land in the same log.

## Open Activity in the app or in chat

In the app, open **Activity** and pick the **Calls** or **Changes** tab. Choose a period (**Today**,
**Last 7 days**, **Last 30 days**, **Last 90 days**, **Last 6 months** or **Last 1 year**), and on
Changes narrow by **Created**, **Updated**, **Removed**, **Activated** or **Deactivated**, and by
advertiser and campaign.

From an agent client, ask Semi to "show my API activity" or "show failed calls", or call `open_page`
with `page: "activity"` (pass `{ tab: "changes" }` to land on Changes).

## Changes: the audit feed

```bash theme={null}
curl "https://api.semicola.com/api/v2/buyer/audit-logs?limit=50" \
  -H "Authorization: Bearer $SEMICOLA_API_KEY" \
  -H "X-Account-Id: $ACCOUNT_ID"
```

```json theme={null}
{
  "data": [
    {
      "id": "…",
      "at": "2026-11-01T14:30:12.481Z",
      "actorKind": "user",
      "actorLabel": "Alex Operator",
      "actorOrigin": "human",
      "action": "UPDATE",
      "resourceType": "CAMPAIGN",
      "resourceId": "…",
      "resourceName": "Holiday Glaze Launch",
      "description": "Updated budget",
      "changedFields": [{ "field": "budget", "label": "Budget", "before": 20000, "after": 25000 }]
    }
  ],
  "error": null,
  "meta": { "pagination": { "nextCursor": null, "hasMore": false } }
}
```

Each row carries:

| Field                        | Notes                                                                                                                |
| ---------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| `id`, `at`                   | Row id and event time (ISO 8601, UTC).                                                                               |
| `actorKind`                  | Who acted: `user`, `agent`, `automation`, `buyer_agent` or `system`.                                                 |
| `actorLabel`                 | The person's name or the agent's name.                                                                               |
| `actorOrigin`                | How it was initiated: `human`, `agent` (Semi on that person's behalf), `autonomous` or `system`. Null on older rows. |
| `action`                     | `CREATE`, `UPDATE`, `DELETE`, `ARCHIVE`, `EXECUTE`, `ACTIVATE` or `DEACTIVATE`.                                      |
| `resourceType`               | For example `ADVERTISER`, `CAMPAIGN`, `CREATIVE`, `MEDIA_BUY`, `PACKAGE`, `PRODUCT` or `CATALOG`.                    |
| `resourceId`, `resourceName` | The record that changed and its label.                                                                               |
| `description`                | A one-line human summary.                                                                                            |
| `changedFields`              | Field-level `before` and `after` values, where the change has them.                                                  |

### Filters

| Query param    | Meaning                                                                 |
| -------------- | ----------------------------------------------------------------------- |
| `advertiserId` | Only changes for one advertiser.                                        |
| `resourceType` | One resource type, for example `MEDIA_BUY`.                             |
| `action`       | One action, for example `UPDATE`.                                       |
| `since`        | Only changes at or after this ISO 8601 time. Without it, the last year. |
| `limit`        | Rows per page, 1–200 (default 25).                                      |
| `cursor`       | The previous page's `nextCursor`.                                       |

Rows come newest first. Pass `meta.pagination.nextCursor` back as `cursor` until `hasMore` is `false`.
`resourceType` and `action` are applied before paging, so every page is full. A selection pages
through at most its 5,000 most recent changes; narrow it with `since` or the filters to reach older
ones. There's no campaign filter over REST; for one campaign and its media buys, use the **Activity**
page.

### Common questions

* **Who changed this campaign?** Open Activity → Changes, pick the advertiser and campaign, and read
  the actor on each row. The campaign filter includes the campaign's media buys.
* **What did this agent do today?** Pick **Today** and look for rows whose `actorKind` is `agent` or
  `buyer_agent`, or switch to Calls and read the **workload** column.
* **Did an incident leave a trace?** Filter by the resource type most likely to have caused it, then
  read `description` and `changedFields`.

### Semicola staff

Semicola staff can open your account to help with support. Their access is read-only: they can look,
but every change is refused, including through Semi and MCP tools. What they do shows in your Activity
under the actor **Semicola staff**, never a staff member's name:

* Opening your account shows as an `EXECUTE` change on `STAFF_ACCESS`: "Staff opened this account
  (platform administrator)", and "Staff started acting as a member of this account" when they view the
  app as one of your members.
* Account changes Semicola makes for you, such as granting or revoking beta feature access
  (`FEATURE_ENTITLEMENT`) or granting live eligibility, are listed the same way.
* Calls made while staff are in your account appear under **Calls** with the workload
  **Semicola staff**.

## Calls: the API call log

```bash theme={null}
curl "https://api.semicola.com/api/v2/activity/calls?outcome=failed&limit=50" \
  -H "Authorization: Bearer $SEMICOLA_API_KEY" \
  -H "X-Account-Id: $ACCOUNT_ID"
```

| Query param    | Meaning                                                                   |
| -------------- | ------------------------------------------------------------------------- |
| `startTime`    | Only calls at or after this time (ISO 8601). Defaults to the last 7 days. |
| `outcome`      | `succeeded`, `accepted`, `denied`, `failed`, `cancelled` or `unknown`.    |
| `advertiserId` | Only calls about one advertiser.                                          |
| `limit`        | 1–200 (default 50).                                                       |
| `cursor`       | The previous response's `nextCursor`.                                     |

Each call has an `id`, `at`, `operation`, `workload`, `surface` (`rest`, `mcp` or `a2a`), `outcome` and
`latencyMs`, plus `requestId`, `method`, `httpStatus`, `principalType` (`human`, `workload` or
`system`), `workloadName`, `traceId`, an `error` (`code`, `message`, `retryDisposition`) and
`detailAvailability` (`available`, `expired` or `not_captured`).

### Call detail

```bash theme={null}
curl "https://api.semicola.com/api/v2/activity/calls/$CALL_ID" \
  -H "Authorization: Bearer $SEMICOLA_API_KEY" \
  -H "X-Account-Id: $ACCOUNT_ID"
```

The detail adds the `routeTemplate`, the validation and response `steps`, the request JSON with
secret-looking fields removed (`redactedInput`), the error body for failures (`redactedOutput`), an
allow-list of non-secret headers (`safeHeaders`) and `detailExpiresAt`.

What we keep is deliberately narrow. Authorization headers, cookies and credentials are never stored,
and personal contact fields (email addresses, phone numbers) are removed from request JSON. The detail
expires 30 days after the call; the row's metadata and ids stay.

## Seller storefronts

Storefronts have the same two views:

* MCP: `list_storefront_activity` (`view` `changes` or `calls`, `period`, `filter`, `resourceId`,
  `outcome`, `cursor`) and `get_storefront_activity_call` for one call's detail.
* REST: `GET /api/v2/storefront/activity` (the full view, with `tab`, `period`, `filter`, `resourceId`,
  `outcome` and `cursor`), and `GET /api/v2/storefront/audit-logs` (Changes only: `period`, default
  `30d`; `resourceType`; `action`; `resourceId`; `limit` 1–200, default 50).

Storefront changes also cover storefront records: `STOREFRONT`, `STOREFRONT_INVENTORY_SOURCE`,
`ACCEPTANCE_POLICY`, `OPERATING_INSTRUCTIONS`, `RFP` and `APPROVAL`.

## Related

* [Diagnosing a stuck media buy](/guides/diagnosing-stuck-media-buys)
* [Tasks](/guides/tasks)
* [Errors](/v3/errors)
