Collections & pages
Two related surfaces: collections group products for merchandising;
pages are standalone CMS content (about, policies, landing copy). Both
follow the same status + archive conventions as the catalog. Examples reuse
the api() helper.
Collections
Read (public)
const collections = await api<Collection[]>("/public/collections"); // ACTIVE only
const collection = await api<Collection>("/public/collections/new-arrivals");
const itemsInIt = await api<Item[]>("/public/collections/new-arrivals/items");A collection that isn't ACTIVE reads as "no items" on the public surface —
archived items are hidden from the listing too.
Create & curate (merchant)
POST /merchant/collections — permission: catalog:write. Owner/Admin retain
broad access; Staff needs that group.
const collection = await api<Collection>("/merchant/collections", {
method: "POST",
token,
body: JSON.stringify({
name: "New Arrivals", // required
slug: "new-arrivals", // required, unique per tenant
status: "ACTIVE", // required: ACTIVE | DRAFT
description: "This season's fresh stock.",
}),
});
// Add items (already-present items are skipped, new ones appended):
await api(`/merchant/collections/${collection.id}/items`, {
method: "POST", token, body: JSON.stringify({ itemIds: ["id-a", "id-b"] }),
});
// Remove one (idempotent → { removed: 0 | 1 }):
await api(`/merchant/collections/${collection.id}/items/id-a`, {
method: "DELETE", token,
});
// Reorder items within the collection (send the full current set):
await api(`/merchant/collections/${collection.id}/items/order`, {
method: "PATCH", token, body: JSON.stringify({ itemIds: ["id-b", "id-c"] }),
});archive / restore and a collection-level order endpoint mirror the
catalog — same shapes, same "send the complete set" rule for reordering.
CMS pages
Pages use PUBLISHED | DRAFT (not ACTIVE). The public surface serves only
PUBLISHED; DRAFT and archived pages read as 404.
Read (public)
const pages = await api<Page[]>("/public/pages"); // PUBLISHED only
const page = await api<Page>("/public/pages/shipping-policy");Create (merchant)
POST /merchant/pages — permission: content:write. Owner/Admin retain broad
access; Staff needs that group.
await api<Page>("/merchant/pages", {
method: "POST",
token,
body: JSON.stringify({
title: "Shipping policy", // required
slug: "shipping-policy", // required, unique per tenant
content: "<h1>Shipping</h1>…", // required
status: "DRAFT", // required: PUBLISHED | DRAFT
excerpt: "How and when we ship.", // optional
}),
});PATCH /merchant/pages/:id updates; archive soft-deletes. Restoring a page
returns it as DRAFT (conservative — you re-publish explicitly) rather than
silently re-publishing.
Related
- Catalog: products & variants — the items collections group
- Media uploads — collection cover images