Content Studio
Content Studio is the structured admin UI at /admin/cms. Use it when click-to-edit isn’t enough — when you need to browse all entries, manage relationships, edit hidden fields, or restore from history.
What you can do here
Section titled “What you can do here”The home view
Section titled “The home view”/admin/cms shows a card for each known collection plus a “Create Collection” card. Cards come from three sources:
- Registered schemas in
caret()config - Dynamic collections created through Studio
- Discovered collections (anything with at least one entry on disk)
Click a collection card to drill into its entries.
Editing an entry
Section titled “Editing an entry”Inside a collection, you see a list of entries. Click one and Studio renders a form generated from the schema:
| Field type | Renders as |
|---|---|
string | Text input (long strings get textareas) |
number / integer | Number input with min/max |
boolean | Toggle |
enum | Select dropdown |
object | Grouped section with nested controls |
array | Repeatable rows with add/remove |
format: url / email | Input with validation |
Save with the button at the top right. Studio uses optimistic locking — if someone edited the entry while you were typing, you get a conflict toast and a “Reload to see latest” button.
Revision history
Section titled “Revision history”Every save snapshots the previous state. Open the history panel to see prior versions with timestamps and action labels (save_field, put_entry, etc.). One click restores any prior version into the editor; you still need to save to commit.
Creating a new entry
Section titled “Creating a new entry”If a collection’s schema is marked creatable: true, Studio shows a “New entry” button. Clicking it spawns a blank entry from the schema template. Required fields are flagged; you can’t save until they’re filled.
For collections without creatable: true (typical for site::global style singletons), Studio hides the new-entry button.
Reordering
Section titled “Reordering”If the schema is marked orderable: true, the entry list becomes drag-handle reorderable. The new order is persisted via a reorder_entries mutation. Useful for blog-post lists, navigation items, repeating sections.
Schema sources
Section titled “Schema sources”Studio determines field types and labels from one of three sources, in priority order:
- Registered —
caret({ schemas: {...} }) - Dynamic — created via Studio’s collection builder
- Inferred — guessed from the first stored entry
The schema endpoint (/api/cms/schema?collection=pages) returns a source field telling you which one was used. See Schemas for the full picture.
API calls behind the UI
Section titled “API calls behind the UI”Everything Studio does is a public API call you can reproduce from a script:
| Route | Purpose |
|---|---|
GET /api/cms/entries?collection=... | List entries |
GET /api/cms/schema?collection=... | Schema + template |
GET /api/cms/collections-metadata | All dynamic collection metadata |
POST /api/cms/mutate | Execute a mutation command |
GET /api/cms/history?collection=...&id=... | Revision history |
POST /api/cms/upload | Upload an image or asset |
See API Reference for full payloads.
Example mutation
Section titled “Example mutation”curl -X POST http://localhost:4321/api/cms/mutate \ -H 'Content-Type: application/json' \ -H 'x-caret-request: 1' \ -H 'Cookie: caret_session=<your-token>' \ -d '{ "type": "save_field", "collection": "pages", "id": "home", "field": "hero.headline", "value": "Ship faster with CaretCMS", "expectedRevision": 7 }'