PeekPanda markpeekpandaDocumentation
For your AI
Dashboard

Get market signals

Read chart, paid-ad, organic and keyword signals for up to 600 iOS apps in one batch.

Download Markdown ↓

GEThttps://api.peekpanda.com/v1/market/signals

Request

Send country and storeIds as query parameters. storeIds is one comma-separated value of numeric Apple store IDs; MCP clients may send an array instead. This GET never starts collection.

Parameters

NameInTypeRequiredDescription
countryquery^[a-z]{2}$NoApple storefront as two lowercase letters. Defaults to us.
storeIdsquerycomma-separated numeric IDs, 1–600 uniqueYesApple store IDs to annotate, such as the rows of one chart page. Duplicates are removed before the 600 limit applies.

Response

The response echoes the country and the eight weekly dates, says when keyword positions were observed and when organic views were counted, and lists apps keyed by storeId. Look entries up by storeId, not by position. Each app carries the name and 128px icon the market boards print; both are null when no stored fact names the app. placement, paid, organic and keywords are each null when that stream was never collected for the app, never zero. paidCollection says when the app’s paid ads were last collected: freshness is never (no collection has finished, so a null paid signal says nothing about the app’s ads), stale (the last collection is more than two days old) or fresh, the same words boards use, and lastCollectedAt is null until one has finished. A null paid signal with fresh collection means the app ran no ads PeekPanda could find. The second app in the example has no collected ads or organic posts.

Response fields

countrystring
weeks[]string[]
keywordsObservedAtstring
organicViewsCountedAtstring
apps[].storeIdstring
apps[].placement.ranknumber
apps[].placement.previousRanknumber
apps[].placement.chartTypestring
apps[].placement.categoryIdstring
apps[].placement.categoryNamestring
apps[].placement.daystring
apps[].paid.totalAdsnumber
apps[].paid.liveAdsnumber
apps[].paid.startedLast7Daysnumber
apps[].paid.medianDaysLivenumber
apps[].paid.longestDaysLivenumber
apps[].paid.formatsobject
apps[].paid.topCallToActionstring
apps[].paid.destinationsobject
apps[].paid.weeklyStarts[]number[]
apps[].organic.matchedPostsnumber
apps[].organic.viewsnumber
apps[].organic.medianViewsnumber
apps[].organic.bestPostViewsnumber
apps[].organic.postsOverMillionnumber
apps[].organic.newestPublishedAtstring
apps[].organic.platformsobject
apps[].organic.matchedBystring
apps[].keywords.rankednumber
apps[].keywords.top1number
apps[].keywords.top3number
apps[].keywords.top10number
apps[].keywords.top50number
apps[].keywords.bestobject
apps[].keywords.top[].querystring
apps[].keywords.top[].positionnumber
apps[].keywords.top[].popularitynumber
apps[].keywords.top[].popularityEstimatenull
apps[].namestring
apps[].iconUrlstring
apps[].paidCollection.freshnessstring
apps[].paidCollection.lastCollectedAtstring

Authentication

Requires Bearer API credential or OAuth access token. Scope context:read. MCP calls get_market with action signals.

Errors

400invalid_request for an unknown query parameter, an invalid country, or storeIds that are missing, non-numeric or more than 600 unique IDs.
401authentication_required for a missing or invalid credential.
402subscription_required when access is not entitled.
403authorization_required for a missing context:read scope or unavailable preview access.
429rate_limited; wait for the Retry-After seconds, then send the same request again.

MCP request

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

{
  "name": "get_market",
  "arguments": {
    "request": {
      "action": "signals",
      "query": {
        "storeIds": "<storeIds>"
      }
    }
  }
}

Source

placement is the best rank across every stored App Store chart of the storefront on the latest chart day, with the previous day’s rank. Paid ads are collected per chosen app, so an app without ads has not been collected. An ad counts for the app its own verified App Store link names, or for the app its proven advertiser page runs ads for, web funnels and Google Play links included; the paid pulse counts the same ads. destinations splits them into App Store, Play Store and web-funnel ads, and only App Store ads are counted as appStore. "Last 7 days" and run lengths are UTC calendar days. Its paid signal is null. Organic posts are matched by product name, not account ownership, and their views are as last counted. organicViewsCountedAt says when. Keyword positions are observed App Store search result positions, not search volume. Each signals keyword carries popularity, Apple's weekly search popularity (1 to 100), or null when Apple reports nothing. Where Apple reports nothing for a US keyword, popularityEstimate carries PeekPanda's own tier (very_low, low, medium or high) with estimatedAt and the modelTrainedAt of the weekly model behind it, never a number on Apple's scale. popularityEstimate is null whenever popularity is set and on every non-US storefront. Neither is a search count.

Refresh

This GET reads the same stored evidence as GET /v1/market/overview and never starts collection. To ask for paid-ad or organic evidence on one app, record a data request for that competitor.

Rate limits

Market reads share the standard read budget of 60 requests per minute with every other PeekPanda read. During the preview the count is kept per client network address, not per plan, and it resets at the end of each one-minute window. A 429 rate_limited response carries Retry-After when the server can say how long to wait: wait that many seconds, then send the same request again. Every call also counts toward your plan's daily API and MCP allowance: 30 calls a day on Peek and 1,000 on Panda, shared by every key and MCP connection on the plan and reset at 00:00 UTC. Past it, calls answer 429 daily_call_limit until the reset. Stored reads do not use your refresh allowance.

Batches

This read has no cursor. Send at most 600 unique store IDs per request and split a longer list into batches of 600. Each app carries at most 5 top keywords, and every weekly series has exactly 8 Monday-start weeks, oldest first, ending with the current, partial week.

AI agent or LLM? Read this page as markdown