Studio Docs

When to Use

Explain API-authoring a composition vs UI authoring: the entry’s ui (zlib node tree) + data_sources shape, the six binding types, when this path fits. On-ramp before author-composition-via-api.

Use when the user asks “how do I create a composition via API”, “can I bulk-import compositions”, “what does Studio store in the entry”, “what’s the JSON shape of a composition”, or before invoking author-composition-via-api without context. Concept only: for the actual API authoring run author-composition-via-api. Do NOT use for UI authoring (use build-section / build-connected-template).

Auth preflight: settle the credential before the first API call. Resolve it OAuth-first per authenticate-cma: CS_OAUTH_ACCESS_TOKEN, else the Contentstack MCP’s stored session. Never ask the user for a session authtoken. If nothing resolves, or a refresh fails with 400 invalid_refresh_token, hand them ! CONTENTSTACK_REGION=<code> npx @contentstack/mcp --auth (it needs a TTY and a browser, so it cannot be run for them) and wait. 403 error_code 316 is a valid credential aimed at another org: fix the org or the api_key, do not re-authenticate.

What API-authoring a Composition Means

Two Ways to Author a Composition

Compositions live as entries in a Contentstack content type (the project’s compositions CT, typically <project>_compositions). There are two paths to create those entries:

PathToolWhen to use
UI authoring (default)Studio canvas: drag, drop, bind via Data Picker, Save, DeployEvery author-driven workflow. Authors use it. Engineers use it for ad hoc composition.
API authoring (headless)CMA POST /v3/.../entries with a hand-built ui payloadSeed pipelines, scripted provisioning, automated migration, debugging via diff, bulk import

API authoring is NOT a replacement for the UI. The Data Picker handles every shape the API path describes. Reach for the API only when scripting at scale or seeding fixtures.

What’s in the Composition Entry

The compositions CT has 13 fields (full schema in provision-studio-project). The two that carry the composition itself:

  • ui: zlib:<base64>-encoded composition node tree. The whole layout (page, sections, components, repeaters, condition blocks, section slots) lives here as one inflated JSON tree.
  • data_sources: JSON object holding resolvedReferences (which fields to populate via CDA ?include[]=), the static-value map, and other resolution metadata.

Other fields (composable_uid, url, linked_schemas, linked_sections, url_metadata, etc.) are CT-level routing/metadata. The actual composition is in ui + data_sources.

The Six Binding Types

Studio’s Data Picker emits one of six binding shapes per bound prop, and these are the six an API author writes by hand:

TypeWhere the value comes fromCommon use
templateThe template’s preview entry (the page-level CT)entry.title, entry.hero.headline
repeaterThe current Repeater iteration iteminside a Repeater iterating entry.related_posts
contentstackA Pinned Entry on the template (Freeform must be on)dataSources.contentstack.<uid>.title
contentstack_queriesA Pinned Query on the template (Freeform must be on)a Repeater sourced from dataSources.contentstack_queries.<uid>
static_valueA literal value baked into the compositionLabels, button text the author types once
component_propsA Section’s exposed prop (passed in from a Template)Section’s “Card Title” override

API-authored bindings live at props.<propName>.binding on each node.

The Node Anatomy

Each node in the ui tree has:

  • type: registered component UID (page, section, repeater, condition-block, section-slot, or a custom registered component)
  • props: bindings + static values + exposed-prop metadata
  • slots: { <slot_uid>: [<child_node>, ...] } for children. Every slot must have a non-empty array: empty slots crash the renderer (see troubleshoot-canvas).
  • metadata: mode (preview/design), condition, sectionBindingOverride, etc.

When API-authoring is the Right Choice

TaskRight path
Seed compositions for a test environmentAPI authoring (author-composition-via-api)
Migrate an existing hand-coded marketing siteUI authoring (Studio canvas + build-section / build-connected-template)
Bulk-import 200 product detail compositions from a CSVAPI authoring
Author a Hero Strip section that authors will tweakUI authoring
Diff “what Studio writes” against “what my SDK reads”API authoring (decode + inspect)
Auto-provision a Studio project for a new test stackAPI authoring + provision-studio-project

The rule of thumb: API path for machines doing it at scale or in pipelines, UI path for humans composing pages.

What You’ll Need to Know Before API Authoring

  1. The six binding types and their shapes (above).
  2. The node anatomy: props.<prop>.binding for bindings, slots: { <uid>: [...] } for children, metadata for mode/condition.
  3. data_sources.resolvedReferences: what to populate via CDA ?include[]= so reference fields come back as full entries, not stubs.
  4. The zlib:<base64> encoding: both for writing and for debugging (decode + walk to diagnose).
  5. The composable_uid contract: equals the CMA entry uid for runtime lookup.
  6. The pre-publish preflight: every slot’s children array non-empty, no orphan descendant references, Repeater metadata.mode: "preview", Condition Block sibling on reference/modular-block iteration.

What This Skill is NOT