---
title: "Get a product"
method: GET
path: "/products/{id}"
tags: ["Products"]
---

# Get a product

`GET /products/{id}`

## Request

- Base URL: `https://api.privy.com/v1`
- URL: `https://api.privy.com/v1/products/{id}`
- Auth: HTTP bearer

Retrieve a single product from your connected store's catalog by its
store product id.

Includes detail fields not returned by the list endpoint: `description`,
`tags`, `options`, `image`, `images`, and `media`, plus per-variant
`barcode`, `inventory_policy`, `position`, `product_id`, `taxable`,
`image_id`, and `updated_at`.

Requires a connected Shopify or BigCommerce store — without one, this endpoint returns
`404 no_connected_store`.

The response shape is the same on both platforms; detail fields BigCommerce does
not supply (`media`, per-variant `inventory_policy`, `position`, `taxable`,
`image_id`, `updated_at`) are `null` or empty.

**Required scope:** `products_read`

## Path parameters

- `id` integer, required

## Headers

- `Privy-Account-Id` string

## Response `200`

The product.

- object
  - `data` ProductDetail: A product with the additional detail fields only returned by `GET /v1/products/{id}` (the list endpoint returns the leaner `Product` shape).
    - `id` integer: The store's product id. Use this value in `/v1/products/{id}`. Matches the product ids on order line items.
    - `title` string
    - `handle` string, nullable: The product's URL slug. `null` on BigCommerce products with no storefront path.
    - `status` 'active' | 'draft' | 'archived'
    - `product_type` string, nullable: The merchant-defined product category. Always `null` on BigCommerce stores.
    - `vendor` string, nullable: The product's vendor/brand. Always `null` on BigCommerce stores.
    - `url` string, nullable: The product's storefront URL. `null` if not published to the online store; always `null` on BigCommerce stores.
    - `image_url` string, nullable
    - `price_range` object, nullable
      - `min` string
      - `max` string
      - `currency_code` string
    - `total_inventory` integer, nullable: Total sellable inventory across variants. `null` when the store does not report it.
    - `tracks_inventory` boolean
    - `variants_count` integer, nullable: Total number of variants on the product (the `variants` array may be truncated below this).
    - `variants` object[]
      - `id` integer: The store's variant id.
      - `title` string, nullable: `null` on BigCommerce stores for a product's base variant (it has no option values); Shopify default variants carry "Default Title" instead.
      - `price` string, nullable: Variant price in the store's currency, as a decimal string.
      - `compare_at_price` string, nullable
      - `sku` string, nullable
      - `inventory_quantity` integer, nullable
      - `available` boolean: Whether the variant can currently be purchased (untracked inventory counts as available).
      - `barcode` string, nullable
      - `inventory_policy` 'deny' | 'continue' | 'null', nullable: Whether the variant can be sold when out of stock. Always `null` on BigCommerce stores.
      - `position` integer, nullable: The variant's position within the product. Always `null` on BigCommerce stores.
      - `product_id` integer: The store's id of the parent product.
      - `taxable` boolean, nullable: Always `null` on BigCommerce stores.
      - `image_id` integer, nullable: The store's id of the variant's image. `null` when the variant has no dedicated image.
      - `updated_at` string, date-time, nullable: Always `null` on BigCommerce stores.
    - `created_at` string, date-time
    - `updated_at` string, date-time
    - `description` string, nullable: The product description, as plain text.
    - `tags` string[]
    - `options` object[]: The product's option definitions (e.g. Size, Color).
      - `id` integer
      - `name` string
      - `position` integer
      - `values` string[]
    - `image` ProductImage
      - `id` integer, nullable: The store's image id.
      - `url` string
      - `alt_text` string, nullable
      - `width` integer, nullable
      - `height` integer, nullable
    - `images` ProductImage[]: All product images (up to 100).
      - `id` integer, nullable: The store's image id.
      - `url` string
      - `alt_text` string, nullable
      - `width` integer, nullable
      - `height` integer, nullable
    - `media` object[]: All product media — images, videos, 3D models (up to 100).
      - `id` integer
      - `media_content_type` 'image' | 'video' | 'external_video' | 'model_3d'
      - `alt` string, nullable
      - `preview_image_url` string, nullable

## Other responses

- `401`: Missing or invalid bearer token.
- `403`: `insufficient_scope` when the token lacks the required scope for this endpoint.
- `404`: The requested resource does not exist or does not belong to your account.
- `429`: Rate limit exceeded — either Privy's API rate limit (code `rate_limited`, with the `X-RateLimit-*` headers) or the connected store's own quota passed through (code `store_rate_limited`). `Retry-After` carries the wait when it is known — BigCommerce's reset window, or a wait derived from Shopify's throttle cost payload.
- `502`: The connected store's API could not be reached or returned an error. Retry shortly.

## Changes

- **2026-11-05** `cf0885e90d5a`: 10 warning
  - added the new `forbidden` enum value to the `error/code` response property for the response status `401`
  - added the new `forbidden` enum value to the `error/code` response property for the response status `403`
  - added the new `forbidden` enum value to the `error/code` response property for the response status `404`
  - added the new `forbidden` enum value to the `error/code` response property for the response status `429`
  - …6 more
- **2026-11-03** `fe500ab59b3b`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/privy/apis/privy-api/changes/products/:id/get.md)

---

[API](https://skmtc.dev/privy/apis/privy-api.md) - [All operations](https://skmtc.dev/privy/apis/privy-api/llms.txt) - [OpenAPI document](https://skmtc.dev/privy/apis/privy-api/revisions/bc29b48dcdd2?raw)
