> ## Documentation Index
> Fetch the complete documentation index at: https://docs.trychannel3.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Collections

A **collection** is a catalog you curate yourself — brands, websites, categories, and specific products you pick. Create it once, then search, browse, and chat inside it by passing `config.collection_id`.

Creating and managing collections is **free**.

## What's in a collection

Each collection is made of one or more **clauses**. Inside a clause, fill in any of:

* **Any of these brands** (`brand_ids`)
* **Any of these websites** (`website_ids`)
* **Any of these categories** (`category_ids`)
* **Any of these products** (`product_ids`)

Let's walk through an example. You want Nike running shoes. That's one clause: Nike under brands, running shoes under categories.

```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { Channel3 } from "@channel3/sdk";

const client = new Channel3();

const brands = await client.brands.search({ query: "Nike" });
const nikeId = brands.brands[0].id;

const collection = await client.collections.create({
  name: "Nike running",
  clauses: [
    {
      brand_ids: [nikeId],
      category_ids: ["running-shoes"],
    },
  ],
});
```

```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from channel3_sdk import Channel3

client = Channel3()

brands = client.brands.search(query="Nike")
nike_id = brands.brands[0].id

collection = client.collections.create(
    name="Nike running",
    clauses=[
        {
            "brand_ids": [nike_id],
            "category_ids": ["running-shoes"],
        }
    ],
)
```

```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -X POST https://api.trychannel3.com/v1/collections \
  -H "x-api-key: $CHANNEL3_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Nike running",
    "clauses": [
      {
        "brand_ids": ["brand_nike_abc123"],
        "category_ids": ["running-shoes"]
      }
    ]
  }'
```

Search inside that collection and you'll only get Nike products in running shoes — not all Nike, and not running shoes from other brands.

```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
const results = await client.products.search({
  query: "trail runners",
  config: { collection_id: collection.collection_id },
});
```

```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
results = client.products.search(
    query="trail runners",
    config={"collection_id": collection.collection_id},
)
```

```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -X POST https://api.trychannel3.com/v1/search \
  -H "x-api-key: $CHANNEL3_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "trail runners",
    "config": { "collection_id": "COLLECTION_ID" }
  }'
```

Want REI too? Adding a clause and adding to a clause give different results.

> **Add a clause**
>
> Nike running shoes **or** anything from REI.
>
> ```typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
> add_clauses: [
>   { website_ids: ["rei.com"] },
> ]
> ```

> **Add to the clause**
>
> Only Nike running shoes, and only from REI.
>
> ```typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
> replace_clauses: [{
>   clause_id,
>   brand_ids: [nikeId],
>   category_ids: ["running-shoes"],
>   website_ids: ["rei.com"],
> }]
> ```

Filters on a later search can only **narrow** what's already in the collection — they can't widen it. In the Nike running shoes collection:

```typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
// Narrows: Nike running shoes under $150
await client.products.search({
  query: "trail runners",
  filters: { price: { max_price: 150 } },
  config: { collection_id: collection.collection_id },
});

// Zero results: this asks for Nike (the collection) AND Adidas (the filter)
await client.products.search({
  query: "trail runners",
  filters: { brand_ids: [adidasId] },
  config: { collection_id: collection.collection_id },
});
```

> [!NOTE]
>
> A collection can have up to 100 clauses, 100 IDs in each list per clause, and
> 500 `product_ids` in total.

For websites, you can pass a merchant ID or a domain like `nike.com`.

You can create an empty collection (`clauses: []`) and add clauses later.

Optional `user_id` ties the collection to one of your users. If a later search uses this collection and you don't send `x-user-id`, Channel3 attributes clicks to that user.

## Search, browse, image search, and similar

Pass the ID on `config.collection_id`.

```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
const results = await client.products.search({
  query: "trail runners",
  config: { collection_id: collection.collection_id },
});

const grid = await client.products.browse({
  config: { collection_id: collection.collection_id },
});
```

```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
results = client.products.search(
    query="trail runners",
    config={"collection_id": collection.collection_id},
)

grid = client.products.browse(
    config={"collection_id": collection.collection_id},
)
```

```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -X POST https://api.trychannel3.com/v1/search \
  -H "x-api-key: $CHANNEL3_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "trail runners",
    "config": { "collection_id": "COLLECTION_ID" }
  }'
```

The same `config.collection_id` field works on [`POST /v1/image-search`](/api-reference/v1/image-search), [`POST /v1/similar`](/api-reference/v1/similar-products), and [`POST /experimental/find-products-in-image`](/api-reference/v1/find-products-in-image). A 404 means that ID doesn't exist. `/v1/lookup` doesn't take a collection.

## List collections

List is paginated. Pass `user_id` to see one user's collections.

```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
const page = await client.collections.list({ limit: 50 });

for (const item of page.items) {
  console.log(item.collection_id, item.name);
}

if (page.next_page_token) {
  const next = await client.collections.list({
    limit: 50,
    page_token: page.next_page_token,
  });
}
```

```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
page = client.collections.list(limit=50)

for item in page.items:
    print(item.collection_id, item.name)

if page.next_page_token:
    next_page = client.collections.list(
        limit=50,
        page_token=page.next_page_token,
    )
```

```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl "https://api.trychannel3.com/v1/collections?limit=50" \
  -H "x-api-key: $CHANNEL3_API_KEY"
```

## Get a collection

Fetch one collection by ID. The response includes name, description, `user_id`, and every clause.

```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
const collection = await client.collections.retrieve(collectionId);

console.log(collection.collection_id, collection.name);
console.log(collection.clauses);
```

```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
collection = client.collections.retrieve(collection_id)

print(collection.collection_id, collection.name)
print(collection.clauses)
```

```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl https://api.trychannel3.com/v1/collections/COLLECTION_ID \
  -H "x-api-key: $CHANNEL3_API_KEY"
```

A 404 means that ID doesn't exist.

## Update a collection

PATCH can replace a clause in place by `clause_id`, remove one, or add another clause.

```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
const updated = await client.collections.update(collection.collection_id, {
  add_clauses: [{ brand_ids: ["brand_adidas_abc"] }],
});
```

```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
updated = client.collections.update(
    collection.collection_id,
    add_clauses=[{"brand_ids": ["brand_adidas_abc"]}],
)
```

```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -X PATCH https://api.trychannel3.com/v1/collections/COLLECTION_ID \
  -H "x-api-key: $CHANNEL3_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "add_clauses": [{ "brand_ids": ["brand_adidas_abc"] }]
  }'
```

> **[Search](/guides/search)**
>
> Filters on a search can only narrow what the collection returns.

> **[Conversations](/conversations)**
>
> Bind a shopping chat to a collection.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.