Public Alpha. Easel is in early development, so expect rough edges.

Easel

← API Documentation

Collections API

Manage collections for a site. A collection groups products and has its own
slug on the storefront. A collection also has an optional plain-text
description that is shown on its storefront page. Tags attached to a
collection can drive navigation.

Every site also has two automatic collections, New Arrivals and Best Sellers,
which Easel fills itself. They appear in the list like any other collection,
but can't be updated, deleted, or tagged.

Endpoints

Collections:

Collection tags:

Tags themselves are managed with the Tags endpoints.


List Collections

Retrieve the collections for a site, each with its tags. This endpoint is not
paginated, since a site holds at most 500 collections.

Endpoint: GET /api/v1/sites/{site_id}/collections/

Scope Required: collections:read

Request

curl -X GET "https://studio.easel.engineering/api/v1/sites/sit_d0b6fmv28q6vn14peun0/collections/" \
  -H "Authorization: Bearer your_api_key_here"

Response

Status: 200 OK

{
  "data": [
    {
      "id": "col_d0b6fmv28q6vn14peun0",
      "name": "Summer",
      "description": "Summer picks for the patio.",
      "slug": "summer",
      "tags": [
        {
          "id": "ctg_d0b6fmv28q6vn14peun0",
          "tag": {
            "id": "tag_d0b6fmv28q6vn14peun0",
            "name": "Outdoor"
          }
        }
      ],
      "created_at": "2023-01-01T10:00:00Z",
      "updated_at": "2023-01-01T10:00:00Z",
      "external_source": null,
      "external_id": null,
      "taken_down_at": null
    }
  ]
}

Create Collection

Create a collection for a site. The slug is generated from the name. A site
holds at most 500 collections; creating one past that returns
INVALID_FIELD. A name already used by another collection on the site,
including Best Sellers and New Arrivals, returns 409 Conflict with
DUPLICATE.

Endpoint: POST /api/v1/sites/{site_id}/collections/

Scope Required: collections:write

Request Body

{
  "name": "Summer",
  "description": "Summer picks for the patio."
}
Field Type Required Description
name string Yes Collection name
description string No Plain-text collection description
external_source string No System the record was imported from; requires external_id (see External References)
external_id string No Record's ID in that system; requires external_source

Request

curl -X POST "https://studio.easel.engineering/api/v1/sites/sit_d0b6fmv28q6vn14peun0/collections/" \
  -H "Authorization: Bearer your_api_key_here" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: unique-request-id-12345" \
  -d '{"name": "Summer", "description": "Summer picks for the patio."}'

Response

Status: 201 Created

{
  "id": "col_d0b6fmv28q6vn14peun0"
}

Get Collection

Retrieve a single collection, including its tags.

Endpoint: GET /api/v1/sites/{site_id}/collections/{collection_id}/

Scope Required: collections:read

Request

curl -X GET "https://studio.easel.engineering/api/v1/sites/sit_d0b6fmv28q6vn14peun0/collections/col_d0b6fmv28q6vn14peun0/" \
  -H "Authorization: Bearer your_api_key_here"

Response

Status: 200 OK

{
  "id": "col_d0b6fmv28q6vn14peun0",
  "name": "Summer",
  "description": "Summer picks for the patio.",
  "slug": "summer",
  "tags": [
    {
      "id": "ctg_d0b6fmv28q6vn14peun0",
      "tag": {
        "id": "tag_d0b6fmv28q6vn14peun0",
        "name": "Summer"
      }
    }
  ],
  "created_at": "2023-01-01T10:00:00Z",
  "updated_at": "2023-01-01T10:00:00Z",
  "external_source": null,
  "external_id": null,
  "taken_down_at": null
}

Update Collection

Update a collection's name or description. The slug is not changed. Send an
empty description to clear it.

Endpoint: PUT /api/v1/sites/{site_id}/collections/{collection_id}/

Scope Required: collections:write

Request Body

{
  "name": "Summer 2024",
  "description": "Updated summer picks for the patio."
}

Fields

Field Type Required Description
name string Yes Collection name
description string No Plain-text collection description

Request

curl -X PUT "https://studio.easel.engineering/api/v1/sites/sit_d0b6fmv28q6vn14peun0/collections/col_d0b6fmv28q6vn14peun0/" \
  -H "Authorization: Bearer your_api_key_here" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: unique-request-id-67890" \
  -d '{"name": "Summer 2024", "description": "Updated summer picks for the patio."}'

