# App schema (/docs/schema/app)



{/*
  AUTO-GENERATED. Do not hand-edit.
  Source: packages/social-api/src/docs/generate-schema-pages.ts
  Regenerate with: pnpm -F @repo/social-api generate:docs
  Field tables derive from the canonical Zod schemas (packages/social-api/src/schemas/canonical.ts);
  availability + equivalence derive from the registry fieldMaps.
  */}

App schema [#app-schema]

Every SocialCrawl endpoint that returns a app-store listing gives you this exact shape, whatever the source platform. Write your parser once and the same code reads app data from every platform below. That is the unified schema: one contract instead of a dozen raw upstream formats.

Field reference [#field-reference]

| Field                | Type                | Nullable | Description                                                    |
| -------------------- | ------------------- | -------- | -------------------------------------------------------------- |
| `id`                 | `string`            | No       | Store app ID (Google Play package name / App Store numeric id) |
| `store`              | `string`            | No       | App marketplace ("google\_play" or "app\_store")               |
| `url`                | `string`            | Yes      |                                                                |
| `title`              | `string`            | Yes      | App title                                                      |
| `icon`               | `string`            | Yes      |                                                                |
| `description`        | `string`            | Yes      |                                                                |
| `developer.id`       | `string`            | Yes      |                                                                |
| `developer.name`     | `string`            | Yes      |                                                                |
| `developer.url`      | `string`            | Yes      |                                                                |
| `developer.email`    | `string`            | Yes      |                                                                |
| `developer.address`  | `string`            | Yes      |                                                                |
| `developer.website`  | `string`            | Yes      |                                                                |
| `rating.value`       | `integer`           | Yes      |                                                                |
| `rating.max`         | `integer`           | Yes      |                                                                |
| `rating.count`       | `integer`           | Yes      |                                                                |
| `price.current`      | `integer`           | Yes      |                                                                |
| `price.original`     | `integer`           | Yes      |                                                                |
| `price.currency`     | `string`            | Yes      |                                                                |
| `price.is_free`      | `boolean`           | Yes      |                                                                |
| `price.displayed`    | `string`            | Yes      |                                                                |
| `reviews_count`      | `integer`           | Yes      |                                                                |
| `category`           | `string`            | Yes      |                                                                |
| `categories`         | `string[]`          | Yes      |                                                                |
| `installs.display`   | `string`            | Yes      |                                                                |
| `installs.count`     | `integer`           | Yes      |                                                                |
| `version`            | `string`            | Yes      |                                                                |
| `minimum_os_version` | `string`            | Yes      |                                                                |
| `size`               | `string`            | Yes      |                                                                |
| `released_at`        | `string or integer` | Yes      | Union: string \| integer \| null                               |
| `updated_at`         | `string or integer` | Yes      | Union: string \| integer \| null                               |
| `update_notes`       | `string`            | Yes      |                                                                |
| `image_urls`         | `string[]`          | Yes      | Screenshot URLs                                                |
| `video_urls`         | `string[]`          | Yes      |                                                                |
| `languages`          | `string[]`          | Yes      |                                                                |
| `advisories`         | `string[]`          | Yes      | Apple age/content advisories (null on Google)                  |
| `genres`             | `string[]`          | Yes      | Google Play genres (null on Apple)                             |
| `tags`               | `string[]`          | Yes      |                                                                |
| `similar_apps`       | `object[]`          | Yes      |                                                                |
| `more_by_developer`  | `object[]`          | Yes      |                                                                |

Extension fields (`ext`) [#extension-fields-ext]

Platform-specific passthrough. Each field is present only on the platforms that expose it and is absent everywhere else, so treat every `ext.*` field as optional. These carry the richer, per-platform signals the unified leaves cannot hold, and the join keys that chain endpoints together.

| Field         | Type     | Nullable | Description |
| ------------- | -------- | -------- | ----------- |
| `ext.appdata` | `string` | Yes      |             |

Platform availability [#platform-availability]

2 platforms return the `App` shape. `id`, `store` are never null on any platform. The fields below vary: **yes** means the platform populates it (the value may still be null); a blank means the platform never provides it, so it is always null.

<div className="overflow-x-auto">
  | Platform        | `url` | `title` | `icon` | `description` | `developer.id` | `developer.name` | `developer.url` | `developer.email` | `developer.address` | `developer.website` | `rating.value` | `rating.max` |
  | --------------- | ----- | ------- | ------ | ------------- | -------------- | ---------------- | --------------- | ----------------- | ------------------- | ------------------- | -------------- | ------------ |
  | Apple App Store | yes   | yes     | yes    | yes           | yes            | yes              | yes             | yes               | yes                 | yes                 | yes            | yes          |
  | Google Play     | yes   | yes     | yes    | yes           | yes            | yes              | yes             | yes               | yes                 | yes                 | yes            | yes          |
</div>

Machine-readable schema [#machine-readable-schema]

Validate responses programmatically against the JSON Schema (2020-12):

[`/schemas/app.json`](/schemas/app.json)

Point a validator (Ajv, `jsonschema`, or your framework's) at that URL, or hand it to an agent so it can check the shape without a live call.

Returned by [#returned-by]

Endpoints with the `App` / `AppList` archetype return this shape:

[Apple App Store](/platforms/app_store) · [Google Play](/platforms/google_play)

See how the same fields map to each platform's raw upstream names in the [cross-platform field equivalence table](/docs/schema/field-equivalence).
