Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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.