# Analyze paid-ad creative

Ask for creative analysis of one stored ad’s owned media; it runs in the background.

## Endpoint: POST /v1/paid-ads/{platform}/{archiveId}/analysis

- Method: `POST`
- Path: `/v1/paid-ads/{platform}/{archiveId}/analysis`
- Authentication: Bearer API credential or OAuth access token
- Required scope: `content:write`
- MCP tool: `refresh`
- MCP action: `ad_analysis`

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `platform` | path | meta | tiktok | yes | Advertising platform. |
| `archiveId` | path | string, 1–255 | yes | Provider archive id. |

## Known errors

- 400 invalid_request for an invalid filter, identity or limit.
- 401 authentication_required for a missing or invalid credential.
- 402 subscription_required when access is not entitled.
- 403 authorization_required for a missing scope or unavailable preview access.
- 403 workspace_not_accessible when x-genviral-tenancy names a workspace the credential cannot reach.
- 404 not_found when the record is outside the accessible catalogue.
- 429 rate_limited; honor Retry-After when present.
- 429 daily_call_limit; the plan's daily API and MCP calls are used until 00:00 UTC.
- 409 conflict when the write would duplicate an exclusive row.

## Request

The command has no request body and answers 202 at once: it stores the request and a background worker runs it, usually within a minute. Read where it stands with GET /v1/paid-ads/{platform}/{archiveId}/analysis every 15 to 30 seconds until status is ready or failed; each read counts toward the daily API and MCP call allowance. Asking again while it runs returns the same pending request, and a ready analysis is returned from storage without another run. A video analysis stored before timelines is regenerated to add one, and the stored analysis stays if that fails. It accepts mirrored image or video media up to 25 MB. For a video, the same run also generates and stores the transcript when it is missing; read it from GET /v1/paid-ads/{platform}/{archiveId}. A transcript that fails, or a video with no speech, does not fail the analysis.

```
curl --request POST 'https://api.peekpanda.com/v1/paid-ads/meta/111222333/analysis' \
  --header "Authorization: Bearer $PEEKPANDA_TOKEN" \
  --header 'x-genviral-tenancy: personal'
```

## MCP request

Call refresh with action ad_analysis. Path fields go in params, filters in query, and a write body in body.

```
{
  "name": "refresh",
  "arguments": {
    "request": {
      "action": "ad_analysis",
      "params": {
        "platform": "<platform>",
        "archiveId": "<archiveId>"
      }
    }
  }
}

```

## Response

Returns the analysis state: pending with requestedAt while the worker runs it, or ready with the stored analysis when one already exists.

```
{
  "status": "pending",
  "requestedAt": "2026-09-06T00:00:00.000Z"
}

```

## Source

Stored public advertising-library observations with source dates. Spend is unavailable unless the public record reports it.

## Refresh

An explicit request uses the owned mirror and persists its result. Repeating after settlement returns the stored result without generating it again.
