# Product schema (/docs/schema/product)



{/*
  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.
  */}

Product schema [#product-schema]

Every SocialCrawl endpoint that returns a product gives you this exact shape, whatever the source platform. Write your parser once and the same code reads product 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       | Platform product ID (Amazon ASIN / Google Shopping product id)            |
| `url`            | `string`             | Yes      | Direct URL to the product page                                            |
| `title`          | `string`             | Yes      | Product title                                                             |
| `description`    | `string`             | Yes      |                                                                           |
| `seller`         | `string`             | Yes      |                                                                           |
| `brand`          | `string`             | Yes      | Brand name (cleaned). Null when the platform exposes a seller instead.    |
| `price.current`  | `integer`            | Yes      |                                                                           |
| `price.original` | `integer`            | Yes      |                                                                           |
| `price.currency` | `string`             | Yes      |                                                                           |
| `rating.average` | `integer`            | Yes      |                                                                           |
| `rating.count`   | `integer`            | Yes      |                                                                           |
| `image_urls`     | `string or string[]` | Yes      | Primary image URL, or an array of image URLs for products with a gallery. |
| `availability`   | `string`             | Yes      | Stock/availability string when surfaced                                   |
| `reviews_count`  | `integer`            | Yes      |                                                                           |
| `features`       | `string[]`           | Yes      |                                                                           |
| `specifications` | `object[]`           | Yes      |                                                                           |
| `variations`     | `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.gid`                                                         | `string`   | Yes      |             |
| `ext.data_docid`                                                  | `string`   | Yes      |             |
| `ext.pvf`                                                         | `string`   | Yes      |             |
| `ext.seller_id`                                                   | `string`   | Yes      |             |
| `ext.sold_count`                                                  | `integer`  | Yes      |             |
| `ext.catalog_id`                                                  | `string`   | Yes      |             |
| `ext.requested_id`                                                | `string`   | Yes      |             |
| `ext.rating_distribution.star_1`                                  | `integer`  | Yes      |             |
| `ext.rating_distribution.star_2`                                  | `integer`  | Yes      |             |
| `ext.rating_distribution.star_3`                                  | `integer`  | Yes      |             |
| `ext.rating_distribution.star_4`                                  | `integer`  | Yes      |             |
| `ext.rating_distribution.star_5`                                  | `integer`  | Yes      |             |
| `ext.store_inventory`                                             | `object[]` | Yes      |             |
| `ext.condition`                                                   | `string`   | Yes      |             |
| `ext.available_quantity`                                          | `integer`  | Yes      |             |
| `ext.watchers`                                                    | `integer`  | Yes      |             |
| `ext.sold_at`                                                     | `string`   | Yes      |             |
| `ext.sold_caption`                                                | `string`   | Yes      |             |
| `ext.buying_format`                                               | `string`   | Yes      |             |
| `ext.seller_reputation.feedback_percentage`                       | `integer`  | Yes      |             |
| `ext.seller_reputation.feedback_count`                            | `integer`  | Yes      |             |
| `ext.seller_reputation.top_rated`                                 | `boolean`  | Yes      |             |
| `ext.seller_reputation.items_sold`                                | `integer`  | Yes      |             |
| `ext.seller_reputation.joined`                                    | `string`   | Yes      |             |
| `ext.seller_reputation.url`                                       | `string`   | Yes      |             |
| `ext.seller_reputation.detailed_ratings.accurate_description`     | `integer`  | Yes      |             |
| `ext.seller_reputation.detailed_ratings.reasonable_shipping_cost` | `integer`  | Yes      |             |
| `ext.seller_reputation.detailed_ratings.shipping_speed`           | `integer`  | Yes      |             |
| `ext.seller_reputation.detailed_ratings.communication`            | `integer`  | Yes      |             |

Platform availability [#platform-availability]

7 platforms return the `Product` shape. `id` 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        | `image_urls` | `seller` | `reviews_count` | `availability` | `features` | `price.currency` | `specifications` | `variations` |
  | --------------- | ------------ | -------- | --------------- | -------------- | ---------- | ---------------- | ---------------- | ------------ |
  | Amazon          | yes          |          |                 |                |            | yes              |                  |              |
  | eBay            |              | yes      | yes             |                |            | yes              |                  |              |
  | Google Shopping |              | yes      | yes             |                |            | yes              |                  |              |
  | Home Depot      | yes          |          | yes             |                | yes        | yes              |                  |              |
  | Target          |              |          | yes             |                |            |                  |                  |              |
  | TikTok Shop     | yes          | yes      | yes             |                |            | yes              |                  |              |
  | Walmart         | yes          | yes      |                 | yes            |            | yes              | yes              | yes          |
</div>

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

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

[`/schemas/product.json`](/schemas/product.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 `Product` / `ProductList` archetype return this shape:

[Amazon](/platforms/amazon) · [eBay](/platforms/ebay) · [Google Shopping](/platforms/google_shopping) · [Home Depot](/platforms/home_depot) · [Target](/platforms/target) · [TikTok Shop](/platforms/tiktokshop) · [Walmart](/platforms/walmart)

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