Skip to main content

API Overview

ClearCMS provides a REST API for reading and writing your site's content, media, and forms. This page covers authentication, versioning, rate limits, and error handling — things that apply to every endpoint.

For specific endpoints, see:

Base URL

All API requests use your site's ClearCMS domain:

https://your-site.clearcms.app/api/v1

Replace your-site with your site's slug.

Versioning

The API uses a URL-based version prefix (/api/v1/). All current endpoints are v1. When breaking changes are introduced, a new version (v2) will be added alongside v1 — existing endpoints will continue to work.

Non-breaking additions (new fields in responses, new optional parameters) are made to the current version without a version bump.

Authentication

API keys

Most endpoints require an API key. Generate one in Settings > Developer > API Keys.

Include it as a Bearer token:

Authorization: Bearer YOUR_API_KEY

API keys have permission levels:

  • Read — fetch content, media, globals
  • Write — create and update content, upload media
  • Admin — delete content, manage forms

Keep API keys secret. Never expose them in client-side JavaScript.

Public endpoints

Some endpoints work without authentication:

EndpointDescription
GET /api/v1/public/contentPublished content items
GET /api/v1/public/collections/{type}Published collection items
GET /api/v1/public/pages/{slug}Published page with sections
GET /api/v1/public/mediaMedia files (basic fields)
GET /api/v1/public/globalsSite settings
GET /api/v1/public/tokens.jsonDesign tokens as JSON
GET /api/v1/public/tokens.cssDesign tokens as CSS
GET /api/v1/public/tailwind.config.jsDesign tokens as Tailwind config
POST /api/v1/forms/{id}/submissionsSubmit a form
GET /api/v1/schemaSchema introspection

Public endpoints support CORS and are cached (typically 60 seconds for content, 1 hour for tokens).

Rate limits

Requests are rate-limited per API key:

TierRequests per minute
Public (no key)60
Free plan120
Pro / Team300
Business / Growth600
Scale / Enterprise1200

When you exceed the limit, the API returns 429 Too Many Requests with a Retry-After header (in seconds).

CORS

Public endpoints (/api/v1/public/*) allow cross-origin requests from any origin for all HTTP methods. Authenticated endpoints allow GET requests cross-origin. Write operations (POST, PUT, DELETE) on authenticated endpoints should be made from server-side code.

All endpoints respond to OPTIONS preflight requests.

Pagination

List endpoints use offset-based pagination:

GET /api/v1/public/content?type=posts&limit=10&offset=20

Every list response includes pagination metadata:

{
"data": [...],
"total": 42,
"limit": 10,
"offset": 20
}

Calculate pages:

const totalPages = Math.ceil(total / limit);
const currentPage = Math.floor(offset / limit) + 1;

The collections endpoint uses page-based pagination instead:

GET /api/v1/public/collections/posts?page=2&per_page=20

Filtering and sorting

Content list endpoints support:

ParameterExampleDescription
sortcreatedAtField to sort by
orderdescasc or desc
searchhelloSearch in title field
filter[field][op]=valuefilter[price][gte]=100Field filtering (authenticated only)

Supported filter operators: eq, neq, gt, gte, lt, lte, like, in.

Draft content

By default, all endpoints return only published content. To include drafts, add ?draft=true and include an API key:

GET /api/v1/public/pages/about?draft=true
Authorization: Bearer YOUR_API_KEY

Error responses

All errors return JSON with this shape:

{
"error": "NOT_FOUND",
"message": "No page found with slug 'missing-page'"
}
StatusCodeMeaning
400BAD_REQUESTInvalid query parameter or request body
401UNAUTHORIZEDMissing or invalid API key
403FORBIDDENAPI key lacks permission for this operation
404NOT_FOUNDResource does not exist
422VALIDATION_ERRORRequest body failed validation
429RATE_LIMITEDToo many requests; check Retry-After header
500INTERNAL_ERRORServer error

SDKs

There are no official client SDKs yet. The API returns standard JSON and works with any HTTP client. See the Headless Quickstart for a practical Next.js example with a typed API client.

Was this page helpful?