Content Module

June 17, 2026 · 5 min read

The Content Module is a CMS-like module for MedusaJS that allows creating and managing content pages like blog articles, landing pages, product descriptions and anything else that you might want to manage as content.

Admin Dashboard Usage

After installing the plugin, the "Content" section will become available in the admin sidebar.

Rich Text Editor

Content editing is done through a rich text editor via the lexical editor library. The editor supports all Markdown features.

Admin API

Query Content Posts

GET /admin/blog/posts - Query content posts with optional filters, sorting, and pagination.

Query parameters:

  • offset - Number of posts to skip (default: 0)
  • limit - Maximum number of posts to return (default: 20)
  • order - Sort order of the posts (default: "created_at DESC")
  • published - Filter by published status (true/false)
  • q - Search query for post title or content
  • post_type_id - Filter by post type ID

Get Single Post

GET /admin/blog/posts/:id - Retrieve a single content post by its ID.

Create Post

POST /admin/blog/posts - Create a new content post.

Request body:

  • title (string, required) - Title of the post.
  • slug (string, required) - URL-friendly slug for the post.
  • content (string, required) - The post content (supports Markdown).
  • featured_image (string, optional, nullable) - URL of the featured image.
  • published (boolean, required) - Whether the post is published.
  • post_type_id (string, optional, nullable) - ID of the post type.
  • tags (array of strings, required) - List of tag IDs to associate.
  • categories (array of strings, required) - List of category IDs to associate.
  • metadata (record, optional, nullable) - Custom key-value metadata.

Update Post

PUT /admin/blog/posts/:id - Update an existing content post.

Request body (all fields optional):

  • title (string) - Title of the post.
  • slug (string) - URL-friendly slug for the post.
  • excerpt (string, optional, nullable) - Short excerpt/summary of the post.
  • content (string) - The post content (supports Markdown).
  • featured_image (string, optional, nullable) - URL of the featured image (must be a valid URL).
  • published (boolean) - Whether the post is published.
  • published_at (string, optional, nullable) - ISO 8601 datetime of publication.
  • metadata (record, optional, nullable) - Custom key-value metadata.
  • post_type_id (string, optional, nullable) - ID of the post type.
  • categories (array of strings) - List of category IDs to associate.
  • tags (array of strings) - List of tag IDs to associate.

Delete Post

DELETE /admin/blog/posts/:id - Delete a content post.


List Categories

GET /admin/blog/categories - Query categories with optional pagination.

Query parameters:

  • offset - Number of categories to skip (default: 0)
  • limit - Maximum number of categories to return (default: 20)
  • q - Search query for category name
  • order - Sort order (default: "created_at DESC")

Get Single Category

GET /admin/blog/categories/:id - Retrieve a single category by its ID.

Create Category

POST /admin/blog/categories - Create a new category.

Request body:

  • name (string, required) - Name of the category.
  • slug (string, required) - URL-friendly slug for the category.
  • description (string, optional, nullable) - Description of the category.

Update Category

PUT /admin/blog/categories/:id - Update an existing category.

Request body (all fields optional):

  • name (string) - Name of the category.
  • slug (string) - URL-friendly slug for the category.
  • description (string, optional, nullable) - Description of the category.

Delete Category

DELETE /admin/blog/categories/:id - Delete a category.


List Tags

GET /admin/blog/tags - Query tags with optional pagination.

Query parameters:

  • offset - Number of tags to skip (default: 0)
  • limit - Maximum number of tags to return (default: 20)
  • q - Search query for tag name
  • order - Sort order (default: "created_at DESC")

Get Single Tag

GET /admin/blog/tags/:id - Retrieve a single tag by its ID.

Create Tag

POST /admin/blog/tags - Create a new tag.

Request body:

  • name (string, required) - Name of the tag.
  • slug (string, required) - URL-friendly slug for the tag.

Update Tag

PUT /admin/blog/tags/:id - Update an existing tag.

Request body (all fields optional):

  • name (string) - Name of the tag.
  • slug (string) - URL-friendly slug for the tag.

Delete Tag

DELETE /admin/blog/tags/:id - Delete a tag.


List Post Types

GET /admin/blog/post-types - Query post types with optional pagination.

Query parameters:

  • offset - Number of post types to skip (default: 0)
  • limit - Maximum number of post types to return (default: 20)
  • q - Search query for post type name
  • order - Sort order (default: "created_at DESC")

Get Single Post Type

GET /admin/blog/post-types/:id - Retrieve a single post type by its ID.

Create Post Type

POST /admin/blog/post-types - Create a new post type.

Request body:

  • name (string, required) - Name of the post type.
  • slug (string, required) - URL-friendly slug for the post type.
  • description (string, optional, nullable) - Description of the post type.

Update Post Type

PUT /admin/blog/post-types/:id - Update an existing post type.

Request body (all fields optional):

  • name (string) - Name of the post type.
  • slug (string) - URL-friendly slug for the post type.
  • description (string, optional, nullable) - Description of the post type.

Delete Post Type

DELETE /admin/blog/post-types/:id - Delete a post type.

Store API

Store API routes are public-facing and read-only. They return only published content.

Posts

List Posts

GET /store/blog/posts - Query published content posts with optional filters, sorting, and pagination.

Query parameters:

  • offset - Number of posts to skip (default: 0)
  • limit - Maximum number of posts to return (default: 20)
  • order - Sort order (default: "created_at DESC")
  • q - Search query for post title or content
  • post_type_id - Filter by post type ID

Get Single Post

GET /store/blog/posts/:id - Retrieve a single published content post by its ID.


Categories

List Categories

GET /store/blog/categories - Query categories with optional pagination.

Query parameters:

  • offset - Number of categories to skip (default: 0)
  • limit - Maximum number of categories to return (default: 20)
  • q - Search query for category name
  • order - Sort order (default: "created_at DESC")

Get Single Category

GET /store/blog/categories/:id - Retrieve a single category by its ID.


Tags

List Tags

GET /store/blog/tags - Query tags with optional pagination.

Query parameters:

  • offset - Number of tags to skip (default: 0)
  • limit - Maximum number of tags to return (default: 20)
  • q - Search query for tag name
  • order - Sort order (default: "created_at DESC")

Get Single Tag

GET /store/blog/tags/:id - Retrieve a single tag by its ID.


Post Types

List Post Types

GET /store/blog/post-types - Query post types with optional pagination.

Query parameters:

  • offset - Number of post types to skip (default: 0)
  • limit - Maximum number of post types to return (default: 20)
  • q - Search query for post type name
  • order - Sort order (default: "created_at DESC")

Get Single Post Type

GET /store/blog/post-types/:id - Retrieve a single post type by its ID.