PeekPanda markpeekpandaDocumentation
For your AI
Dashboard

Get competitor case file

Read one competitor app’s whole overview in one request.

Download Markdown ↓

GEThttps://api.peekpanda.com/v1/competitors/{platform}/{storeId}/case-file

Request

Identify the listing and, optionally, the chart the standing is read from.

Parameters

NameInTypeRequiredDescription
platformpathiosYesThe preview supports iOS only.
storeIdpathnumeric stringYesApple App Store identifier.
countryquerytwo-letter storefront codeNoChart storefront; defaults to us.
categoryIdqueryall or App Store genre idNoChart category; defaults to all.
chartTypequeryfree, paid or grossingNoChart for the standing. When omitted, a priced app reads the paid chart and a free app the free chart.

Response

listing.currentFacts holds the name, rating, rating count and price to show, each with its provenance (observed from an App Store storefront, or the catalogue snapshot) and its own asOf date; the top-level listing fields keep the dated snapshot. paid is ready, updating (a rebuild is pending and nothing is stored yet), none (no paid evidence, with the reason) or unavailable (its read failed). A ready summary is read at request time over the last 7 days and 12 weeks, and its attribution splits the ads by basis. startedLast7Days counts ads that started on the reading day or the six UTC days before it; recentDays lays out those same seven days one by one, newest first, with quiet days as zero: newAds is how many ads started that day and liveAds how many of those are still live, and the seven newAds add up to startedLast7Days. weeklyStarts counts new ads per Monday week, oldest first, ending with the reading day’s own partial week. latestAds (newest first) and longestRunningAds (live ads with a start date, earliest start first, empty when none) use the Search paid ads item shape with short-lived media URLs. aso, estimates and rankStanding are null outside iOS; grossing is null when the chart is already grossing. listingHistory.storefronts lists every App Store storefront with an earlier iPhone screenshot set, the most recently changed first; each carries its currentScreenshotUrls and its earlier sets, most recently replaced first, with up to 12 earlier sets across all storefronts. PeekPanda keeps a set when a store lookup returns different iPhone screenshots: replacedAt is the lookup that first saw the new set and lastSeenAt the last lookup that still saw this one, so the developer changed the page between them. History starts at the first change PeekPanda saw. viewer is yours alone. See Section states for sections whose read failed.

Response fields

listing.platformstring
listing.storeIdstring
listing.appNamestring
listing.categorystring
listing.developerIdstring
listing.pricenumber
listing.adSupportednull
listing.inAppPurchasesboolean
listing.totalRatingsnumber
listing.ratingnumber
listing.installsobject
listing.releaseDatestring
listing.storeUpdatedAtstring
listing.sourceUpdatedAtstring
listing.descriptionUpdatedAtnull
listing.descriptionnull
listing.shortDescriptionnull
listing.sourcestring
listing.snapshotDatestring
listing.currentFactsobject
paid.kindstring
paid.summaryobject
paid.advertisers[].advertiserIdstring
paid.advertisers[].externalIdstring
paid.advertisers[].namestring
paid.advertisers[].totalAdsnumber
paid.advertisers[].liveAdsnumber
paid.latestAdsarray
paid.longestRunningAdsarray
paid.builtAtstring
paid.updatingnull
aso.positionKindstring
aso.storeIdstring
aso.countrystring
aso.languagestring
aso.sourcestring
aso.queriesMatchednumber
aso.summaryobject
aso.bestPositions[].querystring
aso.bestPositions[].positionnumber
aso.bestPositions[].popularitynumber
estimates.dataarray
rankStanding.countrystring
rankStanding.categoryIdstring
rankStanding.chartTypestring
rankStanding.chartobject
rankStanding.grossingnull
rankStanding.storefronts[].countrystring
rankStanding.storefronts[].daystring
rankStanding.storefronts[].ranknumber
listingHistory.storefronts[].countrystring
listingHistory.storefronts[].currentScreenshotUrls[]string[]
listingHistory.storefronts[].versions[].replacedAtstring
listingHistory.storefronts[].versions[].lastSeenAtstring
listingHistory.storefronts[].versions[].versionstring
listingHistory.storefronts[].versions[].screenshotUrls[]string[]
organic.matchedCountnumber
organic.candidateLimitReachedboolean
organic.latest[].sourceIdstring
organic.latest[].productNamestring
organic.latest[].captionstring
organic.latest[].linkstring
organic.latest[].datePublishedstring
organic.latest[].matchobject
viewer.canGenerateIntelligenceboolean
viewer.requestsobject

