Open-source headless CMS with self-hosted option, REST and GraphQL APIs, and customizable admin panel. Targets Strapi 5.
| Integration | Available | Notes |
|---|---|---|
| API | ✓ | REST (default), GraphQL (plugin) |
| MCP | - | No official MCP server |
| CLI | ✓ | strapi CLI for project setup, content types, plugins |
| SDK | ✓ | @strapi/sdk-js, @strapi/blocks-react-renderer |
- Type: API Token or Users & Permissions JWT
- Header:
Authorization: Bearer {api_token} - Tokens: Create in Settings → API Tokens (full access, read-only, or custom)
- JWT:
POST /api/auth/localwith identifier + password returns JWT
GET http://localhost:1337/api/articles?populate=*
Authorization: Bearer {api_token}GET http://localhost:1337/api/articles/{documentId}?populate=*
Authorization: Bearer {api_token}# Filter by field
GET http://localhost:1337/api/articles?filters[slug][$eq]=my-post
# Multiple filters
GET http://localhost:1337/api/articles?filters[category][name][$eq]=Marketing&filters[publishedAt][$notNull]=true
# Sort
GET http://localhost:1337/api/articles?sort=publishedAt:desc
# Pagination
GET http://localhost:1337/api/articles?pagination[page]=1&pagination[pageSize]=10POST http://localhost:1337/api/articles
Content-Type: application/json
Authorization: Bearer {api_token}
{
"data": {
"title": "New Article",
"slug": "new-article",
"body": "Article content here",
"category": "{category_documentId}"
}
}PUT http://localhost:1337/api/articles/{documentId}
Content-Type: application/json
Authorization: Bearer {api_token}
{
"data": {
"title": "Updated Title"
}
}DELETE http://localhost:1337/api/articles/{documentId}
Authorization: Bearer {api_token}# Strapi 5 uses status parameter (replaces v4 publicationState)
GET http://localhost:1337/api/articles?status=draft
Authorization: Bearer {api_token}Publishing and unpublishing are managed through the Strapi admin panel or Document Service API (server-side). The public REST API does not expose dedicated publish/unpublish endpoints.
# Populate all relations
GET http://localhost:1337/api/articles?populate=*
# Populate specific relations
GET http://localhost:1337/api/articles?populate[0]=author&populate[1]=category
# Deep populate
GET http://localhost:1337/api/articles?populate[author][populate]=avatar# Create new Strapi project
npx create-strapi@latest my-project
# Start development server
strapi develop
# Build admin panel
strapi build
# Generate content type
strapi generate content-type
# Generate controller
strapi generate controller
# Add GraphQL plugin
npm install @strapi/plugin-graphql- Content Type — Schema definition (collection type or single type)
- Document — Content item identified by
documentId(Strapi 5 pattern) - Component — Reusable field group (e.g., SEO fields, CTA block)
- Dynamic Zone — Flexible content area accepting multiple component types
- Media — Files managed through the Media Library
- Locale — i18n locale for content translation (plugin-based)
- Self-hosted CMS with full data ownership
- Budget-conscious projects (no per-seat pricing)
- Custom admin panel or plugin requirements
- Teams with DevOps capability
- Projects needing both REST and GraphQL access
- Self-hosted: No built-in rate limits (configure via middleware or reverse proxy)
- Strapi Cloud: Varies by plan
- Recommended: Add rate limiting middleware for production APIs
- content-strategy (CMS selection, content modeling)
- programmatic-seo (CMS as data source for generated pages)
- site-architecture (URL structure from CMS slugs)