---
title: "List products"
method: GET
path: "/products"
---

# List products

`GET /products`

## Request

- Base URL: `https://www.merchkit.com/api/v1`
- URL: `https://www.merchkit.com/api/v1/products`
- Auth: HTTP bearer

Returns a paginated page of products in the one-map resource shape (system fields top-level, every customer key under `attributes`). Reference attributes embed COMPLETE as labeled stubs — no expansion calls; inverse-reference keys never appear (query the other side via filters, or page `/products/{id}/references`). Filter with `filter[<key>]=<value>` / `filter[<key>][<op>]=<value>` (see the `filter` parameter for the grammar), sort with `sort`, page with `limit`/`offset`, and narrow the returned keys with `fields=<key>,<key>`.

Scope: `read:products`.

## Query parameters

- `limit` integer
- `offset` integer
- `sort` string
- `filter` object
- `filter_join` 'and' | 'or'
- `fields` string

## Response `200`

A page of products.

- object
  - `data` EntityResource[]
    - `id` string, uuid, required
    - `type` 'product' | 'image' | 'vendor' | 'category' | 'source', required: The entity type discriminator.
    - `label` string, nullable, required: The workspace's primary-attribute value for this entity; null when no primary attribute is configured or it is unset (never a UUID posing as a name). Render `label ?? id`.
    - `parent_id` string, uuid, nullable, required: Parent entity id (products: the variant parent).
    - `created_at` string, date-time, nullable, required
    - `updated_at` string, date-time, nullable, required
    - `attributes` object, required: SPARSE map of customer-defined keys — only keys with values appear; a missing key means unset or not-applicable (read `attributes[key] ?? null`; never contains null or ""). Scalars are bare values; a single reference is a labeled stub; a list reference is a COMPLETE ordered stub array (no cap, array order = position order). Inverse-reference keys never appear — traverse them via filters or `/products/{id}/references`. The full key list comes from `GET /attributes`.
  - `pagination` Pagination
    - `total` integer
    - `limit` integer
    - `offset` integer: The exact requested offset, echoed back.
    - `has_more` boolean

## Other responses

- `400`: Invalid filter, sort, or paging parameter.

---

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