Authentication

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

Errors

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

MCP request

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

{
  "name": "get_app",
  "arguments": {
    "request": {
      "action": "case_file",
      "params": {
        "platform": "<platform>",
        "storeId": "<storeId>"
      }
    }
  }
}

Source

The stored per-app paid signal (an ad belongs to the app its own verified App Store link names, or to the app whose proven advertiser page ran it), current US App Store search observations, PeekPanda estimates, stored Apple chart snapshots and the public organic corpus. Missing evidence is null or none, never zero.

Refresh

This read returns stored observations and does not start collection.

Section states

Each section says why it holds no evidence. null means the section does not apply to this listing: aso, estimates, rankStanding and listingHistory are null outside iOS. none means PeekPanda holds no paid evidence for the app, with the reason. unavailable means the section could not be read for this request. It says nothing about the evidence itself, so retry later instead of reading it as empty. paid, aso, estimates, rankStanding, listingHistory, organic and viewer.requests can each be unavailable while the rest of the case file still answers; the listing is the only part whose failure fails the request. The example shows a case file whose paid, estimates, organic and request reads failed.

{
  "listing": {
    "platform": "ios",
    "storeId": "0000000000",
    "appName": "Example Calorie Tracker",
    "category": "Health & Fitness",
    "developerId": "example-developer",
    "price": 0,
    "adSupported": null,
    "inAppPurchases": true,
    "totalRatings": 12450,
    "rating": 4.7,
    "installs": {
      "kind": "ratings_proxy",
      "value": 622500
    },
    "releaseDate": "2024-05-01",
    "storeUpdatedAt": "2026-09-06",
    "sourceUpdatedAt": "2026-09-06",
    "descriptionUpdatedAt": null,
    "description": null,
    "shortDescription": null,
    "source": "itunes",
    "snapshotDate": "2026-03-01",
    "currentFacts": {
      "appName": {
        "provenance": "observed",
        "value": "Example Calorie Tracker",
        "asOf": "2026-09-06T00:00:00.000Z",
        "country": "us"
      },
      "rating": {
        "provenance": "observed",
        "value": 4.8,
        "asOf": "2026-09-06T00:00:00.000Z",
        "country": "us"
      },
      "totalRatings": {
        "provenance": "observed",
        "value": 13210,
        "asOf": "2026-09-06T00:00:00.000Z",
        "country": "us"
      },
      "price": {
        "provenance": "snapshot",
        "value": 0,
        "asOf": "2026-09-06"
      }
    }
  },
  "paid": {
    "kind": "unavailable"
  },
  "aso": {
    "positionKind": "observed_search_api_position",
    "storeId": "0000000000",
    "country": "us",
    "language": "en_us",
    "source": "itunes_search",
    "queriesMatched": 1,
    "summary": {
      "top3": 0,
      "top10": 1,
      "top50": 1,
      "bestPosition": {
        "query": "calorie tracker",
        "position": 4
      },
      "medianPosition": 4
    },
    "bestPositions": [
      {
        "query": "calorie tracker",
        "position": 4,
        "popularity": 63
      }
    ]
  },
  "estimates": {
    "kind": "unavailable"
  },
  "rankStanding": {
    "country": "us",
    "categoryId": "all",
    "chartType": "free",
    "chart": {
      "chartType": "free",
      "latest": {
        "day": "2026-09-06",
        "rank": 18
      },
      "previous": {
        "day": "2026-09-05",
        "rank": 21
      }
    },
    "grossing": null,
    "storefronts": [
      {
        "country": "us",
        "day": "2026-09-06",
        "rank": 18
      },
      {
        "country": "gb",
        "day": "2026-09-06",
        "rank": 33
      }
    ]
  },
  "listingHistory": {
    "storefronts": [
      {
        "country": "us",
        "currentScreenshotUrls": [
          "https://is1-ssl.mzstatic.com/image/thumb/example-now/392x696bb.jpg"
        ],
        "versions": [
          {
            "replacedAt": "2026-08-14T09:30:00.000Z",
            "lastSeenAt": "2026-08-13T09:30:00.000Z",
            "version": "4.1.3",
            "screenshotUrls": [
              "https://is1-ssl.mzstatic.com/image/thumb/example-old/392x696bb.jpg"
            ]
          }
        ]
      }
    ]
  },
  "organic": {
    "kind": "unavailable"
  },
  "viewer": {
    "canGenerateIntelligence": true,
    "requests": {
      "kind": "unavailable"
    }
  }
}

AI agent or LLM? Read this page as markdown