# Get an app developer

Read one iOS App Store developer and every app PeekPanda catalogues for it, with store facts, monthly download and revenue estimates and paid-ad counts, in one call.

## 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/developers/{platform}/{developerId}

- Method: `GET`
- Path: `/v1/developers/{platform}/{developerId}`
- Authentication: Bearer API credential or OAuth access token
- Required scope: `context:read`
- MCP tool: `search_apps`
- MCP action: `developer`

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `platform` | path | ios | yes | The preview supports iOS only. |
| `developerId` | path | numeric string, up to 20 digits | yes | Apple's numeric developer id: the developerId on a catalogue listing, or the number after id in an apps.apple.com/developer link. |

## 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.
- 403 workspace_not_accessible when x-genviral-tenancy names a workspace the credential cannot reach.
- 404 not_found when the record is outside the accessible catalogue.
- 429 rate_limited; honor Retry-After when present.
- 429 daily_call_limit; the plan's daily API and MCP calls are used until 00:00 UTC.

## Request

Pass Apple's numeric developer id in the path. Take it from the developerId on a catalogue listing, or from an App Store developer link: apps.apple.com/developer/example-labs/id1000000000 has developerId 1000000000. A developer is identified by this id, never matched by name. There is no query or body.

```
curl --get 'https://api.peekpanda.com/v1/developers/ios/1000000000' \
  --header "Authorization: Bearer $PEEKPANDA_TOKEN" \
  --header 'x-genviral-tenancy: personal'
```

## MCP request

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

```
{
  "name": "search_apps",
  "arguments": {
    "request": {
      "action": "developer",
      "params": {
        "platform": "<platform>",
        "developerId": "<developerId>"
      }
    }
  }
}

```

## Response

name is the seller name the App Store shows, or null until a storefront lookup has named the developer. apps come ordered by estimated revenue, then estimated downloads, then ratings. Each app has its store facts; storeStatus is listed, not_found when every observed storefront reported it missing, or unchecked before any lookup. monthlyInstalls and monthlyRevenue are the current worldwide monthly range (or below_floor under 5,000 a month) with the night it was scored, and previous is the estimate that held a month earlier. paidAds holds the stored paid-ad counts {liveAds, totalAds, builtAt}. An estimate or paidAds is null when PeekPanda holds none for the app: unknown, not zero. categories lists the served apps’ categories, most apps first, and topRevenueStoreId and topInstallsStoreId name the leading apps. history holds the developer’s daily totals for up to the last 90 scored days, oldest first and ending on the newest scored night. Each point applies the totals rule to the estimates in effect that day and carries the same counts, so when rangedApps rises from one day to the next, more apps were scored, which is not growth; a range is null on a day no app had one, and the list is empty until any app has been scored. A developer with no catalogued app answers 404 not_found.