Response

Status: 204 No Content

Error Responses

Automatic collection

New Arrivals and Best Sellers can't be changed.

Status: 409 Conflict

{
  "error": "New Arrivals and Best Sellers are managed automatically and cannot be changed",
  "code": "SYSTEM_COLLECTION"
}

Delete Collection

Delete a collection.

Endpoint: DELETE /api/v1/sites/{site_id}/collections/{collection_id}/

Scope Required: collections:write

Request

curl -X DELETE "https://studio.easel.engineering/api/v1/sites/sit_d0b6fmv28q6vn14peun0/collections/col_d0b6fmv28q6vn14peun0/" \
  -H "Authorization: Bearer your_api_key_here"

Response

Status: 204 No Content

Error Responses

Automatic collection

New Arrivals and Best Sellers can't be deleted.

Status: 409 Conflict

{
  "error": "New Arrivals and Best Sellers are managed automatically and cannot be changed",
  "code": "SYSTEM_COLLECTION"
}

List Collection Tags

Retrieve the tags attached to a collection.

Endpoint: GET /api/v1/sites/{site_id}/collections/{collection_id}/tags/

Scope Required: collections:read

Request

curl -X GET "https://studio.easel.engineering/api/v1/sites/sit_d0b6fmv28q6vn14peun0/collections/col_d0b6fmv28q6vn14peun0/tags/" \
  -H "Authorization: Bearer your_api_key_here"

Response

Status: 200 OK

{
  "data": [
    {
      "id": "ctg_d0b6fmv28q6vn14peun0",
      "tag": {
        "id": "tag_d0b6fmv28q6vn14peun0",
        "name": "Summer"
      }
    }
  ]
}

Add Collection Tag

Attach an existing tag to a collection.

Endpoint: POST /api/v1/sites/{site_id}/collections/{collection_id}/tags/

Scope Required: collections:write

Request Body

{
  "tag_id": "tag_d0b6fmv28q6vn14peun0"
}

Request

curl -X POST "https://studio.easel.engineering/api/v1/sites/sit_d0b6fmv28q6vn14peun0/collections/col_d0b6fmv28q6vn14peun0/tags/" \
  -H "Authorization: Bearer your_api_key_here" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: unique-request-id-13579" \
  -d '{"tag_id": "tag_d0b6fmv28q6vn14peun0"}'

Response

Status: 201 Created

Error Responses

Automatic collection

New Arrivals and Best Sellers choose their own products, so they can't be
tagged.

Status: 409 Conflict

{
  "error": "New Arrivals and Best Sellers are managed automatically and cannot be changed",
  "code": "SYSTEM_COLLECTION"
}

The response body is empty.


Delete Collection Tag

Detach a tag from a collection.

Endpoint: DELETE /api/v1/sites/{site_id}/collections/{collection_id}/tags/{tag_id}/

Scope Required: collections:write

Request

curl -X DELETE "https://studio.easel.engineering/api/v1/sites/sit_d0b6fmv28q6vn14peun0/collections/col_d0b6fmv28q6vn14peun0/tags/tag_d0b6fmv28q6vn14peun0/" \
  -H "Authorization: Bearer your_api_key_here"

Response

Status: 204 No Content


Collection Object

Fields

Field Type Description
id string Collection public ID
name string Collection name
description string Plain-text description shown on the storefront (empty when unset)
slug string Storefront slug
tags array Collection tags
created_at string ISO 8601 timestamp
updated_at string ISO 8601 timestamp
external_source string|null System the record was imported from (see External References)
external_id string|null Record's ID in that system
taken_down_at string|null ISO 8601 timestamp of when Easel took the collection down, or null while it hasn't. Read-only. See Takedowns

Takedowns

Easel hosts your store's content, so under the EU Digital Services Act its
staff may take a collection down that's illegal or against Easel's terms
(see Moderation), which sets its
taken_down_at. Until Easel restores it, the storefront leaves it out:
its page is not found and nothing links to it, though its products stay
on sale. You can still edit it, which asks Easel to review it again, or
reply to the email Easel sent the store's owners.

That email is the statement of reasons, and the dashboard keeps it under
Settings › Activity › Easel decisions. The activity log's taken_down
event names the category in reason.

Collection Tag Object

Fields

Field Type Description
id string Collection tag public ID
tag object The tag, with id and name