PeekPanda markpeekpandaDocumentation
For your AI
Dashboard

Pull new competitor ads on a schedule

Check your competitors for newly found paid ads on a timer, read only what is new since the last run, and transcribe the video ads.

Download Markdown ↓

A scheduled job, a cron script or an agent on a timer can ask PeekPanda one question every run: which ads did you find for these apps since I last looked? The loop below reads stored observations only. It never asks PeekPanda to collect new ads, so it is cheap and safe to repeat.

What you need

  • An API key from /account, or an MCP client that is signed in. See API keys.
  • The App Store ids of the apps you follow, up to 25 per request.
  • One place to remember a single value between runs: the newest discoveredAt you have read.

The loop

  1. Read the value you stored last time. On the very first run there is none, so leave discoveredAfter out.
  2. Call GET /v1/paid-ads with storeIds, sort=recently_discovered and, when you have one, discoveredAfter set to the stored value.
  3. Follow nextCursor while hasMore is true. Keep every other filter and the sort unchanged between pages.
  4. Process the new items. Each one is an ad PeekPanda first recorded after your stored instant.
  5. Store the newest discoveredAt from this run. Only replace the stored value once the run has finished, so a failed run is simply read again next time.
bash
curl --get https://api.peekpanda.com/v1/paid-ads \
  -H "Authorization: Bearer $PEEKPANDA_API_KEY" \
  --data-urlencode 'storeIds=6480417616,1234567890' \
  --data-urlencode 'sort=recently_discovered' \
  --data-urlencode 'discoveredAfter=2026-10-05T06:00:00Z' \
  --data-urlencode 'limit=40'

discoveredAfter is strict: an ad recorded at exactly the stored instant is not returned again. discoveredAt is when PeekPanda first recorded the ad, not when the advertiser started running it. Use startedAt for that, where the source discloses it.

storeIds returns only ads verified to link to those apps. To follow one advertiser instead, pass advertiserExternalId with its exact page id.

The same loop through MCP

An agent makes the same read with the get_ads tool and the search action. The query takes the same names as the HTTP request.

json
{
  "name": "get_ads",
  "arguments": {
    "request": {
      "action": "search",
      "query": {
        "storeIds": "6480417616,1234567890",
        "sort": "recently_discovered",
        "discoveredAfter": "2026-10-05T06:00:00Z",
        "limit": 40
      }
    }
  }
}

Transcribing the video ads

Only video ads have speech to transcribe. For each new item whose creative.format is video, call POST /v1/paid-ads/{platform}/{archiveId}/transcript, taking the platform and archive id from the item. Through MCP, use the refresh tool with the ad_transcript action and pass platform and archiveId in params.

bash
curl -X POST https://api.peekpanda.com/v1/paid-ads/meta/1234567890123456/transcript \
  -H "Authorization: Bearer $PEEKPANDA_API_KEY"
  • A transcript that is already ready comes back from storage, so asking twice is safe.
  • 409 means a transcript for that ad is being generated right now. Leave it and try again on the next run.
  • 422 means the ad has no stored video, for example an image-only ad. Do not retry it.

Transcribing uses the content:write scope. The search itself only needs context:read.

Fitting it in your daily allowance

Every API request and every MCP call counts toward your plan's daily allowance, which resets at 00:00 UTC. Your plan's figure is on /account and in Usage and limits. Budget one run like this:

calls per run = pages read + video ads transcribed

calls per day = runs per day × calls per run

Keep calls per day under your allowance with room for the rest of your work. Two ways to stay inside it: run less often, since the loop never misses an ad between runs, and transcribe only the video ads you will actually read. If you do run out, the API answers 429 with daily_call_limit until the reset.

AI agent or LLM? Read this page as markdown