REST API CMS Parts

Listing parts for a page

GET /cms/pages/:page_id/parts.xml
GET /cms/pages/:page_id/parts.json

Returns all CMS parts belonging to a page, ordered by name. The :page_id parameter accepts the page name or numeric ID.

Examples:

GET /cms/pages/home/parts.xml
GET /cms/pages/home/parts.json
GET /cms/pages/1/parts.xml

Response:

<?xml version="1.0" encoding="UTF-8"?>
<cms_parts type="array">
  <cms_part>
    <id>1</id>
    <name>content</name>
    <description>Main content area</description>
    <content>h1. Welcome</content>
    <filter>textile</filter>
    <status id="1" name="active"/>
    <is_cached>false</is_cached>
    <position>1</position>
    <page id="1" name="home"/>
    <created_at>2024-01-01T10:00:00Z</created_at>
    <updated_at>2024-06-01T12:00:00Z</updated_at>
  </cms_part>
  <cms_part>
    <id>2</id>
    <name>sidebar</name>
    <description>Right sidebar</description>
    <content>h3. Related Links</content>
    <filter>textile</filter>
    <status id="1" name="active"/>
    <is_cached>false</is_cached>
    <position>2</position>
    <page id="1" name="home"/>
    <created_at>2024-01-01T10:00:00Z</created_at>
    <updated_at>2024-06-01T12:00:00Z</updated_at>
  </cms_part>
</cms_parts>

Showing a part

GET /cms/parts/:id.xml
GET /cms/parts/:id.json

Returns a single CMS part. The :id can be a numeric ID or part name.

Public rendering endpoint (no API key required, returns rendered HTML):

GET /pages/:page_id/parts/:name

Examples:

GET /cms/parts/1.xml
GET /cms/parts/1.json

# Public render - returns rendered HTML output
GET /pages/home/parts/content
GET /pages/home/parts/sidebar

Response:

<?xml version="1.0" encoding="UTF-8"?>
<cms_part>
  <id>1</id>
  <name>content</name>
  <description>Main content area</description>
  <content>h1. Welcome</content>
  <filter>textile</filter>
  <status id="1" name="active"/>
  <is_cached>false</is_cached>
  <position>1</position>
  <page id="1" name="home"/>
  <created_at>2024-01-01T10:00:00Z</created_at>
  <updated_at>2024-06-01T12:00:00Z</updated_at>
</cms_part>

Creating a part

POST /cms/parts.xml
POST /cms/parts.json

Creates a new CMS part. Requires CMS edit permission.

Parameters:

  • cms_part — part attributes:
Attribute Type Required Description
name string yes identifier (lowercase letters, digits, hyphens, underscores)
content string yes part body
page_id integer yes parent page ID
description string no human-readable label
filter_id string no markup filter: textile, markdown, html, none
status_id integer no 1 = active (default), 2 = locked
position integer no sort order within the page
is_cached boolean no enable part caching

Examples:

POST /cms/parts.xml

<?xml version="1.0"?>
<cms_part>
  <name>sidebar</name>
  <page_id>1</page_id>
  <description>Right sidebar</description>
  <content>h3. Related Links</content>
  <filter_id>textile</filter_id>
  <status_id>1</status_id>
</cms_part>
POST /cms/parts.json

{
  "cms_part": {
    "name": "sidebar",
    "page_id": 1,
    "description": "Right sidebar",
    "content": "h3. Related Links",
    "filter_id": "textile",
    "status_id": 1
  }
}

Response: HTTP 201 Created, with Location header pointing to the new part.

Updating a part

PUT /cms/parts/:id.xml
PUT /cms/parts/:id.json

Updates an existing CMS part. Accepts the same attributes as creating a part. Requires CMS edit permission.

Examples:

PUT /cms/parts/1.xml

<?xml version="1.0"?>
<cms_part>
  <content>h3. Updated Links</content>
  <description>Updated sidebar content</description>
</cms_part>
PUT /cms/parts/1.json

{
  "cms_part": {
    "content": "h3. Updated Links",
    "description": "Updated sidebar content" 
  }
}

Response: HTTP 200 OK (no body).

Deleting a part

DELETE /cms/parts/:id.xml
DELETE /cms/parts/:id.json

Deletes a CMS part. Requires admin privileges.

Examples:

DELETE /cms/parts/1.xml
DELETE /cms/parts/1.json

Response: HTTP 200 OK (no body).

Part name conventions

CMS parts follow naming conventions used in layout templates:

Name Typical use
content Main page body
header Page header block
footer Page footer block
sidebar Side panel

Any valid name works; these are not enforced by the plugin.

Authentication

All API endpoints require authentication. Supported methods:

  • key query parameter: ?key=YOUR_API_KEY
  • X-Redmine-API-Key HTTP header (preferred)
  • HTTP Basic auth with login/password

The public rendering endpoint GET /pages/:page_id/parts/:name does not require a key and respects page visibility rules.

curl examples

List parts for a page

curl -H "X-Redmine-API-Key: YOUR_API_KEY" \
  http://localhost:3000/cms/pages/home/parts.xml

Show part

curl -H "X-Redmine-API-Key: YOUR_API_KEY" \
  http://localhost:3000/cms/parts/1.json

Create part

curl -v -H "Content-Type: application/xml" \
  -H "X-Redmine-API-Key: YOUR_API_KEY" \
  -X POST \
  -d "<cms_part><name>footer</name><page_id>1</page_id><content>Footer text</content><filter_id>textile</filter_id><status_id>1</status_id></cms_part>" \
  http://localhost:3000/cms/parts.xml

Update part

curl -v -H "Content-Type: application/json" \
  -H "X-Redmine-API-Key: YOUR_API_KEY" \
  -X PUT http://localhost:3000/cms/parts/1.json \
  -d "{\"cms_part\": {\"content\": \"New footer text\"}}" 

Delete part

curl -v -H "X-Redmine-API-Key: YOUR_API_KEY" \
  -X DELETE http://localhost:3000/cms/parts/1.xml
Was this article helpful? Yes  No