---
title: "/products"
method: GET
path: "/projects/{project_id}/products"
tags: ["Products"]
---

# /products

`GET /projects/{project_id}/products`

## Request

- Base URL: `https://api.productbyte.com/v1`
- URL: `https://api.productbyte.com/v1/projects/{project_id}/products`
- Auth: HTTP bearer

Lists the project’s catalogue, or searches it with `query`.

Paging is by page number, not cursor: the catalogue is a search index whose order changes as it re-indexes, and a cursor would silently skip rows across a re-index. Use `total` to size the walk.

Requires the `products:read` scope.

## Path parameters

- `project_id` string, required: The project whose catalogue to read.

## Query parameters

- `query` string: Match against product name, URL, and other indexed text.
- `page` integer, nullable: Page to return, counting from 0.
- `limit` integer: Page size, 1–100.
- `include_raw` boolean, nullable: Include each product’s `raw` fields. Off by default: a full page of catalogue documents is far larger than the named fields, and most callers never read them.

## Response `200`

A page of products.

- object
  - `products` object[], required: Products on this page.
    - `id` string, required: Identifier for this product.
    - `name` string: Product title.
    - `sku` string: The identifier your catalogue uses, when it has one.
    - `url` string: Link to the product page, when the catalogue provides one.
    - `price_cents` integer: Regular price in minor units — 2930 is €29.30. Minor units avoid rounding a decimal price.
    - `sale_price_cents` integer: Discounted price in minor units, when on offer.
    - `currency` string: Currency of the prices, as an ISO 4217 code.
    - `images` string[]: Product image URLs, primary first.
    - `raw` object: The fields your catalogue exported, exactly as they arrived — `stock_status`, `on_sale`, whatever your shop sends. Only present when the request asks for it with `include_raw`. **Not a contract.** The keys are your connector’s, not ProductByte’s: they differ per catalogue, change when your shop changes, and are not versioned with this API. Build on the named fields above; reach for `raw` when you need something they do not cover.
  - `total` integer, required: How many products match, across every page.
  - `page` integer, required: The page this is, counting from 0.

## Other responses

- `401`: Missing, unknown, revoked, or expired key (`API_KEY_UNAUTHORIZED`).
- `403`: The key lacks `products:read`, or the project is outside its allowlist.
- `429`: Too many requests for this key (`API_RATE_LIMITED`). Back off and retry; `Retry-After` gives the window length.
- `503`: The catalogue could not be reached (`API_PRODUCTS_UNAVAILABLE`). Retry; nothing is wrong with the request.

---

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