> For the complete documentation index, see [llms.txt](https://developers.flipsnack.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers.flipsnack.com/api-reference/collection.createcatalog.md).

# collection.createCatalog

Generates a product catalog by laying out feed products on templates.

Generation runs asynchronously. The call returns when the catalog is queued.

Poll [collection.getCollection](/api-reference/api-method-collection.getcollection.md) until the status changes.

For static template pages and blank spacers, use `collection.createFromTemplate`.

**Note:** Requests must be made to **<https://api.flipsnack.com/v1/>**.

### Request parameters

| Name                   | Type        | Description                                                                |
| ---------------------- | ----------- | -------------------------------------------------------------------------- |
| `apiKey` (required)    | string      | The API key provided for your user.                                        |
| `signature` (required) | string      | Request signature. See [How to sign a request](/how-to-sign-a-request.md). |
| `action` (required)    | string      | Must be `collection.createCatalog`.                                        |
| `sections` (required)  | JSON string | A JSON-encoded array of feed sections.                                     |
| `title`                | string      | Title of the generated catalog.                                            |
| `folder`               | string      | Destination folder path, such as `Catalogs/2026`.                          |

`sections` is a JSON-encoded string. This allows signatures over flat parameters.

### Sections

`sections` is a non-empty ordered array of feed section objects.

Only `sectionType: "feed"` is accepted.

#### Feed section fields

Feed sections lay out products from one or more feeds. Products can be grouped, sorted, and filtered.

| Field         | Type      | Required | Description                    |
| ------------- | --------- | -------- | ------------------------------ |
| `sectionType` | string    | Yes      | Must be `feed`.                |
| `sources`     | object\[] | Yes      | Product feeds.                 |
| `templates`   | object\[] | Yes      | Templates for product layout.  |
| `groupBy`     | object\[] | No       | Groups products before layout. |
| `sortBy`      | object\[] | No       | Orders products before layout. |
| `filters`     | object\[] | No       | Include or exclude rules.      |

**Sources**

| Field        | Type   | Required | Description               |
| ------------ | ------ | -------- | ------------------------- |
| `sourceHash` | string | Yes      | Hash of the product feed. |

**Templates**

| Field          | Type   | Required | Description                     |
| -------------- | ------ | -------- | ------------------------------- |
| `templateHash` | string | Yes      | Hash of the generator template. |

Only `templates[0]` is used for product layout. Use separate sections for different templates.

**Group products**

`groupBy` is evaluated in order. The first entry is the outermost group.

| Field       | Type    | Required | Description                                         |
| ----------- | ------- | -------- | --------------------------------------------------- |
| `field`     | string  | Yes      | Feed column used for grouping.                      |
| `pageBreak` | boolean | No       | Starts a new page for each value. Default: `false`. |

**Sort products**

`sortBy` is evaluated in order. The first entry is the primary sort key.

| Field   | Type                | Required | Description                                 |
| ------- | ------------------- | -------- | ------------------------------------------- |
| `field` | string              | Yes      | Feed column used for sorting.               |
| `order` | string or string\[] | Yes      | `asc`, `desc`, or custom field-value order. |

With custom order, unmatched products follow matched products in their relative order.

**Filters**

`filters` is an ordered array of filter blocks. `include` blocks narrow results. `exclude` blocks remove results.

| Field        | Type      | Required | Description                                |
| ------------ | --------- | -------- | ------------------------------------------ |
| `mode`       | string    | Yes      | `include` or `exclude`.                    |
| `match`      | string    | No       | `all` (AND) or `any` (OR). Default: `all`. |
| `conditions` | object\[] | Yes      | Conditions in this block.                  |

Each condition has these fields:

| Field      | Type   | Required | Description                                     |
| ---------- | ------ | -------- | ----------------------------------------------- |
| `field`    | string | Yes      | Feed column. Use `sku` to match SKUs.           |
| `operator` | string | Yes      | Matching operator. See [Operators](#operators). |
| `value`    | mixed  | Yes      | String, string array, or numeric-string range.  |

**Operators**

| Operator     | Value                        | Meaning                               |
| ------------ | ---------------------------- | ------------------------------------- |
| `in` / `nin` | string\[]                    | Included / excluded values.           |
| `eq` / `ne`  | string                       | Equal / not equal.                    |
| `lt` / `lte` | numeric string               | Less than / less than or equal.       |
| `gt` / `gte` | numeric string               | Greater than / greater than or equal. |
| `between`    | `[min, max]` numeric strings | Inclusive range.                      |
| `contains`   | string                       | Field contains the substring.         |

Numeric operators require numeric strings, such as `"100"`.

### Authentication

Sign each request with the secret key associated with `apiKey`:

1. Exclude `signature` from the request parameters.
2. Sort the remaining parameters alphabetically by key.
3. Concatenate them as `key1value1key2value2…`.
4. Prepend the secret key.
5. Generate the MD5 hash of the resulting string.

The `sections` value signs as one parameter value.

### Examples

#### Request

```
POST https://api.flipsnack.com/v1/

apiKey           = YOUR_API_KEY
signature        = 9f8b1c…              (MD5; see Authentication)
action           = collection.createCatalog
title            = My Catalog
folder           = Catalogs/2026
sections         = <JSON string below>
```

Use this `sections` array before URL or JSON encoding:

```json
[
  {
    "sectionType": "feed",
    "sources": [
      { "sourceHash": "abc123sourceHash" },
      { "sourceHash": "abc456sourceHash" }
    ],
    "templates": [
      { "templateHash": "tmplPhonesHash" }
    ],
    "groupBy": [
      { "field": "Categorias", "pageBreak": true },
      { "field": "Marcas", "pageBreak": true }
    ],
    "sortBy": [
      { "field": "Categorias", "order": "asc" },
      { "field": "Marcas", "order": "asc" },
      { "field": "storage", "order": "desc" }
    ],
    "filters": [
      {
        "mode": "include",
        "match": "all",
        "conditions": [
          { "field": "Categorias", "operator": "in", "value": ["Phones", "Tablets"] },
          { "field": "Marcas", "operator": "in", "value": ["Apple", "Samsung"] }
        ]
      },
      {
        "mode": "include",
        "match": "any",
        "conditions": [
          { "field": "Marcas", "operator": "eq", "value": "Xiaomi" },
          { "field": "Tags", "operator": "contains", "value": "featured" }
        ]
      },
      {
        "mode": "exclude",
        "conditions": [
          { "field": "Preț", "operator": "between", "value": ["100", "200"] },
          { "field": "stock", "operator": "lte", "value": "0" }
        ]
      },
      {
        "mode": "exclude",
        "conditions": [
          { "field": "sku", "operator": "in", "value": ["sku123", "456-asda-qwrf-qwe", "789"] }
        ]
      }
    ]
  },
  {
    "sectionType": "feed",
    "sources": [{ "sourceHash": "abc123sourceHash" }],
    "templates": [{ "templateHash": "tmplLaptopsHash" }],
    "filters": [
      {
        "mode": "include",
        "conditions": [
          { "field": "Categorias", "operator": "in", "value": ["Laptops"] }
        ]
      }
    ]
  },
  {
    "sectionType": "feed",
    "sources": [{ "sourceHash": "abc123sourceHash" }],
    "templates": [{ "templateHash": "tmplDefault2Hash" }],
    "filters": [
      {
        "mode": "exclude",
        "conditions": [
          { "field": "Categorias", "operator": "in", "value": ["Laptops", "Phones", "Tablets"] }
        ]
      }
    ]
  }
]
```

### Response parameters

The response returns the new catalog hash. Generation continues in the background.

| Name             | Type   | Description                                                                                                                          |
| ---------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------ |
| `collectionHash` | string | Hash of the newly created catalog. Use it to poll [collection.getCollection](/api-reference/api-method-collection.getcollection.md). |

```json
{
  "code": 20,
  "status": "OK",
  "data": {
    "collectionHash": "newHash123"
  }
}
```

Poll [collection.getCollection](/api-reference/api-method-collection.getcollection.md) using the returned `collectionHash`.

### Error codes

See [API status codes](/api-status-codes.md) for all error codes.

Validation failures (`code` `40`) can include `data.message` and `data.errors`.

```json
{
  "code": 40,
  "status": "Bad Request",
  "data": {
    "message": "Validation errors",
    "errors": [
      "sections[0].sources: must be provided."
    ]
  }
}
```
