v1 REST API
Fetch content from CMS One using simple HTTP endpoints. Authenticate with an API key and start serving articles to any front‑end, app, or service.
GET /api/v1/articlesGET /api/v1/articles/:slugGET /api/v1/articles/:slug/assetsOverview
The v1 API exposes published content from your workspace over HTTPS. All requests must be authenticated and all responses use the same JSON envelope.
REST + JSON
Simple HTTP endpoints returning predictable JSON responses. No SDK required.
API Key Auth
Authenticate every request with a Bearer token scoped to your workspace.
Paginated Lists
All collection endpoints support page, limit, search, and sort parameters.
Consistent Errors
Every error returns { success: false, error } with a reliable HTTP status code.
Base URL
https://your-domain.com/api/v1Replace your-domain.com with your own domain or the CMS One cloud hostname.
Authentication
Every request must include a valid API key in the Authorization header. Generate keys from Workspace → API Keys. Keys are scoped to your workspace - they only grant access to content belonging to that tenant.
Required header
Authorization: Bearer YOUR_API_KEYconst res = await fetch("https://your-domain.com/api/v1/articles", {
headers: {
Authorization: "Bearer YOUR_API_KEY",
},
});
const { success, data, meta } = await res.json();Where to find your API key
Open your workspace and navigate to API Keys. Create a new key, copy it once - it will not be shown again.
Articles
The Articles resource gives read‑only access to all published content in your workspace. Three endpoints are available: one for listing, one for fetching a single article by its slug, and one for fetching an article's image assets with captions.
/api/v1/articles- List ArticlesReturns a paginated list of published articles for your workspace. Results are ordered by publish date (newest first) by default. Filter by type, category, tag, or language, and search full‑text across titles and content.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
page | number | 1 | Page number (1‑based). |
limit | number | 10 | Results per page. Maximum 100. |
type | string | - | Filter by article type. One of: blog, news, case-study, tutorial, documentation, page. |
category | string | - | Filter by category slug (e.g. guides). |
tag | string | - | Filter by tag slug or name. |
search | string | - | Full‑text search term matched against titles and content. |
language | string | - | ISO language code (e.g. "en", "fr"). |
sort | string | latest | "latest" orders by publishedAt desc (default); "popular" orders by view count desc. |
Example
const res = await fetch(
"https://your-domain.com/api/v1/articles?page=1&limit=5&sort=latest",
{
headers: { Authorization: "Bearer YOUR_API_KEY" },
}
);
const { success, data, meta } = await res.json();
// data → Article[]
// meta → { page: 1, limit: 5, total: 48, totalPages: 10 }Response Fields
| Field | Type | Description |
|---|---|---|
id | string | Article ObjectId as a hex string. |
title | string | Article title. |
slug | string | URL‑friendly identifier. Use this to fetch the full article. |
excerptnullable | string | Short summary suitable for list views. |
type | string | Content type (blog, tutorial, etc.). |
featuredImagenullable | string | Cover image URL. |
featuredImageAltnullable | string | Image alt text. |
categories | { id, name, slug }[] | Resolved category objects. |
tags | string[] | Tag slugs / names. |
language | string | Language code. |
publishedAt | ISO string | Publication date. |
readCount | number | Total view count. |
likeCount | number | Total likes. |
commentCount | number | Total comments. |
isFeatured | boolean | Whether the article is featured. |
isPinned | boolean | Whether the article is pinned. |
/api/v1/articles/:slug- Get ArticleReturns the full content of a single published article identified by its slug. Includes the body as a Tiptap JSON document (contentType: blocks), resolved category and tag objects, SEO metadata, addon links, and up to 5 related articles. Calling this endpoint also increments the article's view counter - repeat visits within the same time window are deduplicated automatically.
Example
const slug = "getting-started-with-cms-one";
const res = await fetch(
`https://your-domain.com/api/v1/articles/${slug}`,
{
headers: { Authorization: "Bearer YOUR_API_KEY" },
}
);
const { success, data } = await res.json();
// data.content → Tiptap JSON document (stringified)
// data.contentType → "blocks"
const doc = JSON.parse(data.content);
// data.related → up to 5 related articlesResponse Fields
| Field | Type | Description |
|---|---|---|
id | string | Article ObjectId as a hex string. |
title | string | Article title. |
slug | string | URL‑friendly identifier. |
content | string | Full article body as a JSON-stringified Tiptap document ({ type: "doc", content: [...] }). JSON.parse it and render with Tiptap (e.g. generateHTML) or your own node renderer. |
contentType | "blocks" | Always "blocks". Posts written in Markdown or HTML (via MCP or the API) are converted to blocks when saved; older posts are converted on read. |
excerptnullable | string | Short summary. |
type | string | Content type. |
featuredImagenullable | string | Cover image URL. |
featuredImageAltnullable | string | Alt text for the cover image. |
gallery | string[] | Additional image URLs. |
language | string | Language code. |
publishedAt | ISO string | Publication date. |
updatedAt | ISO string | Last updated date. |
categories | { id, name, slug, description? }[] | Fully resolved category objects. |
tags | { name, slug, color }[] | Fully resolved tag objects including brand color. |
readCount | number | Total view count (incremented by this request, deduplicated). |
likeCount | number | Total likes. |
commentCount | number | Total comments. |
allowComments | boolean | Whether the comment section is open. |
isFeatured | boolean | Featured flag. |
seo | object | SEO metadata: { title, description, ogImage, noIndex }. |
addonLinks | { type, label, url, order }[] | Additional links attached to the article (type is one of "github", "article", "demo", "custom"). Empty array when none. |
related | RelatedArticle[] | Up to 5 related articles based on shared categories and tags. Each includes id, title, slug, excerpt, featuredImage, featuredImageAlt, publishedAt, readCount, and type. |
/api/v1/articles/:slug/assets- Get Article AssetsReturns image assets attached to a published article, including caption text, alt text, order, and file metadata. Use this endpoint when your frontend needs article gallery images with captions separate from the main article payload.
Example
const slug = "getting-started-with-cms-one";
const res = await fetch(
`https://your-domain.com/api/v1/articles/${slug}/assets`,
{
headers: { Authorization: "Bearer YOUR_API_KEY" },
}
);
const { success, data } = await res.json();
// data.assets -> [{ url, caption, alt, order, ... }]Response Fields
| Field | Type | Description |
|---|---|---|
article.id | string | Article ObjectId as a hex string. |
article.slug | string | Article slug. |
article.title | string | Article title. |
assets[].id | string | Article asset ObjectId. |
assets[].mediaId | string | Source media ObjectId. |
assets[].type | "image" | Asset type. |
assets[].url | string | Absolute image URL. |
assets[].mimeType | string | MIME type of the image. |
assets[].altnullable | string | Alt text for accessibility. |
assets[].captionnullable | string | Free text caption for the image asset. |
assets[].order | number | Display order within the article gallery. |
assets[].createdAt | ISO string | When this asset was attached to the article. |
assets[].updatedAt | ISO string | Last update timestamp for this asset. |
Error Handling
Every failed request returns a JSON body with success: false and a human‑readable error string. Always check the HTTP status code first, then inspect the body for details.
| Status | When it occurs | Response body |
|---|---|---|
| 401 | The Authorization header is missing or malformed, the API key does not exist, or the key has expired. | { "success": false, "error": "Invalid API key" } |
| 404 | The requested article does not exist, is not published, or its publish date is in the future. | { "success": false, "error": "Article not found" } |
| 500 | An unexpected server error occurred. Please verify your request and try again. | { "success": false, "error": "Failed to fetch articles" } |
