CMS
Collections, entries, schemas, blocks, and media fields
The CMS module models content as collections and entries. A collection defines a block schema; each entry stores typed blocks validated by that schema. Taxonomies remain separate for classification and filtering.
Forms, taxonomies, and email templates have their own APIs. See Forms, Taxonomies, and Email Templates.
Collections
Collections are content tables. They define which blocks entries can store, including nested objects/lists and media references.
Create Collection
/v1/stores/{storeId}/collections sdk.cms.collection.create() const pages = await sdk.cms.collection.create({
store_id: storeId,
key: "pages",
schema: [
{
id: "title",
key: "title",
type: "localized_text",
required: true,
properties: {},
children: []
},
{
id: "body",
key: "body",
type: "markdown",
required: false,
properties: {},
children: []
}
]
});Parameters
| Name | Type | Description |
|---|---|---|
key required | string | Unique collection key |
schema optional | BlockSchema[] | Block types and constraints accepted by entries |
blocks optional | Block[] | Content stored directly on the collection |
List Collections
/v1/stores/{storeId}/collections sdk.cms.collection.find() const collections = await sdk.cms.collection.find({
store_id: storeId,
query: "pages",
limit: 20
});
Update Collection
/v1/stores/{storeId}/collections/{id} sdk.cms.collection.update() await sdk.cms.collection.update({
store_id: storeId,
id: "collection_xyz789",
schema: updatedSchema,
blocks: updatedBlocks
});
Delete Collection
/v1/stores/{storeId}/collections/{id} sdk.cms.collection.delete() await sdk.cms.collection.delete({ store_id: storeId, id: "collection_xyz789" });
Entries
Entries are content rows inside a collection. Entries do not have a first-class parent field; hierarchy and filtering stay in taxonomies for now.
Create Entry
/v1/stores/{storeId}/entries sdk.cms.entry.create() const homepage = await sdk.cms.entry.create({
store_id: storeId,
collection_id: pages.id,
key: "homepage",
slug: { en: "home" },
blocks: [
{
id: crypto.randomUUID(),
type: "localized_text",
key: "title",
properties: {},
value: { en: "Home" }
}
]
});Parameters
| Name | Type | Description |
|---|---|---|
collection_id required | string | Collection that owns the entry |
key required | string | Unique entry key inside the collection |
blocks optional | Block[] | Typed content validated against the collection schema |
slug optional | Record<string, string> | Localized URL-friendly slugs |
Get Entry
/v1/stores/{storeId}/entries/{id} sdk.cms.entry.get() const entry = await sdk.cms.entry.get({ store_id: storeId, id: "entry_xyz789" });
List Entries
/v1/stores/{storeId}/entries sdk.cms.entry.find() const pages = await sdk.cms.entry.find({
store_id: storeId,
collection_id: "collection_xyz789",
status: "active",
limit: 20
});
Update Entry
/v1/stores/{storeId}/entries/{id} sdk.cms.entry.update() await sdk.cms.entry.update({
store_id: storeId,
id: "entry_xyz789",
blocks: updatedBlocks
});
Delete Entry
/v1/stores/{storeId}/entries/{id} sdk.cms.entry.delete() await sdk.cms.entry.delete({ store_id: storeId, id: "entry_xyz789" });
References
Blocks can reference media, entry, product, and digital_product records by ID. Responses keep those IDs instead of implicitly fetching nested objects. This keeps every collection and entry read bounded.
Fetch the referenced records explicitly, once per type:
import { collectBlockReferences } from "arky-sdk";
const references = collectBlockReferences(homepage.blocks);
const { data: media } = await arky.cms.media.findByIds({
ids: references.mediaIds
});
const { data: entries } = await arky.cms.entry.findByIds({
ids: references.entryIds
});
Relationship schemas may set on_delete to restrict or set_null. An entry schema may also set collection_id to constrain the referenced entry’s collection.