# Search paid ads

Search stored Meta and TikTok ad-library observations.

## Contract status

Preview contract: these routes and tools are implemented in the shared contract, but the public host, customer API access and OAuth flow have not been deployment verified.

## Endpoint: GET /v1/paid-ads

- Method: `GET`
- Path: `/v1/paid-ads`
- Authentication: Bearer API credential or OAuth access token
- Required scope: `context:read`
- MCP tool: `search_paid_ads`

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `cursor` | query | opaque string | no | Cursor returned by the previous page. |
| `limit` | query | integer, 1–40 | no | Page size; defaults to 18. |
| `search` | query | string, max 120 | no | Advertiser or creative search text. |
| `platform` | query | meta | tiktok | no | Advertising platform filter. |
| `status` | query | active | inactive | unknown | no | Observed ad status. |
| `advertiser` | query | string, max 120 | no | Advertiser name filter. |
| `format` | query | image | video | carousel | dynamic | unknown | no | Creative format filter. |
| `saved` | query | boolean | true | false | no | When true, only account-saved ads. |
| `sort` | query | recently_discovered | newest_started | highest_reported_reach | no | Defaults to recently_discovered. |

## 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.
- 404 not_found when the record is outside the accessible catalogue.
- 429 rate_limited; honor Retry-After when present.

## Request

Send peekPandaPaidAdQuerySchema filters as query parameters. This read does not collect new ads.

```
curl --get 'https://api.peekpanda.com/v1/paid-ads' \
  --header "Authorization: Bearer $PEEKPANDA_TOKEN" \
  --header 'x-genviral-tenancy: personal' \
  --data-urlencode 'platform=meta' \
  --data-urlencode 'limit=18' \
  --data-urlencode 'sort=recently_discovered'
```

## Response

items are stored paid-ad observations. canonicalKey matches paid:(meta|tiktok):{archiveId}. performance is unavailable or a reported_reach disclosure. There is no spend field.

```
{
  "items": [
    {
      "id": "33333333-3333-4333-8333-333333333333",
      "canonicalKey": "paid:meta:111222333",
      "source": "paid",
      "platform": "meta",
      "archiveId": "111222333",
      "advertiser": {
        "externalId": "444555666",
        "name": "Example Advertiser"
      },
      "status": "active",
      "startedAt": "2026-08-01T00:00:00.000Z",
      "endedAt": null,
      "discoveredAt": "2026-09-06T00:00:00.000Z",
      "sourceUrl": "https://www.facebook.com/ads/library?id=111222333",
      "creative": {
        "format": "video",
        "hook": "Turn saved recipes into a grocery list",
        "body": "Turn saved recipes into a grocery list.",
        "title": "Example Meal Planner",
        "description": null,
        "ctaText": "Download",
        "imageUrls": [
          "https://cdn.example.com/ad.jpg"
        ],
        "videoUrls": [
          "https://cdn.example.com/ad.mp4"
        ],
        "units": []
      },
      "productLink": {
        "kind": "official_domain",
        "name": "Example Meal Planner",
        "url": "https://example.com",
        "externalId": null,
        "confidence": "unresolved"
      },
      "productIconUrl": null,
      "performance": {
        "kind": "unavailable"
      },
      "saved": false
    }
  ],
  "nextCursor": null,
  "hasMore": false,
  "total": 1,
  "reportedReachCount": 0
}

```

## Source

Stored Meta/TikTok ad-library observations (scrapecreators or direct Meta). Not Apple. No spend field.

## Refresh

Paid-ad ingestion is a separate operator path; this GET is a stored read. Save/remove are account bookmarks.
