agentsclimarketplace

Api headless

Skill ColdBox/skills/contentbox-cfml/api-headless

Collection of skills for the ColdBox Platform and Claude Plugin

Install
npx -y skills add ColdBox/skills --skill api-headless

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Use this skill when implementing headless ContentBox APIs, including REST endpoint design, JWT authentication flows, content CRUD, custom API handlers, and integration patterns for decoupled frontends.

SKILL.md

9.4 KB, as published. Nobody here has run it

ContentBox API & Headless Development (CFML)

Build headless and REST API integrations with ContentBox CMS using CFML. ContentBox provides a full REST API (v1) for managing all content types, enabling headless CMS architectures.

API Architecture

The API module lives at modules/contentbox/modules/contentbox-api/ with a nested v1 module at modules/contentbox/modules/contentbox-api/modules/contentbox-api-v1/.

API v1 Handlers

HandlerResourceDescription
auth.cfcAuthenticationJWT token generation and validation
authors.cfcAuthorsAuthor CRUD operations
categories.cfcCategoriesCategory CRUD operations
comments.cfcCommentsComment management
contentStore.cfcContentStoreKey-value content blocks
contentTemplates.cfcTemplatesContent template management
entries.cfcEntriesBlog entry CRUD operations
menus.cfcMenusMenu management
pages.cfcPagesPage CRUD operations
relocations.cfcRelocationsURL redirect management
settings.cfcSettingsGlobal settings API
siteSettings.cfcSite SettingsSite-specific settings
sites.cfcSitesMulti-site management
versions.cfcVersionsContent versioning
echo.cfcHealth CheckAPI health check / echo

Base Handler Pattern

API handlers extend BaseHandler (which extends cborm.models.resources.BaseHandler):

<!--- handlers/api/v1/MyResource.cfc --->
<cfcomponent extends="contentbox.modules.contentbox-api.modules.contentbox-api-v1.handlers.baseHandler" singleton>

	<!--- Inject the virtual entity service --->
	<cfproperty name="ormService" inject="MyEntityService@contentbox">

	<!--- Entity name (singular) --->
	<cfset variables.entity = "MyEntity">

	<!--- Default sort order --->
	<cfset variables.sortOrder = "createdDate DESC">

	<!--- Use native getOrFail() or getByIdOrSlugOrFail() --->
	<cfset variables.useGetOrFail = true>

</cfcomponent>

This automatically provides: index, create, show, update, delete methods.

Authentication

JWT Authentication

The API uses JWT tokens for authentication:

// POST /api/v1/auth
// Body: { "username": "admin", "password": "secret" }

// Response: { "token": "eyJhbGciOiJIUzI1NiIs...", "expires": 3600 }

Using Tokens

Include the token in the Authorization header:

Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

API Endpoints

Entries

GET    /api/v1/entries              → List entries (paginated)
GET    /api/v1/entries/:id          → Get single entry
POST   /api/v1/entries              → Create entry
PUT    /api/v1/entries/:id          → Update entry
DELETE /api/v1/entries/:id          → Delete entry

Query Parameters

ParameterDescription
pagePage number (default: 1)
maxRowsResults per page
sortOrderSort field and direction
isDeletedInclude soft-deleted entries
includesRelated entities to include
excludesFields to exclude from response

Pages

GET    /api/v1/pages                → List pages
GET    /api/v1/pages/:id            → Get single page (by ID or slug)
POST   /api/v1/pages                → Create page
PUT    /api/v1/pages/:id            → Update page
DELETE /api/v1/pages/:id            → Delete page

Categories

GET    /api/v1/categories           → List categories
GET    /api/v1/categories/:id       → Get single category
POST   /api/v1/categories           → Create category
PUT    /api/v1/categories/:id       → Update category
DELETE /api/v1/categories/:id       → Delete category

Authors

GET    /api/v1/authors              → List authors
GET    /api/v1/authors/:id          → Get single author
POST   /api/v1/authors              → Create author
PUT    /api/v1/authors/:id          → Update author
DELETE /api/v1/authors/:id          → Delete author

ContentStore

GET    /api/v1/contentstore         → List all content store items
GET    /api/v1/contentstore/:key    → Get item by key
POST   /api/v1/contentstore         → Create item
PUT    /api/v1/contentstore/:key    → Update item
DELETE /api/v1/contentstore/:key    → Delete item

Menus

GET    /api/v1/menus                → List menus
GET    /api/v1/menus/:slug          → Get menu by slug
POST   /api/v1/menus                → Create menu
PUT    /api/v1/menus/:slug          → Update menu
DELETE /api/v1/menus/:slug          → Delete menu