```
{
  "platform": "ios",
  "developerId": "1000000000",
  "name": "Example Labs",
  "appCount": 2,
  "appsTruncated": false,
  "categories": [
    {
      "category": "health_and_fitness",
      "appCount": 2
    }
  ],
  "totals": {
    "monthlyInstalls": {
      "range": {
        "low": 62000,
        "mid": 130000,
        "high": 270000
      },
      "rangedApps": 1,
      "belowFloorApps": 1,
      "belowFloorCeiling": 5000,
      "unknownApps": 0
    },
    "monthlyRevenue": {
      "range": {
        "low": 140000,
        "mid": 290000,
        "high": 600000
      },
      "rangedApps": 1,
      "belowFloorApps": 0,
      "belowFloorCeiling": null,
      "unknownApps": 1
    },
    "liveAds": 18,
    "appsWithPaidAds": 1
  },
  "topInstallsStoreId": "0000000000",
  "topRevenueStoreId": "0000000000",
  "estimatesAsOf": "2026-10-15T00:00:00.000Z",
  "currency": "USD",
  "history": [
    {
      "day": "2026-10-13",
      "monthlyInstalls": {
        "range": {
          "low": 60000,
          "mid": 120000,
          "high": 250000
        },
        "rangedApps": 1,
        "belowFloorApps": 0,
        "belowFloorCeiling": null,
        "unknownApps": 1
      },
      "monthlyRevenue": {
        "range": {
          "low": 130000,
          "mid": 270000,
          "high": 560000
        },
        "rangedApps": 1,
        "belowFloorApps": 0,
        "belowFloorCeiling": null,
        "unknownApps": 1
      }
    },
    {
      "day": "2026-10-14",
      "monthlyInstalls": {
        "range": {
          "low": 60000,
          "mid": 120000,
          "high": 250000
        },
        "rangedApps": 1,
        "belowFloorApps": 1,
        "belowFloorCeiling": 5000,
        "unknownApps": 0
      },
      "monthlyRevenue": {
        "range": {
          "low": 130000,
          "mid": 270000,
          "high": 560000
        },
        "rangedApps": 1,
        "belowFloorApps": 0,
        "belowFloorCeiling": null,
        "unknownApps": 1
      }
    },
    {
      "day": "2026-10-15",
      "monthlyInstalls": {
        "range": {
          "low": 62000,
          "mid": 130000,
          "high": 270000
        },
        "rangedApps": 1,
        "belowFloorApps": 1,
        "belowFloorCeiling": 5000,
        "unknownApps": 0
      },
      "monthlyRevenue": {
        "range": {
          "low": 140000,
          "mid": 290000,
          "high": 600000
        },
        "rangedApps": 1,
        "belowFloorApps": 0,
        "belowFloorCeiling": null,
        "unknownApps": 1
      }
    }
  ],
  "apps": [
    {
      "storeId": "0000000000",
      "name": "Example Calorie Tracker",
      "iconUrl": null,
      "category": "health_and_fitness",
      "genre": "Health & Fitness",
      "price": 0,
      "formattedPrice": "Free",
      "inAppPurchases": true,
      "storeStatus": "listed",
      "rating": 4.7,
      "totalRatings": 12450,
      "releaseDate": "2024-05-01",
      "storeUpdatedAt": "2026-09-30",
      "monthlyInstalls": {
        "kind": "range",
        "scope": "worldwide",
        "range": {
          "low": 62000,
          "mid": 130000,
          "high": 270000
        },
        "observedAt": "2026-10-15T00:00:00.000Z",
        "previous": {
          "kind": "range",
          "scope": "worldwide",
          "range": {
            "low": 51000,
            "mid": 110000,
            "high": 220000
          },
          "observedAt": "2026-09-15T00:00:00.000Z"
        }
      },
      "monthlyRevenue": {
        "kind": "range",
        "scope": "worldwide",
        "range": {
          "low": 140000,
          "mid": 290000,
          "high": 600000
        },
        "observedAt": "2026-10-15T00:00:00.000Z",
        "previous": null
      },
      "paidAds": {
        "liveAds": 18,
        "totalAds": 64,
        "builtAt": "2026-10-15T03:00:00.000Z"
      }
    },
    {
      "storeId": "0000000001",
      "name": "Example Water Reminder",
      "iconUrl": null,
      "category": "health_and_fitness",
      "genre": "Health & Fitness",
      "price": 0,
      "formattedPrice": "Free",
      "inAppPurchases": true,
      "storeStatus": "listed",
      "rating": 4.5,
      "totalRatings": 860,
      "releaseDate": "2025-02-11",
      "storeUpdatedAt": "2026-08-19",
      "monthlyInstalls": {
        "kind": "below_floor",
        "scope": "worldwide",
        "ceiling": 5000,
        "observedAt": "2026-10-15T00:00:00.000Z",
        "previous": null
      },
      "monthlyRevenue": null,
      "paidAds": null
    }
  ]
}

```

## Source

Dated public App Store listing observations from the PeekPanda catalogue, with PeekPanda estimates refreshed nightly and stored paid-ad counts. An app belongs to the developer its storefront listing names, so an app transferred to another developer moves with it.

## Refresh

This read returns stored observations and estimates and does not start collection.

## App limit

One read serves at most 400 apps. A developer with more catalogued apps serves its 400 most-rated apps, appCount says how many apps the catalogue holds for it, and appsTruncated is true. There is no cursor.

## Totals

totals are computed over the served apps. monthlyInstalls.range and monthlyRevenue.range add up the ranges of the apps with a ranged estimate (rangedApps) and are null when none has one. Apps under the floor (belowFloorApps) and apps with no estimate (unknownApps) are counted apart, never folded into the sum, so a total covers only the scored apps it names. belowFloorCeiling is the level the below-floor apps sit under (5,000 a month today) and is null when belowFloorApps is 0. liveAds adds up the apps’ stored live-ad counts and appsWithPaidAds counts the apps with stored counts, even when none of their ads is live; an app without stored counts is unknown, not zero.

## Revenue scope

Estimates are App Store revenue only: worldwide monthly App Store figures in USD. Revenue earned outside the App Store, such as web checkout, is not included.

## Rate limits

This read uses the standard read budget; honor Retry-After on a 429 rate_limited response. 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.
