Send country, categoryId and chartType as query parameters. This GET reads stored evidence and never starts collection.
Parameters
NameInTypeRequiredDescription
countryquery^[a-z]{2}$NoApple storefront as two lowercase letters. Defaults to us.
categoryIdqueryall or digitsNoOverall or the Apple category for the selected chart. Defaults to all.
chartTypequeryfree | paid | grossingNoSelected chart type. Defaults to free.
Response
The response keeps the full chart-page fields, including history, coverage and freshness, for free, paid, grossing and a category-selected chart. For categoryId=all, viewChart is null because charts[chartType] is the selected chart already. It also includes the market overview and one signals batch for every app rendered. Each chart has at most 100 rows, so the response has at most 400 chart rows before duplicates; signals remain capped at 600 unique apps.
Response fields
projection.computedAtstring
projection.staleAtstring
projection.staleboolean
overview.countrystring
overview.chartobject
overview.weeks[]string[]
overview.pulseobject
overview.boardsobject
overview.searchesobject
overview.findingsobject
overview.suspects[].storeIdstring
overview.suspects[].namestring
overview.suspects[].iconUrlstring
overview.suspects[].categoryNamestring
overview.suspects[].boards[]string[]
overview.suspects[].placementobject
overview.suspects[].paidobject
overview.suspects[].organicobject
overview.suspects[].keywordsobject
charts.freeobject
charts.paidobject
charts.grossingobject
viewChart.queryobject
viewChart.coverageobject
viewChart.snapshotobject
viewChart.summaryobject
viewChart.insightsobject
viewChart.data[].storeIdstring
viewChart.data[].namestring
viewChart.data[].developerstring
viewChart.data[].iconUrlstring
viewChart.data[].appUrlstring
viewChart.data[].categoryIdstring
viewChart.data[].categoryNamestring
viewChart.data[].releaseDatestring
viewChart.data[].pricenumber
viewChart.data[].currencystring
viewChart.data[].ratingnumber
viewChart.data[].ratingCountnumber
viewChart.data[].metadataUpdatedAtstring
viewChart.data[].history[].daystring
viewChart.data[].history[].ranknumber
viewChart.data[].ranknumber
viewChart.data[].previousRanknumber
viewChart.data[].movementnumber
viewChart.data[].statusstring
viewChart.data[].inCatalogueboolean
viewChart.data[].estimatesobject
viewChart.updatedAtstring
signals.countrystring
signals.weeks[]string[]
signals.keywordsObservedAtstring
signals.organicViewsCountedAtstring
signals.apps[].storeIdstring
signals.apps[].placementobject
signals.apps[].paidobject
signals.apps[].organicobject
signals.apps[].keywordsobject
Authentication
Requires Bearer API credential or OAuth access token. Scope context:read. MCP calls get_market with action leaderboard.
Errors
400invalid_request for an unknown query parameter, invalid storefront, category or chart type.
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 leaderboard. Path fields go in params, filters in query, and a write body in body.
Chart placements come from dated public App Store chart observations. 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. Organic posts are matched by product name, not account ownership, and their views are as last counted. 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 stored evidence only. It combines existing chart, overview and bounded signal reads under one access check; it never calls Apple or an advertising library.
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.
Bounded response
Three overall charts and a category-selected chart carry at most 100 rows each. For categoryId=all, viewChart is null and the selected chart is charts[chartType], so it is sent once. Signals are deduplicated and capped at 600 app IDs. The endpoint has no cursor.