Expert guidance for building with DatoCMS headless CMS. Includes API decision guides (CDA vs CMA), executable workflow playbooks for schema management, content operations, asset uploads, migrations, structured text (DAST), webhooks, and framework integrations. Covers official MCP server integration and troubleshooting.
Install
npx skillscat add jodusnodus/datocms-skill/datocms Install via the SkillsCat registry.
DatoCMS Agent Skill
This skill provides comprehensive guidance for working with DatoCMS, a headless CMS platform. It combines decision frameworks, executable workflows, and complete documentation reference.
When to Use This Skill
Use this skill when:
- Building or maintaining a DatoCMS project
- Integrating DatoCMS with frameworks (Next.js, React, Vue, etc.)
- Managing content models, records, or assets via API
- Setting up webhooks or real-time updates
- Working with DatoCMS plugins or the Plugin SDK
- Migrating content or managing multiple environments
- Troubleshooting DatoCMS API or integration issues
Do NOT use this skill for:
- Generic CMS comparisons (unless DatoCMS-specific)
- Non-DatoCMS headless CMS implementations
- Basic frontend development unrelated to DatoCMS
API Decision Guide
DatoCMS provides multiple APIs for different use cases:
Content Delivery API (CDA)
Use for: Fetching published content for production sites
- GraphQL-based, read-only
- Optimized for speed with global CDN
- Supports filtering, sorting, pagination
- Best for: SSR, SSG, client-side fetching
Example:
import { executeQuery } from '@datocms/cda-client';
const result = await executeQuery(query, {
token: process.env.DATOCMS_API_TOKEN,
environment: 'main'
});Content Management API (CMA)
Use for: Creating, updating, deleting content and schema
- REST-based with full CRUD operations
- Requires write permissions
- Best for: Admin panels, migrations, automated content creation
Example:
import { buildClient } from '@datocms/cma-client-node';
const client = buildClient({ apiToken: process.env.DATOCMS_API_TOKEN });
// Create a record
const record = await client.items.create({
item_type: { type: 'item_type', id: 'blog_post' },
title: 'New Post',
content: 'Content here'
});Asset API
Use for: Uploading files and managing assets
- Two-step process: request upload URL, then upload file
- Supports images, videos, documents
Real-Time Updates API
Use for: Live preview, collaborative editing
- WebSocket-based
- Reflects draft changes instantly
Getting Started
1. API Tokens
- Go to Settings > API Tokens in your DatoCMS project
- Read-only token for CDA (can be public)
- Full-access token for CMA (keep secret)
2. Install Clients
# For content fetching
npm install @datocms/cda-client
# For content management
npm install @datocms/cma-client-node
# For React/Next.js
npm install react-datocms3. Basic Query
import { executeQuery } from '@datocms/cda-client';
const query = `
query {
allBlogPosts {
id
title
slug
publishedAt
}
}
`;
const data = await executeQuery(query, {
token: process.env.DATOCMS_API_TOKEN
});Workflow Playbooks
1. Schema Management: Create Models & Fields
When: Setting up new content types or modifying existing ones
import { buildClient } from '@datocms/cma-client-node';
const client = buildClient({ apiToken: process.env.DATOCMS_API_TOKEN });
// Create a model
const model = await client.itemTypes.create({
name: 'Blog Post',
api_key: 'blog_post',
singleton: false
});
// Add fields
await client.fields.create(model.id, {
label: 'Title',
field_type: 'string',
api_key: 'title',
validators: { required: {} }
});
await client.fields.create(model.id, {
label: 'Content',
field_type: 'structured_text',
api_key: 'content'
});2. Content Operations: CRUD + Publishing
When: Managing content records programmatically
// Create draft
const draft = await client.items.create({
item_type: { type: 'item_type', id: 'blog_post' },
title: 'My Post',
content: { /* DAST structure */ }
});
// Update
await client.items.update(draft.id, {
title: 'Updated Title'
});
// Publish
await client.items.publish(draft.id);
// Unpublish
await client.items.unpublish(draft.id);
// Delete
await client.items.destroy(draft.id);3. Asset Uploads: Two-Step Flow
When: Uploading images, videos, or documents
import { buildClient } from '@datocms/cma-client-node';
import fs from 'fs';
const client = buildClient({ apiToken: process.env.DATOCMS_API_TOKEN });
// Step 1: Create upload request
const path = './image.jpg';
const uploadRequest = await client.uploads.createFromFileOrBlob({
fileOrBlob: fs.createReadStream(path),
filename: 'image.jpg'
});
// Step 2: Use upload in a record
await client.items.create({
item_type: { type: 'item_type', id: 'blog_post' },
title: 'Post with Image',
cover_image: {
upload_id: uploadRequest.id
}
});4. Migrations: Sandbox to Production
When: Testing schema changes before deploying
# Create sandbox environment
# (Do this in DatoCMS UI: Settings > Environments)
# Make changes in sandbox
DATOCMS_ENVIRONMENT=sandbox node update-schema.js
# Test in sandbox
# Preview at: https://your-project.admin.datocms.com/editor?environment=sandbox
# Promote to primary environment (via UI or API)5. Structured Text (DAST): Handling Rich Content
When: Working with rich text fields
import { render } from 'datocms-structured-text-to-html-string';
// DAST structure
const structuredText = {
schema: 'dast',
document: {
type: 'root',
children: [
{
type: 'heading',
level: 1,
children: [{ type: 'span', value: 'Hello World' }]
},
{
type: 'paragraph',
children: [
{ type: 'span', value: 'This is ' },
{ type: 'span', marks: ['strong'], value: 'bold text' }
]
}
]
}
};
// Render to HTML
const html = render(structuredText);6. Webhooks: Event Notifications
When: Triggering builds or syncing data on content changes
// Create webhook via CMA
const webhook = await client.webhooks.create({
name: 'Deploy on Publish',
url: 'https://api.vercel.com/v1/integrations/deploy/...',
events: [
{ entity_type: 'item', event_types: ['publish', 'unpublish'] }
],
http_basic_user: 'user',
http_basic_password: 'pass'
});7. Framework Integration: Next.js Example
When: Building a Next.js site with DatoCMS
// app/blog/page.tsx
import { executeQuery } from '@datocms/cda-client';
const query = `
query {
allBlogPosts(orderBy: publishedAt_DESC) {
id
title
slug
excerpt
}
}
`;
export default async function BlogPage() {
const { allBlogPosts } = await executeQuery(query, {
token: process.env.DATOCMS_API_TOKEN!
});
return (
<div>
{allBlogPosts.map(post => (
<article key={post.id}>
<h2>{post.title}</h2>
<p>{post.excerpt}</p>
</article>
))}
</div>
);
}MCP Server Integration
DatoCMS provides an official Model Context Protocol (MCP) server for AI agents:
Installation
{
"mcpServers": {
"datocms": {
"command": "npx",
"args": ["-y", "@datocms/mcp-server"],
"env": {
"DATOCMS_API_TOKEN": "your-full-access-token"
}
}
}
}Available Tools
list_models- List all content modelsget_model- Get model details with fieldslist_records- List records of a modelget_record- Get single record by IDcreate_record- Create new recordupdate_record- Update existing recorddelete_record- Delete record
Troubleshooting
Common Issues
1. "Invalid API token"
- Verify token in Settings > API Tokens
- Check environment variable is loaded
- Ensure token has required permissions (read-only vs full-access)
2. "Model/Field not found"
- Use
api_keynotidin queries - Check model exists in current environment
- Verify field spelling and case sensitivity
3. "Rate limit exceeded"
- CDA: 30 requests/second (burst: 60)
- CMA: 15 requests/second
- Implement exponential backoff
4. Asset upload fails
- Check file size limits (5GB max)
- Verify file type is supported
- Use
createFromFileOrBlobmethod
5. Structured text not rendering
- Validate DAST schema structure
- Use official rendering packages
- Check for custom block types
Debug Checklist
- API token is correct and has required permissions
- Environment name matches (main vs sandbox)
- API key names match schema (not display names)
- Request payload matches API documentation
- Check DatoCMS status page for outages
- Review API logs in DatoCMS settings
Documentation Reference
Below is the complete index of DatoCMS documentation organized by topic. All links point to Markdown versions for easy parsing.
DatoCMS
Docs
- What is DatoCMS?
- Organizations and accounts
- Project collaborators, roles and permissions
- The content schema
- Organizing content
- Record versioning
- Draft/published system
- Scheduled publishing
- Media Area
- Localization
- Visual Editing
- Collaboration features
- Workflows
- Webhooks
- Plugins
- DatoCMS Site Search
- Project Templates
- How your website and DatoCMS work together
- How to deploy
- Primary and sandbox environments
- Project usages
- Audit Logs
- Introduction to Content Modeling
- Single instance models
- Record ordering
- Hierarchical sorting (Tree-like collections)
- Blocks
- Modular content fields
- Structured text fields
- Link fields
- SEO fields
- Slugs and permalinks
- External video field
- Validations
- Data consistency: key concepts and implications
- Overview of DatoCMS APIs
- DatoCMS Domains and Content Security Policy (CSP)
- Content Delivery API Overview
- Your first request
- How to fetch records
- API headers (environments, drafts, strict mode, cache tags, content link)
- Authentication and permissions
- Error codes & handling failures (CDA)
- Technical Limits (CDA)
- Complexity
- Custom Scalar Types
- Pagination
- Filtering records
- Deep Filtering
- Ordering records
- Localization
- Direct vs. Inverse relationships
- Modular content fields
- Structured text fields
- Hierarchical sorting (Tree-like collections)
- Images and videos
- Filtering uploads
- SEO and favicon
- Meta fields
- Cache Tags
- Changelog
- Content Management API Overview
- Using the JavaScript client
- API versioning
- Authentication
- Environments
- Error codes & handling failures (CMA)
- Pagination
- Asynchronous jobs
- Technical Limits (CMA)
- Record
- List all records
- Create a new record
- Duplicate a record
- Update a record
- Referenced records
- Retrieve a record
- Delete a record
- Publish a record
- Unpublish a record
- Publish items in bulk
- Unpublish items in bulk
- Destroy items in bulk
- Move items to stage in bulk
- Scheduled publication
- Create a new scheduled publication
- Delete a scheduled publication
- Scheduled unpublishing
- Create a new scheduled unpublishing
- Delete a scheduled unpublishing
- Upload
- Create a new upload
- List all uploads
- Retrieve an upload
- Delete an upload
- Update an upload
- Referenced records
- Add tags to assets in bulk
- Put assets into a collection in bulk
- Destroy uploads
- Site
- Retrieve the site
- Update the site's settings
- Model/Block model
- Create a new model/block model
- Update a model/block model
- List all models/block models
- Retrieve a model/block model
- Duplicate model/block model
- Delete a model/block model
- List models referencing another model/block
- Field
- Create a new field
- Update a field
- List all fields of a model/block
- List fields referencing a model/block
- Retrieve a field
- Delete a field
- Duplicate a field
- Fieldset
- Create a new fieldset
- Update a fieldset
- List all fieldsets of a model/block
- Retrieve a fieldset
- Delete a fieldset
- Record version
- Restore an old record version
- List all record versions
- Retrieve a record version
- Upload permission
- Request a new permission to upload a file
- Upload track
- Create a new upload track
- List upload tracks
- Delete an upload track
- Manual tags
- List all manually created upload tags
- Create a new upload tag
- Smart tags
- List all automatically created upload tags
- Upload Collection
- Create a new upload collection
- Update a upload collection
- List all upload collections
- Retrieve a upload collection
- Delete a upload collection
- Search Index
- List all search indexes for a site
- Retrieve a search index
- Create a search index
- Update a search index
- Trigger the indexing process
- Abort a the current indexing process and mark it as failed
- Delete a search index
- Search result
- Search for results
- Search indexing activity
- List all search indexing events
- Retrieve a search indexing event
- Environment
- Fork an existing environment
- Promote an environment to primary
- Rename an environment
- List all environments
- Retrieve a environment
- Delete a environment
- Maintenance mode
- Retrieve maintenence mode
- Activate maintenance mode: this means that the primary environment will be read-only
- De-activate maintenance mode
- Menu Item
- Create a new menu item
- Update a menu item
- List all menu items
- Retrieve a menu item
- Delete a menu item
- Schema Menu Item
- Create a new schema menu item
- Update a schema menu item
- List all schema menu items
- Retrieve a schema menu item
- Delete a schema menu item
- Uploads filter
- Create a new filter
- Update a filter
- List all filters
- Retrieve a filter
- Delete a filter
- Model filter
- Create a new filter
- Update a filter
- List all filters
- Retrieve a filter
- Delete a filter
- Plugin
- Create a new plugin
- Update a plugin
- List all plugins
- Retrieve a plugin
- Delete a plugin
- Retrieve all fields using the plugin
- Workflow
- Create a new workflow
- Update a workflow
- List all workflows
- Retrieve a workflow
- Delete a workflow
- Asynchronous job
- Job result
- Retrieve a job result
- Account
- Organization
- Invitation
- Invite a new user
- Update an invitation
- List all invitations
- Retrieve an invitation
- Delete an invitation
- Resend an invitation
- Collaborator
- Update a collaborator
- List all collaborators
- Retrieve a collaborator
- Retrieve current signed-in user
- Delete a collaborator
- Role
- Create a new role
- Update a role
- List all roles
- Retrieve a role
- Delete a role
- Duplicate a role
- API token
- Create a new API token
- Update an API token
- List all API tokens
- Retrieve an API token
- Rotate API token
- Delete an API token
- Webhook
- Create a new webhook
- Update a webhook
- List all webhooks
- Retrieve a webhook
- Delete a webhook
- Webhook call
- List all webhooks calls
- Retrieve a webhook call
- Re-send the webhook call
- Build trigger
- List all build triggers for a site
- Retrieve a build trigger
- Create build trigger
- Update build trigger
- Trigger a deploy
- Abort a deploy and mark it as failed
- Abort a site search spidering and mark it as failed
- Trigger a new site search spidering of the website
- Delete a build trigger
- Deploy activity
- List all deploy events
- Retrieve a deploy event
- Subscription limit
- Get all the subscription limits
- Get a single subscription limit
- Subscription feature
- Get all the subscription features
- SSO Settings
- Retrieve SSO Settings
- Generate SSO token
- Update SSO Settings
- SSO User
- List all users
- Returns a SSO user
- Copy editors as SSO users
- Delete a SSO user
- SSO Group
- List all SSO groups
- Sync SSO provider groups to DatoCMS roles
- Update a SSO group
- Delete a group
- White-label settings
- Retrieve white-label settings
- Update white-label settings
- Audit log event
- List Audit Log events
- Images API
- Video API
- Asset CDN Settings
- Real-Time Updates API Overview
- How to use it
- API reference
- Limits and pricing
- MCP server
- LLM-ready Docs
- Translating content with AI
- Visual Editing
- Introduction to Environments & Migrations
- Safe iterations using environments
- Configuring the CLI
- Write and test migration scripts
- Apply migrations to primary environment
- Running legacy migration scripts
- Keeping multiple DatoCMS projects in sync
- Structured Text and \`dast\` format
- Migrating content to Structured Text
- Available Export & Backup Options
- Enterprise Project Exports
- Import space from Contentful
- Import from WordPress
- Importing data from other sources
- Introduction to the DatoCMS Plugin SDK
- Build your first DatoCMS plugin
- Real-world examples
- What hooks are
- Config screen
- Custom pages
- Sidebars and sidebar panels
- Outlets
- Field extensions
- Manual field extensions
- Dropdown actions
- Structured Text customizations
- Asset sources
- Opening modals
- Event hooks
- Customize record presentation
- React UI Components
- Button
- Button group
- Dropdown
- Form
- Section
- Sidebar panel
- Spinner
- Toolbar
- Sidebars and split views
- Additional permissions
- Working with form values
- Publishing to Marketplace
- Releasing new plugin versions
- Migrating from legacy plugins
- How to stream videos efficiently: Raw MP4 Downloads vs HLS Streaming
- Streaming Video Analytics with Mux Data
- Site Search Overview
- Configuration
- How the crawling works
- Perform searches via API
- React search widget
- Vue search widget
- Custom Domain Name for Assets (Enterprise only)
- DatoCMS Pro Tips
- Customize CMS domain
- How to manage a live and a preview site
- Next.js + DatoCMS Overview
- Optimizing calls to DatoCMS
- Managing images
- Displaying videos
- Structured Text fields
- Adding SEO to pages
- Setting up Next.js Draft Mode
- Real-time updates
- DatoCMS Cache Tags and Next.js
- Visual Editing
- Nuxt + DatoCMS Overview
- Include draft contents
- Responsive images
- Displaying videos
- Structured Text fields
- Adding SEO to Nuxt pages
- Real-time updates
- Visual Editing
- SvelteKit + DatoCMS Overview
- Accessing draft/updated content
- Managing images
- Displaying videos
- Structured Text fields
- SEO Management
- Real-time updates
- Visual Editing
- Astro + DatoCMS Overview
- Accessing draft/updated content
- Managing images
- Displaying videos
- Structured Text fields
- SEO Management
- Real-time updates
- Visual Editing
- Remix + DatoCMS Overview
- Managing images
- Displaying videos
- Structured Text fields
- Adding SEO to pages
- Setting up a preview mode
- Real-time updates
- DatoCMS Cache Tags and Remix
- Agency Partner Program Overview
- Clients and Agency mandates
- Partners dashboard
- Enrollment requirements
- Public Profile and Case studies
- Pricing Overview
- Billing and pricing
- Payment failures and billing notifications
- Cancellations and refunds
- Credit card change
- How overages are managed
- Transfer project
- Duplicate or delete project
- Migrating to a new pricing
Official packages READMEs
- @datocms/cma-client - Content Management API Client
- @datocms/cda-client - Content Delivery API Client
- datocms-cli - CLI Tool
- datocms-cli - Contentful Import Plugin
- datocms-cli - WordPress Import Plugin
- DatoCMS Plugins - Examples Repository
- react-datocms - Main Package
- react-datocms - <Image> and <SRCImage> Components
- react-datocms - <StructuredText> Component
- react-datocms - <VideoPlayer> Component
- react-datocms - useQuerySubscription Hook
- react-datocms - useSiteSearch Hook
- react-datocms - SEO Meta Tags Utilities
- react-datocms - <ContentLink> Component and useContentLink Hook
- vue-datocms - Main Package
- vue-datocms - <datocms-image> and <datocms-naked-image> Components
- vue-datocms - <VideoPlayer> Component
- vue-datocms - <datocms-structured-text> Component
- vue-datocms - useQuerySubscription Composable
- vue-datocms - useSiteSearch Composable
- vue-datocms - useVideoPlayer Composable
- vue-datocms - <datocms-content-link> Component
- astro-datocms - Main Package
- astro-datocms - <Image> Component
- astro-datocms - <Seo> Component
- astro-datocms - <StructuredText> Component
- astro-datocms - <QueryListener> Component
- astro-datocms - <ContentLink> Component
- datocms-svelte - Main Package
- datocms-svelte - <Image> and <NakedImage> Components
- datocms-svelte - <VideoPlayer> Component
- datocms-svelte - <StructuredText> Component
- datocms-svelte - <Head> Component
- datocms-svelte - querySubscription Store
- datocms-svelte - <ContentLink> Component
- datocms-structured-text-utils - Utilities & Types
- datocms-structured-text-to-plain-text - Renderer
- datocms-structured-text-to-markdown - Renderer
- datocms-structured-text-to-html-string - Renderer
- datocms-structured-text-to-dom-nodes - Renderer
- datocms-html-to-structured-text - Converter
- datocms-structured-text-slate-utils - Slate Utilities
- datocms-listen - Real-Time Updates Client