Sites

GET    /api/v1/sites                → List sites
GET    /api/v1/sites/:id            → Get single site
POST   /api/v1/sites                → Create site
PUT    /api/v1/sites/:id            → Update site
DELETE /api/v1/sites/:id            → Delete site

Response Format

List Response

{
	"data": [
		{ "id": "...", "title": "...", "slug": "...", ... }
	],
	"total": 100,
	"page": 1,
	"maxRows": 25
}

Single Resource Response

{
	"data": {
		"id": "...",
		"title": "...",
		"slug": "...",
		"content": "...",
		"author": { ... },
		"categories": [ ... ],
		...
	}
}

Error Response

{
	"error": true,
	"message": "Resource not found",
	"details": "..."
}

Creating Custom API Endpoints

Custom API Handler

<!--- handlers/api/v1/CustomResource.cfc --->
<cfcomponent extends="contentbox.modules.contentbox-api.modules.contentbox-api-v1.handlers.baseHandler" singleton>

	<cfproperty name="ormService" inject="CustomEntityService@contentbox">
	<cfset variables.entity = "CustomEntity">
	<cfset variables.sortOrder = "createdDate DESC">

	<!--- Override index for custom filtering --->
	<cffunction name="index" access="public" returntype="void">
		<cfargument name="event" type="any">
		<cfargument name="rc" type="struct">
		<cfargument name="prc" type="struct">

		<!--- Custom filtering logic --->
		<cfset prc.criteria = ormService.newCriteria()>
		<cfif structKeyExists( rc, "status" )>
			<cfset prc.criteria.isEq( "status", rc.status )>
		</cfif>

		<!--- Delegate to parent --->
		<cfset super.index( event, rc, prc, prc.criteria )>
	</cffunction>

	<!--- Add custom action --->
	<cffunction name="publish" access="public" returntype="void">
		<cfargument name="event" type="any">
		<cfargument name="rc" type="struct">
		<cfargument name="prc" type="struct">

		<cfset var entity = ormService.get( rc.id )>
		<cfset entity.setStatus( "published" )>
		<cfset ormService.save( entity )>

		<cfset renderData(
			type    = "json",
			data    = { success : true, entity : entity.getMemento() },
			statusCode = 200
		)>
	</cffunction>

</cfcomponent>

Custom API Routes

Register routes in your module's ModuleConfig.cfc:

<cfset routes = [
	// RESTful resources
	{ pattern = "/api/v1/custom", handler = "api/v1/customResource" },
	{ pattern = "/api/v1/custom/:id", handler = "api/v1/customResource" },
	// Custom actions
	{ pattern = "/api/v1/custom/:id/publish", handler = "api/v1/customResource", action = "publish" }
]>

Headless CMS Usage

Frontend Integration

Use the API to build headless frontends:

// Fetch entries
const response = await fetch('/api/v1/entries?page=1&maxRows=10', {
  headers: { 'Authorization': `Bearer ${token}` }
});
const { data, total, page } = await response.json();

// Fetch single page by slug
const pageResponse = await fetch('/api/v1/pages/my-page-slug', {
  headers: { 'Authorization': `Bearer ${token}` }
});
const { data: page } = await pageResponse.json();

Content Rendering

The API returns content with all fields, including:

  • title, slug, content (HTML)
  • publishedDate, createdDate, modifiedDate
  • author (nested object)
  • categories (array)
  • customFields (if configured)
  • featuredImage (media reference)

API Security

Firewall Rules

API routes are protected by cbSecurity rules. Configure in settings:

settings.cbsecurity = {
	firewall : {
		invalidAuthenticationEvent : "cbapi/auth/unauthorized",
		defaultAuthenticationAction : "redirect",
		invalidAuthorizationEvent : "cbapi/auth/forbidden",
		defaultAuthorizationAction : "redirect"
	}
};

Rate Limiting

The core RateLimiter@contentbox interceptor protects against brute-force attacks.

Best Practices

  1. Extend baseHandler — get CRUD operations for free
  2. Inject ormService — use the correct virtual entity service
  3. Use variables.entity — set the singular entity name
  4. Set variables.sortOrder — define default sorting
  5. Use param for defaults — set safe defaults for query parameters
  6. Override methods as needed — customize index, show, etc.
  7. Use renderData() — for consistent JSON responses
  8. Announce interception points — for extensibility
  9. Include related entities — use includes parameter for nested data
  10. Handle errors gracefully — return proper error responses

Engine Compatibility

This skill targets CFML engines (Lucee 5+, Adobe ColdFusion 2018+). For BoxLang-specific syntax and features, see the BoxLang variant of this skill.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.