Content API
Full CRUD for content entries. All endpoints are scoped to an app. Endpoints differ slightly for collection vs single schemas.
Collection endpoints
List entries
GET /api/v1/apps/:app_slug/content/:schema_slug
By default, only published entries are returned. Use ?status=all to include drafts, or ?status=draft for drafts only. Use ?q=search to filter entries by text.
curl -H "Authorization: Bearer $TOKEN" \
http://localhost:3000/api/v1/apps/my-app/content/blog-posts
Response:
[
{
"id": "my-first-post",
"data": {
"title": "My First Post",
"body": "Hello world",
"published": true
}
}
]
Get an entry
GET /api/v1/apps/:app_slug/content/:schema_slug/:entry_id
curl -H "Authorization: Bearer $TOKEN" \
http://localhost:3000/api/v1/apps/my-app/content/blog-posts/my-first-post
Response – the entry data directly (no wrapper):
{
"title": "My First Post",
"body": "Hello world",
"published": true
}
Returns 404 if the entry does not exist.
Create an entry
POST /api/v1/apps/:app_slug/content/:schema_slug
Content-Type: application/json
Requires editor role or above.
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"title": "New Post", "body": "Content here"}' \
http://localhost:3000/api/v1/apps/my-app/content/blog-posts
Response (201 Created):
{
"id": "new-post"
}
The entry ID is generated from the content (see entry ID generation).
Validation errors return 400:
{
"errors": ["title: \"title\" is a required property"]
}
Update an entry
PUT /api/v1/apps/:app_slug/content/:schema_slug/:entry_id
Content-Type: application/json
Requires editor role or above. A version history snapshot is saved before updating.
curl -X PUT \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"title": "Updated Post", "body": "New content", "published": true}' \
http://localhost:3000/api/v1/apps/my-app/content/blog-posts/new-post
Returns 200 OK on success.
Delete an entry
DELETE /api/v1/apps/:app_slug/content/:schema_slug/:entry_id
Requires editor role or above.
curl -X DELETE \
-H "Authorization: Bearer $TOKEN" \
http://localhost:3000/api/v1/apps/my-app/content/blog-posts/new-post
Returns 204 No Content on success.
Publish / Unpublish
POST /api/v1/apps/:app_slug/content/:schema_slug/:entry_id/publish
POST /api/v1/apps/:app_slug/content/:schema_slug/:entry_id/unpublish
See Deployments API for details.
Single endpoints
For schemas with kind: "single", use the /single endpoints instead:
Get
GET /api/v1/apps/:app_slug/content/:schema_slug/single
curl -H "Authorization: Bearer $TOKEN" \
http://localhost:3000/api/v1/apps/my-app/content/site-settings/single
Create or update
PUT /api/v1/apps/:app_slug/content/:schema_slug/single
Content-Type: application/json
curl -X PUT \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"site_name": "My Site", "tagline": "A great site"}' \
http://localhost:3000/api/v1/apps/my-app/content/site-settings/single
Delete
DELETE /api/v1/apps/:app_slug/content/:schema_slug/single
Working with uploads in content
When creating or updating content that includes upload fields, use the upload hash reference format:
{
"title": "Post with Image",
"cover": {
"hash": "a1b2c3d4e5f6...",
"filename": "photo.jpg",
"mime": "image/jpeg"
}
}
Upload the file first via the Uploads API, then use the returned hash in your content.