Content Data
API reference for content CRUD operations — list, get, create, update, delete, and count endpoints.
Content Data API
The Content Data endpoints handle CRUD operations for content entries. Every operation is scoped to a project (via the x-laizy-project header) and requires authentication.
Authentication
All endpoints require:
Authorization: Bearer laizy_eyJhbGciOiJI...
x-laizy-project: <project-id>| Endpoint | Required Scope |
|---|---|
contentData.list | content:read or admin |
contentData.get | content:read or admin |
contentData.count | content:read or admin |
contentData.create | admin |
contentData.update | admin |
contentData.delete | admin |
Read operations work with both frontend tokens (content:read) and admin tokens. Write operations require admin tokens.
contentData.list
List content entries for a specific model with optional status filtering and pagination.
Input
{
modelName: string; // Required — name of the content model
status?: 'draft' | 'published' | 'archived'; // Optional filter
limit?: number; // Default: 50, max: 100
offset?: number; // Default: 0
}Response
Returns an array of content entries:
[
{
id: string;
modelName: string;
projectId: string;
data: Record<string, any>; // Content fields
status: 'draft' | 'published' | 'archived';
createdAt: Date;
updatedAt: Date;
}
]Example with ManagementClient
const entries = await client.listContentData({
modelName: 'BlogPost',
status: 'published',
limit: 10,
offset: 0,
});Example with Generated Client
const posts = await cms.blogPost.findMany({
limit: 10,
offset: 0,
});Errors
| Code | Cause |
|---|---|
NOT_FOUND | Content model does not exist in the project |
UNAUTHORIZED | Invalid or missing authentication |
Frontend tokens automatically filter to published content only, regardless of the status parameter. Admin tokens return content in any status.
contentData.get
Fetch a single content entry by its ID.
Input
{
id: string; // Required — unique entry ID
}Response
Returns a single content entry or throws NOT_FOUND:
{
id: string;
modelName: string;
projectId: string;
data: Record<string, any>;
status: 'draft' | 'published' | 'archived';
createdAt: Date;
updatedAt: Date;
}Example with ManagementClient
const entry = await client.getContentData('abc123');
// Returns null if not found (ManagementClient handles NOT_FOUND)Example with Generated Client
const post = await cms.blogPost.findById('abc123');
// Returns null if not foundErrors
| Code | Cause |
|---|---|
NOT_FOUND | Entry does not exist or belongs to a different project |
UNAUTHORIZED | Invalid or missing authentication |
contentData.create
Create a new content entry for a specified model.
Input
{
modelName: string; // Required — model name
data: Record<string, any>; // Required — content fields (at least one)
status?: 'draft' | 'published' | 'archived'; // Default: 'draft'
}The data object must contain at least one field. Required fields defined in the schema must be present unless they have default values.
Response
Returns the created content entry:
{
id: string; // Generated unique ID
modelName: string;
projectId: string;
data: Record<string, any>;
status: 'draft' | 'published' | 'archived';
createdAt: Date;
updatedAt: Date;
}Example with ManagementClient
const entry = await client.createContentData({
modelName: 'BlogPost',
data: {
title: 'My First Post',
content: 'Hello, world!',
slug: 'my-first-post',
},
status: 'published',
});Example with CLI
echo '{"title": "My First Post", "content": "Hello, world!", "slug": "my-first-post"}' \
| pnpm laizy content create BlogPost --status publishedErrors
| Code | Cause |
|---|---|
NOT_FOUND | Content model does not exist |
BAD_REQUEST | Data object is empty |
UNAUTHORIZED | Token does not have write access |
contentData.update
Update an existing content entry. Supports partial updates -- only include the fields you want to change.
Input
{
id: string; // Required — entry ID
data?: Record<string, any>; // Fields to update
status?: 'draft' | 'published' | 'archived'; // Status to set
}At least one of data or status must be provided.
Response
Returns the updated content entry:
{
id: string;
modelName: string;
projectId: string;
data: Record<string, any>;
status: 'draft' | 'published' | 'archived';
createdAt: Date;
updatedAt: Date;
}Example with ManagementClient
// Update field data
const updated = await client.updateContentData({
id: 'abc123',
data: { title: 'Updated Title' },
});
// Update status only
const published = await client.updateContentData({
id: 'abc123',
status: 'published',
});
// Update both
const result = await client.updateContentData({
id: 'abc123',
data: { title: 'New Title' },
status: 'published',
});Example with CLI
pnpm laizy content update BlogPost abc123 \
--json '{"title": "Updated Title"}' \
--status publishedErrors
| Code | Cause |
|---|---|
NOT_FOUND | Entry does not exist or belongs to a different project |
BAD_REQUEST | Neither data nor status provided |
UNAUTHORIZED | Token does not have write access |
contentData.delete
Permanently delete a content entry.
Input
{
id: string; // Required — entry ID
}Response
{
success: boolean; // true if deleted
}Example with ManagementClient
await client.deleteContentData({
modelName: 'BlogPost',
id: 'abc123',
});Example with CLI
pnpm laizy content delete BlogPost abc123
# Shows confirmation prompt
pnpm laizy content delete BlogPost abc123 --force
# Skips confirmationErrors
| Code | Cause |
|---|---|
NOT_FOUND | Entry does not exist or belongs to a different project |
UNAUTHORIZED | Token does not have write access |
contentData.count
Count content entries for a model with optional status filtering.
Input
{
modelName: string; // Required — model name
status?: 'draft' | 'published' | 'archived'; // Optional filter
}Response
{
count: number; // Total matching entries
}Example with ManagementClient
const count = await client.countContentData({
modelName: 'BlogPost',
status: 'published',
});
// Returns: numberExample with Generated Client
const total = await cms.blogPost.count();
// Returns: numberErrors
| Code | Cause |
|---|---|
NOT_FOUND | Content model does not exist |
UNAUTHORIZED | Invalid or missing authentication |
Live Preview Events
Create, update, and delete operations automatically publish live preview events via Redis. This enables real-time content updates in the dashboard without page refreshes. The event includes the project ID, model name, operation type, and entry ID.
Next Steps
- Authentication -- Token types and how to generate them
- API Overview -- Full list of available endpoints
- Generated Client -- Use the typed client instead of raw API calls