# Search competitors

Search the stored iOS competitor catalogue with bounded, cursor-based filters.

## Endpoint: GET /v1/competitors

- Method: `GET`
- Path: `/v1/competitors`
- Authentication: Bearer API credential or OAuth access token
- Required scope: `context:read`
- MCP tool: `search_apps`
- MCP action: `search`

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `search` | query | string, max 120 | no | Names starting with the text come first, then names holding every word, then descriptions holding every word. Words match whole, singular or plural. |
| `category` | query | string, 1–120 | no | Exact catalogue category filter. |
| `platform` | query | ios | no | The preview supports iOS only. |
| `cursor` | query | opaque string | no | Cursor returned by the previous page. |
| `limit` | query | integer, 1–100 | no | Page size; defaults to 24. |

## 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

Send filters as query parameters. Keep them unchanged when following an opaque cursor.

```
curl --get 'https://api.peekpanda.com/v1/competitors' \
  --header "Authorization: Bearer $PEEKPANDA_TOKEN" \
  --header 'x-genviral-tenancy: personal' \
  --data-urlencode 'platform=ios' \
  --data-urlencode 'search=calorie tracker' \
  --data-urlencode 'limit=24'
```

## MCP request

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

```
{
  "name": "search_apps",
  "arguments": {
    "request": {
      "action": "search"
    }
  }
}

```

## Response

Paginated catalogue listings. 0000000000 is a synthetic valid-format store ID. Show currentFacts: each value names its provenance, observed from an App Store storefront or the catalogue snapshot, and its own asOf date. The top-level appName, rating, totalRatings and price keep the dated snapshot values.

```
{
  "data": [
    {
      "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"
        }
      }
    }
  ],
  "pagination": {
    "nextCursor": null,
    "hasMore": false
  }
}

```

## Source

Dated public App Store listing observations. Installs, when present, are directional estimates rather than store-reported downloads.

## Refresh

Reads return stored observations. When newer listing data is requested, collection continues asynchronously.
