Integration reference
Browse RenewCMS API routes, request fields, access requirements and examples.
v3.7.2-beta (opens in a new tab)For your installed version, open Integration in your backoffice or read its /openapi.json.
Examples use cms.example.com. Replace it with your instance URL and keep your API keys on your server.
85 routes
Browse route groups
Articles
Read, write and publish articles. Titles can't be changed after creation.
GET/v1/article/
List one page of articles, newest update first, with the total and the tab counts (all, online, draft and suggestions). Anonymous callers get online articles only.
Access · Public · 200
Query parameters
formatstring · Optional- markdown, html or json. Default markdown.
pagenumber · Optional- A whole number from 1. Default 1.
sizenumber · Optional- 5, 25, 50 or 100. Default 25.
qstring · Optional- Up to 200 characters, matched anywhere in the title, ignoring case and accents.
statusstring · Optional- online or draft. Default both.
sortstring · Optional- field:direction, with field title, status, created_at or updated_at and direction asc or desc. Default updated_at:desc.
sitestring · Optional- The key of a site. Only its articles are listed. An unknown key answers an empty page.
seostring · Optional- ready, suggestions or hidden. Only the articles with that SEO status are listed, before paging; counts stay unfiltered. Any other value is refused.
Request example
curl "https://cms.example.com/v1/article/"Example response
{
"items": [
{
"id": 12,
"title": "How we price a bathroom renovation",
"body": "A bathroom renovation is priced by room size, plumbing changes and finish level.",
"body_format": "markdown",
"is_online": true,
"site_id": 1,
"slug": "how-we-price-a-bathroom-renovation",
"excerpt": "What drives the price of a bathroom renovation.",
"created_at": "2026-03-12T09:14:00Z",
"updated_at": "2026-09-10T07:00:00Z",
"seo_status": "suggestions",
"seo_suggestions": 2
},
{
"id": 13,
"title": "Choosing tiles for a small bathroom",
"body": "Small rooms show every grout line.",
"body_format": "markdown",
"is_online": false,
"site_id": 1,
"slug": "choosing-tiles-for-a-small-bathroom",
"excerpt": "",
"created_at": "2026-03-12T09:14:00Z",
"updated_at": "2026-09-09T07:00:00Z",
"seo_status": "suggestions",
"seo_suggestions": 2
}
],
"total": 30,
"page": 1,
"size": 25,
"counts": {
"all": 30,
"online": 28,
"draft": 2,
"suggestions": 3
}
}Errors
400The request cannot be processed due to a mismatch in the format of the body.400The format must be one of: markdown, html, json.401You must be logged in to access this resource.
GET/v1/article/{id}
Get one article. Drafts answer 404 to anonymous callers.
Access · Public · 200
Query parameters
formatstring · Optional- markdown, html or json. Default markdown.
The example uses resource ID 12.
Request example
curl "https://cms.example.com/v1/article/12"Example response
{
"id": 12,
"title": "How we price a bathroom renovation",
"body": "A bathroom renovation is priced by room size, plumbing changes and finish level.",
"body_format": "markdown",
"is_online": true,
"site_id": 1,
"slug": "how-we-price-a-bathroom-renovation",
"excerpt": "What drives the price of a bathroom renovation.",
"seo_title": "",
"seo_description": "",
"cover_image_id": 4,
"cover_image_alt": "A tiled bathroom wall",
"social_title": "",
"social_description": "",
"social_image_id": null,
"canonical_url": "",
"noindex": false,
"seo_dismissed": [],
"created_at": "2026-03-12T09:14:00Z",
"updated_at": "2026-09-10T07:00:00Z"
}Errors
400The server expects the ID to be in the format of an unsigned 32-bit integer (uint32).404Article not found400The format must be one of: markdown, html, json.401You must be logged in to access this resource.
POST/v1/article/
Create a draft article.
Access · Verified user · 201
Query parameters
formatstring · Optional- markdown, html or json. Default markdown.
Request body
titlestring · Required- 3 to 200 characters. Can't be changed later.
bodystring · Required- Up to 10 000 characters.
Request example
curl -X POST "https://cms.example.com/v1/article/" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…" \
-H "Content-Type: application/json" \
-d '{"title":"Choosing tiles for a small bathroom","body":"Small rooms show every grout line."}'Example response
{
"id": 13,
"title": "Choosing tiles for a small bathroom",
"body": "Small rooms show every grout line.",
"body_format": "markdown",
"is_online": false,
"site_id": 1,
"slug": "how-we-price-a-bathroom-renovation",
"excerpt": "What drives the price of a bathroom renovation.",
"seo_title": "",
"seo_description": "",
"cover_image_id": 4,
"cover_image_alt": "A tiled bathroom wall",
"social_title": "",
"social_description": "",
"social_image_id": null,
"canonical_url": "",
"noindex": false,
"seo_dismissed": [],
"created_at": "2026-03-12T09:14:00Z",
"updated_at": "2026-09-10T07:00:00Z"
}Errors
400The request cannot be processed due to a mismatch in the format of the body.400Article title must be between 3 and 200 characters.400The format must be one of: markdown, html, json.401You must be logged in to access this resource.403You must verify your account to access this resource.
PATCH/v1/article/{id}
Update the body of an article, move it to another site, or edit its SEO fields. Send at least one field; absent fields are untouched.
Access · Verified user · 200
Query parameters
formatstring · Optional- markdown, html or json. Default markdown.
Request body
bodystring · Optional- Up to 10 000 characters. An empty string empties the body; null is refused.
site_idnumber · Optional- The id of an existing site, 1 or more. null is refused.
slugstring · Optional- Lowercase letters, digits and single dashes, 1 to 100 characters, unique on the site. An empty string regenerates it from the title. null is refused.
excerptstring · Optional- Up to 300 characters. An empty string clears it; null is refused.
seo_titlestring · Optional- Up to 120 characters. An empty string clears it; null is refused.
seo_descriptionstring · Optional- Up to 320 characters. An empty string clears it; null is refused.
cover_image_idnumber | null · Optional- The id of an existing image, 1 or more. null removes the cover.
cover_image_altstring · Optional- Up to 200 characters. An empty string clears it; null is refused.
social_titlestring · Optional- Up to 120 characters. An empty string clears it; null is refused.
social_descriptionstring · Optional- Up to 320 characters. An empty string clears it; null is refused.
social_image_idnumber | null · Optional- The id of an existing image, 1 or more. null removes the social image.
canonical_urlstring · Optional- An absolute https address with a host, up to 2048 characters. An empty string clears it; null is refused.
noindexboolean · Optional- Only a flag: the article stays online. null is refused.
seo_dismissedstring[] · Optional- Dismissed suggestion codes: title_long, title_empty, desc_short, desc_long, cover_alt, cover_none, slug_long, no_au, no_h, body_alt, short. Duplicates are collapsed; null is refused.
The example uses resource ID 12.
Request example
curl -X PATCH "https://cms.example.com/v1/article/12" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…" \
-H "Content-Type: application/json" \
-d '{"body":"Updated text.","site_id":2,"slug":"bathroom-pricing","excerpt":"What drives the price.","cover_image_id":4}'Example response
{
"id": 12,
"title": "How we price a bathroom renovation",
"body": "Updated text.",
"body_format": "markdown",
"is_online": false,
"site_id": 1,
"slug": "how-we-price-a-bathroom-renovation",
"excerpt": "What drives the price of a bathroom renovation.",
"seo_title": "",
"seo_description": "",
"cover_image_id": 4,
"cover_image_alt": "A tiled bathroom wall",
"social_title": "",
"social_description": "",
"social_image_id": null,
"canonical_url": "",
"noindex": false,
"seo_dismissed": [],
"created_at": "2026-03-12T09:14:00Z",
"updated_at": "2026-09-10T07:00:00Z"
}Errors
400The request cannot be processed due to a mismatch in the format of the body.400invalid_slug400image_not_found400The server expects the ID to be in the format of an unsigned 32-bit integer (uint32).404Article not found404site_not_found409slug_taken (the X-Slug-Suggestion header holds the first free slug)422invalid_url400The format must be one of: markdown, html, json.401You must be logged in to access this resource.403You must verify your account to access this resource.
PATCH/v1/article/{id}/publish
Publish an article.
Access · Verified user · 200
Query parameters
formatstring · Optional- markdown, html or json. Default markdown.
The example uses resource ID 12.
Request example
curl -X PATCH "https://cms.example.com/v1/article/12/publish" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…"Example response
{
"id": 12,
"title": "How we price a bathroom renovation",
"body": "A bathroom renovation is priced by room size, plumbing changes and finish level.",
"body_format": "markdown",
"is_online": true,
"site_id": 1,
"slug": "how-we-price-a-bathroom-renovation",
"excerpt": "What drives the price of a bathroom renovation.",
"seo_title": "",
"seo_description": "",
"cover_image_id": 4,
"cover_image_alt": "A tiled bathroom wall",
"social_title": "",
"social_description": "",
"social_image_id": null,
"canonical_url": "",
"noindex": false,
"seo_dismissed": [],
"created_at": "2026-03-12T09:14:00Z",
"updated_at": "2026-09-10T07:00:00Z"
}Errors
400The server expects the ID to be in the format of an unsigned 32-bit integer (uint32).404Article not found400The format must be one of: markdown, html, json.401You must be logged in to access this resource.403You must verify your account to access this resource.
PATCH/v1/article/{id}/unpublish
Unpublish an article.
Access · Verified user · 200
Query parameters
formatstring · Optional- markdown, html or json. Default markdown.
The example uses resource ID 12.
Request example
curl -X PATCH "https://cms.example.com/v1/article/12/unpublish" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…"Example response
{
"id": 12,
"title": "How we price a bathroom renovation",
"body": "A bathroom renovation is priced by room size, plumbing changes and finish level.",
"body_format": "markdown",
"is_online": false,
"site_id": 1,
"slug": "how-we-price-a-bathroom-renovation",
"excerpt": "What drives the price of a bathroom renovation.",
"seo_title": "",
"seo_description": "",
"cover_image_id": 4,
"cover_image_alt": "A tiled bathroom wall",
"social_title": "",
"social_description": "",
"social_image_id": null,
"canonical_url": "",
"noindex": false,
"seo_dismissed": [],
"created_at": "2026-03-12T09:14:00Z",
"updated_at": "2026-09-10T07:00:00Z"
}Errors
400The server expects the ID to be in the format of an unsigned 32-bit integer (uint32).404Article not found400The format must be one of: markdown, html, json.401You must be logged in to access this resource.403You must verify your account to access this resource.
DELETE/v1/article/{id}
Delete an article.
Access · Verified user · 204
Query parameters
formatstring · Optional- markdown, html or json. Default markdown.
The example uses resource ID 12.
Request example
curl -X DELETE "https://cms.example.com/v1/article/12" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…"Example response
204 No ContentErrors
400The server expects the ID to be in the format of an unsigned 32-bit integer (uint32).404Article not found400The format must be one of: markdown, html, json.401You must be logged in to access this resource.403You must verify your account to access this resource.
POST/v1/article/{id}/seo/check
Check the SEO of an article without saving anything. Send {} for the saved state, or fields that replace the saved values for this check only.
Access · Verified user · 200
Request body
bodystring · Optional- Replaces the saved body for this check only. null is refused.
slugstring · Optional- Same rules as PATCH. An empty string regenerates it from the title. null is refused.
excerptstring · Optional- Up to 300 characters. null is refused.
seo_titlestring · Optional- Up to 120 characters. null is refused.
seo_descriptionstring · Optional- Up to 320 characters. null is refused.
cover_image_idnumber | null · Optional- The id of an existing image. null means no cover.
cover_image_altstring · Optional- Up to 200 characters. null is refused.
social_titlestring · Optional- Up to 120 characters. null is refused.
social_descriptionstring · Optional- Up to 320 characters. null is refused.
social_image_idnumber | null · Optional- The id of an existing image. null means no social image.
canonical_urlstring · Optional- An absolute https address with a host, up to 2048 characters. null is refused.
noindexboolean · Optional- null is refused.
seo_dismissedstring[] · Optional- Dismissed suggestion codes, replacing the saved list for this check only. null is refused.
The example uses resource ID 12.
Request example
curl -X POST "https://cms.example.com/v1/article/12/seo/check" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…" \
-H "Content-Type: application/json" \
-d '{"seo_title":"Bathroom costs, explained","noindex":false}'Example response
{
"status": "suggestions",
"suggestions": [
{
"code": "desc_short",
"field": "seo_description",
"params": {
"length": 49,
"min": 70
}
},
{
"code": "no_au",
"field": "author_ids",
"params": {}
}
],
"slug": {
"available": false,
"suggestion": "how-we-price-a-bathroom-renovation-2"
}
}Errors
400The request cannot be processed due to a mismatch in the format of the body.400invalid_slug400image_not_found400The server expects the ID to be in the format of an unsigned 32-bit integer (uint32).401You must be logged in to access this resource.404Article not found422invalid_url403You must verify your account to access this resource.
Search and sharing
RenewCMS doesn't render pages or add meta tags. These endpoints give your frontend the resolved SEO data and the list of published URLs.
GET/v1/article/{id}/seo
Get the resolved SEO object of an article: title with the site template applied, description, canonical_url, robots, og, twitter, image, authors, published_at, modified_at, fallbacks and json_ld. Drafts answer 404 to anonymous callers.
Access · Public · 200
The example uses resource ID 12.
Request example
curl "https://cms.example.com/v1/article/12/seo"Example response
{
"title": "How we price a bathroom renovation | Renew",
"description": "What drives the price of a bathroom renovation.",
"canonical_url": "https://blog.renew.example/how-we-price-a-bathroom-renovation",
"robots": "index, follow",
"og": {
"type": "article",
"title": "How we price a bathroom renovation | Renew",
"description": "What drives the price of a bathroom renovation.",
"image": "https://blog.renew.example/static/uploadedImages/3f9c2b7e.jpg",
"image_alt": "A tiled bathroom wall",
"url": "https://blog.renew.example/how-we-price-a-bathroom-renovation",
"site_name": "Renew",
"locale": "en"
},
"twitter": {
"card": "summary_large_image",
"title": "How we price a bathroom renovation | Renew",
"description": "What drives the price of a bathroom renovation.",
"image": "https://blog.renew.example/static/uploadedImages/3f9c2b7e.jpg",
"image_alt": "A tiled bathroom wall"
},
"image": {
"url": "https://blog.renew.example/static/uploadedImages/3f9c2b7e.jpg",
"alt": "A tiled bathroom wall",
"source": "cover"
},
"authors": [
{
"name": "Inès Duarte",
"url": "https://ines-duarte.example",
"same_as": [
"https://github.com/ines-duarte"
]
}
],
"published_at": "2026-03-12T09:14:00Z",
"modified_at": "2026-09-10T07:00:00Z",
"fallbacks": {
"title": "title",
"description": "excerpt",
"image": "cover",
"canonical": "site"
},
"json_ld": {
"@context": "https://schema.org",
"@type": "Article",
"headline": "How we price a bathroom renovation",
"description": "What drives the price of a bathroom renovation.",
"image": [
"https://blog.renew.example/static/uploadedImages/3f9c2b7e.jpg"
],
"author": [
{
"@type": "Person",
"name": "Inès Duarte",
"url": "https://ines-duarte.example",
"sameAs": [
"https://github.com/ines-duarte"
]
}
],
"datePublished": "2026-03-12T09:14:00Z",
"dateModified": "2026-09-10T07:00:00Z",
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https://blog.renew.example/how-we-price-a-bathroom-renovation"
}
}
}Errors
400The server expects the ID to be in the format of an unsigned 32-bit integer (uint32).401You must be logged in to access this resource.404Article not found
GET/v1/site/{key}/sitemap
List the published URLs of a site, by id ascending, as an array of { url, modified_at, noindex }. The total is in the X-Total-Count header.
Access · Public · 200
Query parameters
pagenumber · Optional- A whole number from 1. Default 1.
sizenumber · Optional- 25, 50, 100 or 500. Default 100.
Request example
curl "https://cms.example.com/v1/site/renew-blog/sitemap"Example response
[
{
"url": "https://blog.renew.example/how-we-price-a-bathroom-renovation",
"modified_at": "2026-09-10T07:00:00Z",
"noindex": false
},
{
"url": "https://blog.renew.example/choosing-tiles-for-a-small-bathroom",
"modified_at": "2026-09-09T07:00:00Z",
"noindex": true
}
]Errors
400The request cannot be processed due to a mismatch in the format of the body.401You must be logged in to access this resource.404site_not_found
Content types
Define your own kind of content, like events or recipes. A user whose role can create and edit content types defines a type made of 1 to 50 ordered fields; the type then has its own entry routes.
GET/v1/content-type/
List all custom content types.
Access · Verified user · 200
Request example
curl "https://cms.example.com/v1/content-type/" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…"Example response
[
{
"id": 2,
"key": "events",
"name": "Events",
"icon": "calendar",
"fields": [
{
"key": "title",
"label": "Title",
"type": "text",
"required": true,
"unique": false,
"default": null,
"min": 3,
"max": 120,
"options": null,
"relation": null
},
{
"key": "starts_on",
"label": "Starts on",
"type": "date",
"required": true,
"unique": false,
"default": null,
"min": null,
"max": null,
"options": null,
"relation": null
},
{
"key": "capacity",
"label": "Capacity",
"type": "number",
"required": true,
"unique": false,
"default": null,
"min": 1,
"max": 5000,
"options": null,
"relation": null
}
],
"created_at": "2026-09-02T08:30:00Z",
"updated_at": "2026-10-20T14:05:00Z"
}
]Errors
401You must be logged in to access this resource.403You must verify your account to access this resource.
GET/v1/content-type/{key}
Get one content type with its fields.
Access · Verified user · 200
Request example
curl "https://cms.example.com/v1/content-type/events" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…"Example response
{
"id": 2,
"key": "events",
"name": "Events",
"icon": "calendar",
"fields": [
{
"key": "title",
"label": "Title",
"type": "text",
"required": true,
"unique": false,
"default": null,
"min": 3,
"max": 120,
"options": null,
"relation": null
},
{
"key": "starts_on",
"label": "Starts on",
"type": "date",
"required": true,
"unique": false,
"default": null,
"min": null,
"max": null,
"options": null,
"relation": null
},
{
"key": "capacity",
"label": "Capacity",
"type": "number",
"required": true,
"unique": false,
"default": null,
"min": 1,
"max": 5000,
"options": null,
"relation": null
},
{
"key": "online",
"label": "Online",
"type": "boolean",
"required": false,
"unique": false,
"default": null,
"min": null,
"max": null,
"options": null,
"relation": null
},
{
"key": "category",
"label": "Category",
"type": "select",
"required": false,
"unique": false,
"default": null,
"min": null,
"max": null,
"options": [
"Workshop",
"Talk",
"Open day"
],
"relation": null
},
{
"key": "cover",
"label": "Cover",
"type": "media",
"required": false,
"unique": false,
"default": null,
"min": null,
"max": null,
"options": null,
"relation": null
}
],
"created_at": "2026-09-02T08:30:00Z",
"updated_at": "2026-10-20T14:05:00Z"
}Errors
401You must be logged in to access this resource.403You must verify your account to access this resource.404content_type_not_found
POST/v1/content-type/
Create a content type. Needs the permission "Create and edit content types".
Access · Needs permission · 201
Request body
keystring · Required- 2 to 40 characters. Lowercase letters, digits and hyphens. Can't be changed later.
namestring · Required- Up to 100 characters.
iconstring · Optional- Optional.
fieldsobject[] · Required- 1 to 50 fields, in order. See Field types.
Request example
curl -X POST "https://cms.example.com/v1/content-type/" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…" \
-H "Content-Type: application/json" \
-d '{
"key": "events",
"name": "Events",
"icon": "calendar",
"fields": [
{
"key": "title",
"label": "Title",
"type": "text",
"required": true,
"unique": false,
"default": null,
"min": 3,
"max": 120,
"options": null,
"relation": null
},
{
"key": "starts_on",
"label": "Starts on",
"type": "date",
"required": true,
"unique": false,
"default": null,
"min": null,
"max": null,
"options": null,
"relation": null
},
{
"key": "capacity",
"label": "Capacity",
"type": "number",
"required": true,
"unique": false,
"default": null,
"min": 1,
"max": 5000,
"options": null,
"relation": null
}
]
}'Example response
{
"id": 2,
"key": "events",
"name": "Events",
"icon": "calendar",
"fields": [
{
"key": "title",
"label": "Title",
"type": "text",
"required": true,
"unique": false,
"default": null,
"min": 3,
"max": 120,
"options": null,
"relation": null
},
{
"key": "starts_on",
"label": "Starts on",
"type": "date",
"required": true,
"unique": false,
"default": null,
"min": null,
"max": null,
"options": null,
"relation": null
},
{
"key": "capacity",
"label": "Capacity",
"type": "number",
"required": true,
"unique": false,
"default": null,
"min": 1,
"max": 5000,
"options": null,
"relation": null
},
{
"key": "online",
"label": "Online",
"type": "boolean",
"required": false,
"unique": false,
"default": null,
"min": null,
"max": null,
"options": null,
"relation": null
},
{
"key": "category",
"label": "Category",
"type": "select",
"required": false,
"unique": false,
"default": null,
"min": null,
"max": null,
"options": [
"Workshop",
"Talk",
"Open day"
],
"relation": null
},
{
"key": "cover",
"label": "Cover",
"type": "media",
"required": false,
"unique": false,
"default": null,
"min": null,
"max": null,
"options": null,
"relation": null
}
],
"created_at": "2026-09-02T08:30:00Z",
"updated_at": "2026-10-20T14:05:00Z"
}Errors
400The request cannot be processed due to a mismatch in the format of the body.401You must be logged in to access this resource.403missing_permission409content_type_key_taken
PUT/v1/content-type/{key}
Replace the name, icon and fields of a type. The key never changes. Saved field keys and types can't change. Needs the permission "Create and edit content types".
Access · Needs permission · 200
Request body
namestring · Required- Up to 100 characters.
iconstring · Optional- Optional.
fieldsobject[] · Required- 1 to 50 fields, in order. See Field types.
Request example
curl -X PUT "https://cms.example.com/v1/content-type/events" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…" \
-H "Content-Type: application/json" \
-d '{
"name": "Events",
"icon": "calendar",
"fields": [
{
"key": "title",
"label": "Title",
"type": "text",
"required": true,
"unique": false,
"default": null,
"min": 3,
"max": 120,
"options": null,
"relation": null
},
{
"key": "starts_on",
"label": "Starts on",
"type": "date",
"required": true,
"unique": false,
"default": null,
"min": null,
"max": null,
"options": null,
"relation": null
},
{
"key": "capacity",
"label": "Capacity",
"type": "number",
"required": true,
"unique": false,
"default": null,
"min": 1,
"max": 5000,
"options": null,
"relation": null
}
]
}'Example response
{
"id": 2,
"key": "events",
"name": "Events",
"icon": "calendar",
"fields": [
{
"key": "title",
"label": "Title",
"type": "text",
"required": true,
"unique": false,
"default": null,
"min": 3,
"max": 120,
"options": null,
"relation": null
},
{
"key": "starts_on",
"label": "Starts on",
"type": "date",
"required": true,
"unique": false,
"default": null,
"min": null,
"max": null,
"options": null,
"relation": null
},
{
"key": "capacity",
"label": "Capacity",
"type": "number",
"required": true,
"unique": false,
"default": null,
"min": 1,
"max": 5000,
"options": null,
"relation": null
},
{
"key": "online",
"label": "Online",
"type": "boolean",
"required": false,
"unique": false,
"default": null,
"min": null,
"max": null,
"options": null,
"relation": null
},
{
"key": "category",
"label": "Category",
"type": "select",
"required": false,
"unique": false,
"default": null,
"min": null,
"max": null,
"options": [
"Workshop",
"Talk",
"Open day"
],
"relation": null
},
{
"key": "cover",
"label": "Cover",
"type": "media",
"required": false,
"unique": false,
"default": null,
"min": null,
"max": null,
"options": null,
"relation": null
}
],
"created_at": "2026-09-02T08:30:00Z",
"updated_at": "2026-10-20T14:05:00Z"
}Errors
400The request cannot be processed due to a mismatch in the format of the body.401You must be logged in to access this resource.403missing_permission404content_type_not_found409schema_incompatible Some existing entries don't fit the new fields. Nothing was changed.
DELETE/v1/content-type/{key}
Delete a content type. Only possible when it has no entries and no relation field points at it. Needs the permission "Delete content types".
Access · Needs permission · 204
Request example
curl -X DELETE "https://cms.example.com/v1/content-type/events" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…"Example response
204 No ContentErrors
401You must be logged in to access this resource.403missing_permission404content_type_not_found409content_type_has_entries409content_type_referenced
Entries
Read and write the content of a custom type. Each route needs the matching content permission of the key creator's role.
GET/v1/content-type/{key}/entry
List entries of a type, one page at a time. The response is an object with items, total, page and size, not a bare array like articles.
Access · Verified user · 200
Query parameters
pageinteger · Optional- 1 or higher. Default 1.
sizeinteger · Optional- One of 5, 25, 50 or 100. Default 25.
sortstring · Optional- id, created_at or updated_at, then :asc or :desc. For example updated_at:desc.
Request example
curl "https://cms.example.com/v1/content-type/events/entry" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…"Example response
{
"items": [
{
"id": 31,
"content_type": "events",
"data": {
"title": "Open day",
"starts_on": "2026-11-14",
"capacity": 120,
"online": false,
"category": "Open day",
"cover": 4
},
"created_by": 1,
"updated_by": 1,
"created_at": "2026-10-20T14:05:00Z",
"updated_at": "2026-10-22T09:41:00Z",
"media": {
"cover": {
"id": 4,
"filename": "north-wall.jpg",
"width": 1600,
"height": 1067,
"size": 3900000,
"thumbnail_url": "/static/uploadedImages/3f9c-thumb.jpg"
}
},
"relations": {}
}
],
"total": 1,
"page": 1,
"size": 25
}Errors
400Invalid page, size or sort.401You must be logged in to access this resource.403You must verify your account to access this resource.404content_type_not_found
POST/v1/content-type/{key}/entry
Create an entry.
Access · Verified user · 201
Request body
dataobject · Required- Keys are the type's field keys. For events: title, starts_on, capacity, online, category and cover.
Request example
curl -X POST "https://cms.example.com/v1/content-type/events/entry" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…" \
-H "Content-Type: application/json" \
-d '{"data":{"title":"Open day","starts_on":"2026-11-14","capacity":120,"online":false,"category":"Open day","cover":4}}'Example response
{
"id": 31,
"content_type": "events",
"data": {
"title": "Open day",
"starts_on": "2026-11-14",
"capacity": 120,
"online": false,
"category": "Open day",
"cover": 4
},
"created_by": 1,
"updated_by": 1,
"created_at": "2026-10-20T14:05:00Z",
"updated_at": "2026-10-22T09:41:00Z",
"media": {
"cover": {
"id": 4,
"filename": "north-wall.jpg",
"width": 1600,
"height": 1067,
"size": 3900000,
"thumbnail_url": "/static/uploadedImages/3f9c-thumb.jpg"
}
},
"relations": {}
}Errors
400The request cannot be processed due to a mismatch in the format of the body.401You must be logged in to access this resource.403You must verify your account to access this resource.404content_type_not_found409invalid_entry: title must be unique422invalid_entry: capacity must be at most 5000
GET/v1/content-type/{key}/entry/{id}
Get one entry.
Access · Verified user · 200
The example uses resource ID 31.
Request example
curl "https://cms.example.com/v1/content-type/events/entry/31" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…"Example response
{
"id": 31,
"content_type": "events",
"data": {
"title": "Open day",
"starts_on": "2026-11-14",
"capacity": 120,
"online": false,
"category": "Open day",
"cover": 4
},
"created_by": 1,
"updated_by": 1,
"created_at": "2026-10-20T14:05:00Z",
"updated_at": "2026-10-22T09:41:00Z",
"media": {
"cover": {
"id": 4,
"filename": "north-wall.jpg",
"width": 1600,
"height": 1067,
"size": 3900000,
"thumbnail_url": "/static/uploadedImages/3f9c-thumb.jpg"
}
},
"relations": {}
}Errors
400The server expects the ID to be in the format of an unsigned 32-bit integer (uint32).401You must be logged in to access this resource.403You must verify your account to access this resource.404entry_not_found404content_type_not_found
PUT/v1/content-type/{key}/entry/{id}
Replace the data of an entry.
Access · Verified user · 200
Request body
dataobject · Required- Keys are the type's field keys. For events: title, starts_on, capacity, online, category and cover.
The example uses resource ID 31.
Request example
curl -X PUT "https://cms.example.com/v1/content-type/events/entry/31" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…" \
-H "Content-Type: application/json" \
-d '{"data":{"title":"Open day","starts_on":"2026-11-14","capacity":150,"online":false,"category":"Open day","cover":4}}'Example response
{
"id": 31,
"content_type": "events",
"data": {
"title": "Open day",
"starts_on": "2026-11-14",
"capacity": 150,
"online": false,
"category": "Open day",
"cover": 4
},
"created_by": 1,
"updated_by": 1,
"created_at": "2026-10-20T14:05:00Z",
"updated_at": "2026-10-22T09:41:00Z",
"media": {
"cover": {
"id": 4,
"filename": "north-wall.jpg",
"width": 1600,
"height": 1067,
"size": 3900000,
"thumbnail_url": "/static/uploadedImages/3f9c-thumb.jpg"
}
},
"relations": {}
}Errors
400The request cannot be processed due to a mismatch in the format of the body.401You must be logged in to access this resource.403You must verify your account to access this resource.404entry_not_found404content_type_not_found409invalid_entry: title must be unique422invalid_entry: capacity must be at most 5000
DELETE/v1/content-type/{key}/entry/{id}
Delete an entry.
Access · Verified user · 204
The example uses resource ID 31.
Request example
curl -X DELETE "https://cms.example.com/v1/content-type/events/entry/31" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…"Example response
204 No ContentErrors
401You must be logged in to access this resource.403You must verify your account to access this resource.404entry_not_found404content_type_not_found
Built-in types
The fields of Articles, Authors, Sites, Media and Users, in the same shape as the fields of a content type.
GET/v1/builtin-type/
List the built-in types (Articles, Authors, Sites, Media, Users) and their fields. Keys are article, author, site, media and user. Needs the permission "View content types".
Access · Needs permission · 200
Request example
curl "https://cms.example.com/v1/builtin-type/" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…"Example response
[
{
"key": "article",
"name": "Articles",
"fields": [
{
"key": "title",
"label": "Title",
"type": "text",
"required": true,
"unique": false,
"default": null,
"min": 3,
"max": 200,
"options": null,
"relation": null
},
{
"key": "slug",
"label": "Slug",
"type": "text",
"required": true,
"unique": true,
"default": null,
"min": null,
"max": null,
"options": null,
"relation": null
},
{
"key": "body",
"label": "Body",
"type": "richtext",
"required": false,
"unique": false,
"default": null,
"min": null,
"max": null,
"options": null,
"relation": null
}
]
},
{
"key": "author",
"name": "Authors",
"fields": [
{
"key": "name",
"label": "Name",
"type": "text",
"required": true,
"unique": false,
"default": null,
"min": 1,
"max": 100,
"options": null,
"relation": null
},
{
"key": "slug",
"label": "Slug",
"type": "text",
"required": true,
"unique": true,
"default": null,
"min": null,
"max": null,
"options": null,
"relation": null
}
]
}
]Errors
401You must be logged in to access this resource.403missing_permission
GET/v1/builtin-type/{key}
Get one built-in type. Keys are article, author, site, media and user. Needs the permission "View content types".
Access · Needs permission · 200
Request example
curl "https://cms.example.com/v1/builtin-type/author" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…"Example response
{
"key": "author",
"name": "Authors",
"fields": [
{
"key": "name",
"label": "Name",
"type": "text",
"required": true,
"unique": false,
"default": null,
"min": 1,
"max": 100,
"options": null,
"relation": null
},
{
"key": "slug",
"label": "Slug",
"type": "text",
"required": true,
"unique": true,
"default": null,
"min": null,
"max": null,
"options": null,
"relation": null
}
]
}Errors
401You must be logged in to access this resource.403missing_permission404builtin_type_not_found
Media
The image library. One image can be used in many articles.
GET/v1/media/
List images.
Access · Verified user · 200
Query parameters
qstring · Optional- Search text.
hashstring · Optional- SHA-256 of the content, lowercased.
filterstring · Optional- all, unused or duplicates. Default all.
sortstring · Optional- newest, oldest, name, largest or total_size. Default newest.
variantsstring · Optional- with or without. Default both.
pagenumber · Optional- A whole number from 1. Default 1.
sizenumber · Optional- 5, 25, 50 or 100. Default 25.
Request example
curl "https://cms.example.com/v1/media/" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…"Example response
{
"items": [
{
"id": 4,
"filename": "north-wall.jpg",
"url": "/static/uploadedImages/3f9c2b7e-5d1a-4c8e-9b0f-6a2d4e8c1b73.jpg",
"size": 3900000,
"content_type": "image/jpeg",
"width": 4032,
"height": 3024,
"sha256": "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9",
"uploaded_by": "marta",
"created_at": "2026-09-10T07:00:00Z",
"used_in": 2,
"duplicate": false
}
],
"total": 1,
"page": 1,
"size": 25,
"counts": {
"all": 1,
"unused": 0,
"duplicates": 0
}
}Errors
400The media query is invalid.401You must be logged in to access this resource.403You must verify your account to access this resource.
GET/v1/media/{id}
Get one image, with the same fields as an item of the list.
Access · Verified user · 200
The example uses resource ID 4.
Request example
curl "https://cms.example.com/v1/media/4" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…"Example response
{
"id": 4,
"filename": "north-wall.jpg",
"url": "/static/uploadedImages/3f9c2b7e-5d1a-4c8e-9b0f-6a2d4e8c1b73.jpg",
"size": 3900000,
"content_type": "image/jpeg",
"width": 4032,
"height": 3024,
"sha256": "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9",
"uploaded_by": "marta",
"created_at": "2026-09-10T07:00:00Z",
"used_in": 2,
"duplicate": false
}Errors
400The server expects the ID to be in the format of an unsigned 32-bit integer (uint32).401You must be logged in to access this resource.404Image not found403You must verify your account to access this resource.
POST/v1/media/
Upload an image (multipart).
Access · Verified user · 201
Request body
filefile · Required- PNG, JPEG, WEBP or SVG.
Request example
curl -X POST "https://cms.example.com/v1/media/" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…" \
-F "file=@north-wall.jpg"Example response
{
"id": 4,
"filename": "north-wall.jpg",
"url": "/static/uploadedImages/3f9c2b7e-5d1a-4c8e-9b0f-6a2d4e8c1b73.jpg",
"size": 3900000,
"content_type": "image/jpeg",
"width": 4032,
"height": 3024,
"sha256": "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9",
"uploaded_by": "marta",
"created_at": "2026-09-10T07:00:00Z",
"used_in": 2,
"duplicate": false
}Errors
400the image could not be read401You must be logged in to access this resource.413the file exceeds the maximum upload size415the file must be a PNG, JPEG, WEBP, or SVG image403You must verify your account to access this resource.
PATCH/v1/media/{id}
Rename an image. The URL stays the same.
Access · Verified user · 200
Request body
filenamestring · Required- The new filename.
The example uses resource ID 4.
Request example
curl -X PATCH "https://cms.example.com/v1/media/4" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…" \
-H "Content-Type: application/json" \
-d '{"filename":"north-wall-01.jpg"}'Example response
{
"id": 4,
"filename": "north-wall-01.jpg",
"url": "/static/uploadedImages/3f9c2b7e-5d1a-4c8e-9b0f-6a2d4e8c1b73.jpg",
"size": 3900000,
"content_type": "image/jpeg",
"width": 4032,
"height": 3024,
"sha256": "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9",
"uploaded_by": "marta",
"created_at": "2026-09-10T07:00:00Z",
"used_in": 2,
"duplicate": false
}Errors
400Enter a filename.400The server expects the ID to be in the format of an unsigned 32-bit integer (uint32).401You must be logged in to access this resource.404Image not found403You must verify your account to access this resource.
DELETE/v1/media/{id}
Delete an image. Articles that use it show a broken image.
Access · Verified user · 204
The example uses resource ID 4.
Request example
curl -X DELETE "https://cms.example.com/v1/media/4" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…"Example response
204 No ContentErrors
400The server expects the ID to be in the format of an unsigned 32-bit integer (uint32).401You must be logged in to access this resource.404Image not found403You must verify your account to access this resource.
POST/v1/media/merge
Merge identical copies into one image.
Access · Verified user · 200
Request body
keep_idnumber · Required- Greater than 0. The image to keep.
merge_idsnumber[] · Required- At least 1, each greater than 0. Identical copies to delete. Articles switch to the kept image.
Request example
curl -X POST "https://cms.example.com/v1/media/merge" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…" \
-H "Content-Type: application/json" \
-d '{"keep_id":4,"merge_ids":[9,11]}'Example response
{
"articles_updated": 5,
"sites_updated": 1,
"merged": 2
}Errors
400Choose an image to keep and at least one other image to merge into it.401You must be logged in to access this resource.409Some of the images to merge changed. Refresh and try again.403You must verify your account to access this resource.
GET/v1/media/{id}/usage
List the articles, authors and sites that use an image, with the places where each one uses it.
Access · Verified user · 200
The example uses resource ID 4.
Request example
curl "https://cms.example.com/v1/media/4/usage" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…"Example response
[
{
"type": "article",
"id": 12,
"title": "How we price a bathroom renovation",
"published": true,
"fields": [
"body",
"cover"
]
},
{
"type": "author",
"id": 2,
"title": "Inès Duarte",
"fields": [
"avatar"
]
},
{
"type": "site",
"id": 1,
"title": "Renew blog",
"fields": [
"default_social_image"
]
}
]Errors
400The server expects the ID to be in the format of an unsigned 32-bit integer (uint32).401You must be logged in to access this resource.404Image not found403You must verify your account to access this resource.
GET/v1/media/purge-settings
Get the automatic duplicate purge settings. Needs the permission "View settings".
Access · Needs permission · 200
Request example
curl "https://cms.example.com/v1/media/purge-settings" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…"Example response
{
"auto_purge_enabled": true,
"auto_purge_interval_days": 30,
"last_purge_at": "2026-09-10T07:00:00Z",
"last_purge_merged": 2,
"last_purge_articles_updated": 5,
"enabled_at": "2026-08-11T07:00:00Z",
"next_purge_at": "2026-10-09T07:00:00Z"
}Errors
401You must be logged in to access this resource.403missing_permission
PATCH/v1/media/purge-settings
Turn the automatic purge on or off, or change its interval. Needs the permission "Edit general settings".
Access · Needs permission · 200
Request body
auto_purge_enabledboolean · Optional- Leave out to keep the current value.
auto_purge_interval_daysnumber · Optional- 1 to 365. Leave out to keep the current value.
Request example
curl -X PATCH "https://cms.example.com/v1/media/purge-settings" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…" \
-H "Content-Type: application/json" \
-d '{"auto_purge_enabled":true,"auto_purge_interval_days":30}'Example response
{
"auto_purge_enabled": true,
"auto_purge_interval_days": 30,
"last_purge_at": "2026-09-10T07:00:00Z",
"last_purge_merged": 2,
"last_purge_articles_updated": 5,
"enabled_at": "2026-08-11T07:00:00Z",
"next_purge_at": "2026-10-09T07:00:00Z"
}Errors
400The request cannot be processed due to a mismatch in the format of the body.400Enter a whole number of days between 1 and 365.401You must be logged in to access this resource.403missing_permission
GET/v1/media/purge-preview
Preview what a purge would merge. Nothing changes. Needs the permission "Delete files".
Access · Needs permission · 200
Request example
curl "https://cms.example.com/v1/media/purge-preview" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…"Example response
{
"groups": 1,
"copies": 2,
"articles": 5,
"list": [
{
"keep_id": 4,
"filename": "north-wall.jpg",
"url": "/static/uploadedImages/3f9c2b7e-5d1a-4c8e-9b0f-6a2d4e8c1b73.jpg",
"used_in": 5,
"merged": 2
}
],
"more": 0,
"fingerprint": "9c1f5e0a7d3b"
}Errors
401You must be logged in to access this resource.403missing_permission
POST/v1/media/purge
Merge every group of identical copies. Send the preview fingerprint to refuse a changed library. failed_groups counts groups that could not be purged; the others were still purged. Needs the permission "Delete files".
Access · Needs permission · 200
Request body
fingerprintstring · Optional- The fingerprint of the preview. Without it, the purge runs on the current library.
Request example
curl -X POST "https://cms.example.com/v1/media/purge" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…" \
-H "Content-Type: application/json" \
-d '{"fingerprint":"9c1f5e0a7d3b"}'Example response
{
"groups_total": 1,
"groups_purged": 1,
"merged": 2,
"articles_updated": 5,
"sites_updated": 1,
"authors_updated": 0,
"failed_groups": 0
}Errors
400The request cannot be processed due to a mismatch in the format of the body.409The library changed, so nothing was purged. Check the new summary and try again.409A purge is already running.401You must be logged in to access this resource.403missing_permission
Sites and authors
Read the sites and authors your content belongs to. Creating and changing them needs a session.
GET/v1/site/
List the sites, the default first and then by name, each with its article count. Without page or size every matching site is returned; the number of matching sites is in the X-Total-Count header.
Access · Verified user · 200
Query parameters
pagenumber · Optional- A whole number from 1. Default 1.
sizenumber · Optional- 5, 25, 50 or 100. Default 25.
qstring · Optional- Up to 200 characters, matched in the name, the key or the base URL, ignoring case and accents.
Request example
curl "https://cms.example.com/v1/site/" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…"Example response
[
{
"id": 1,
"name": "Renew blog",
"key": "renew-blog",
"base_url": "https://blog.renew.example",
"default_social_image_id": 4,
"default_robots": "index",
"locale": "en",
"is_default": true,
"article_count": 30,
"site_name": "Renew",
"title_template": "%title% | %site%",
"default_description": "Notes from a renovation site."
},
{
"id": 2,
"name": "Renew shop",
"key": "renew-shop",
"base_url": "https://shop.renew.example",
"default_social_image_id": null,
"default_robots": "noindex",
"locale": null,
"is_default": false,
"article_count": 4,
"site_name": "",
"title_template": "%title% - %site%",
"default_description": ""
}
]Errors
400The request cannot be processed due to a mismatch in the format of the body.401You must be logged in to access this resource.403You must verify your account to access this resource.
Users and invites
People who can sign in, and pending invitations.
GET/v1/user/
List users and invites.
Access · Verified user · 200
Request example
curl "https://cms.example.com/v1/user/" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…"Example response
[
{
"id": 1,
"kind": "user",
"username": "marta",
"display_name": "Marta Alves",
"email": "marta@renew.example",
"role": {
"id": 1,
"name": "Owner",
"built_in": true,
"locked": true
},
"status": "accepted",
"created_at": "2026-01-05T08:30:00Z"
},
{
"id": 7,
"kind": "invite",
"email": "lea.martin@renew.example",
"role": {
"id": 3,
"name": "Writer",
"built_in": true,
"locked": false
},
"status": "pending",
"created_at": "2026-09-10T07:00:00Z"
}
]Errors
401You must be logged in to access this resource.403You must verify your account to access this resource.
PATCH/v1/user/me
Update my profile.
Access · Verified user · 200
Request body
display_namestring · Required- Up to 60 characters.
Request example
curl -X PATCH "https://cms.example.com/v1/user/me" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…" \
-H "Content-Type: application/json" \
-d '{"display_name":"Marta Alves"}'Example response
{
"id": 1,
"username": "marta",
"email": "marta@renew.example",
"is_verified": true,
"created_at": "2026-01-05T08:30:00Z",
"updated_at": "2026-09-10T07:00:00Z",
"display_name": "Marta Alves"
}Errors
400The request cannot be processed due to a mismatch in the format of the body.400Display name must be 60 characters or fewer.401You must be logged in to access this resource.403You must verify your account to access this resource.
POST/v1/user/invite
Invite a user by email.
Access · Owner only · 201 · Rate limited
Request body
emailstring · Required- A valid email address.
role_idnumber · Optional- The id of the role to give. Absent or 0 means the Writer role. The Owner role is refused.
Request example
curl -X POST "https://cms.example.com/v1/user/invite" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…" \
-H "Content-Type: application/json" \
-d '{"email":"lea.martin@renew.example","role_id":3}'Example response
{
"id": 7,
"kind": "invite",
"email": "lea.martin@renew.example",
"role": {
"id": 3,
"name": "Writer",
"built_in": true,
"locked": false
},
"status": "pending",
"created_at": "2026-09-10T07:00:00Z",
"expires_at": "2026-09-13T07:00:00Z"
}Errors
400The request cannot be processed due to a mismatch in the format of the body.401You must be logged in to access this resource.409This address already has an account.409There's already a pending invite for this address.403missing_permission429Too many requests. Please try again later.
DELETE/v1/user/invite/{id}
Cancel a pending invite.
Access · Owner only · 204 · Rate limited
The example uses resource ID 7.
Request example
curl -X DELETE "https://cms.example.com/v1/user/invite/7" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…"Example response
204 No ContentErrors
400The server expects the ID to be in the format of an unsigned 32-bit integer (uint32).401You must be logged in to access this resource.404Invite not found403missing_permission429Too many requests. Please try again later.
POST/v1/user/invite/{id}/renew
Renew an expired invite.
Access · Owner only · 200 · Rate limited
The example uses resource ID 7.
Request example
curl -X POST "https://cms.example.com/v1/user/invite/7/renew" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…"Example response
{
"id": 7,
"kind": "invite",
"email": "lea.martin@renew.example",
"role": {
"id": 3,
"name": "Writer",
"built_in": true,
"locked": false
},
"status": "pending",
"created_at": "2026-09-10T07:00:00Z",
"expires_at": "2026-09-13T07:00:00Z"
}Errors
400The server expects the ID to be in the format of an unsigned 32-bit integer (uint32).401You must be logged in to access this resource.404Invite not found409This invite has already been accepted.403missing_permission429Too many requests. Please try again later.
GET/v1/auth/me
Get the current user. With a key, the key's owner.
Access · Verified user · 200
Request example
curl "https://cms.example.com/v1/auth/me" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…"Example response
{
"id": 1,
"username": "marta",
"email": "marta@renew.example",
"is_verified": true,
"created_at": "2026-01-05T08:30:00Z",
"updated_at": "2026-09-10T07:00:00Z",
"display_name": "Marta Alves",
"author": null,
"access": {
"role": {
"id": 1,
"name": "Owner",
"built_in": true,
"locked": true
},
"permissions": [
{
"key": "content.read",
"scope": "all"
},
{
"key": "content.create",
"scope": "all"
},
{
"key": "content.update",
"scope": "all"
},
{
"key": "content.delete",
"scope": "all"
},
{
"key": "content.publish",
"scope": "all"
},
{
"key": "settings.view",
"scope": "all"
},
{
"key": "users.view",
"scope": "all"
},
{
"key": "content.update:article",
"scope": "own"
}
]
}
}Errors
401You must be logged in to access this resource.
Settings
Read the site settings, including the activity log retention.
GET/v1/settings
Get settings.
Access · Verified user · 200
Request example
curl "https://cms.example.com/v1/settings" \
-H "Authorization: Bearer rcms_Kf3x9QwL0aBc…"Example response
{
"version": "v3.0.0-beta",
"activity_retention_days": 90,
"activity_retention_max_gb": 5,
"activity_log_size_bytes": 3435973837,
"activity_last_cleanup_at": "2026-09-10T03:00:00Z",
"activity_last_cleanup_removed": 12,
"activity_next_cleanup_at": "2026-09-11T03:00:00Z"
}Errors
401You must be logged in to access this resource.403You must verify your account to access this resource.
Public and sign-in routes
- GET
/v1/Hello world. - GET
/v1/auth/registrationWhether registration is open. - POST
/v1/auth/password-reset/confirmSet a new password with the emailed code. - GET
/v1/auth/inviteCheck an invite code. - POST
/v1/auth/invite/acceptAccept an invite. - GET
/healthzPlain text "ok". Outside /v1.
System · owner only
These routes use a browser session. See your instance’s reference for details.
- GET
/v1/system/updateUpdate status - POST
/v1/system/update/checkCheck for update - POST
/v1/system/update/downloadDownload update - POST
/v1/system/update/restartRestart - PATCH
/v1/settingsChange the activity log retention
Sign in and account
These routes use a browser session. See your instance’s reference for details.
- POST
/v1/auth/loginLog in. Made for the browser. A key is ignored here, with no 403. - POST
/v1/auth/logoutLog out. Made for the browser. A key is ignored here, with no 403. - POST
/v1/auth/registerRegister. Made for the browser. A key is ignored here, with no 403. - POST
/v1/auth/verifyVerify email - DELETE
/v1/auth/registerCancel registration - POST
/v1/auth/password-resetReset password. Made for the browser. A key is ignored here, with no 403.
API key management
These routes use a browser session. See your instance’s reference for details.
- GET
/v1/api-keyList keys - POST
/v1/api-keyCreate a key - DELETE
/v1/api-key/{id}Revoke a key
Sites and authors writes
These routes use a browser session. See your instance’s reference for details.
- POST
/v1/site/Create a site - PATCH
/v1/site/{id}Edit a site - PATCH
/v1/site/{id}/defaultMake a site the default - DELETE
/v1/site/{id}Delete a site, moving its articles with reassign_to - POST
/v1/author/Create an author - PATCH
/v1/author/{id}Edit an author, or your own author as a verified user - DELETE
/v1/author/{id}Delete an author, moving its articles with reassign_to - POST
/v1/author/meCreate your own author profile, as any verified user
Image variants
These routes use a browser session. See your instance’s reference for details.
- GET
/v1/image-variants/List variants - POST
/v1/image-variants/Create a variant - PUT
/v1/image-variants/{name}Replace a variant - PATCH
/v1/image-variants/{name}Update a variant - DELETE
/v1/image-variants/{name}Delete a variant - POST
/v1/image-variants/{name}/purgePurge the cache of a variant - GET
/v1/image-variants/cacheImage cache status - POST
/v1/image-variants/cache/purgePurge the image cache - GET
/v1/media/{id}/variantsList the variants of an image - POST
/v1/media/{id}/variantsAdd variants to an image - POST
/v1/media/{id}/variants/{name}Generate one variant of an image - DELETE
/v1/media/{id}/variants/{name}Delete one variant of an image
Activity
These routes use a browser session. See your instance’s reference for details.
- GET
/v1/activityList activity events - GET
/v1/activity/summaryActivity summary, owner and admin - GET
/v1/activity/exportExport activity as CSV, owner and admin