Search API
Full-text search across published posts, pages, and categories. Powered by spatie/laravel-searchable — the same engine that powers the public web search page.
GET /api/v1/search
Query parameters:
| Param | Default | Description |
|---|---|---|
q |
(required) | Search query, minimum 2 characters |
per_page |
20 |
Max items in posts array (max 50) |
Example:
curl "https://your-site.com/api/v1/search?q=headless+cms"
Response:
{
"success": true,
"message": "Search results retrieved successfully",
"data": {
"query": "headless cms",
"total": 14,
"posts": [
{
"id": 267,
"title": "UnfoldCMS Now Has a Real REST API",
"slug": "unfoldcms-public-api-v1-launch",
"excerpt": "...",
"categories": [...],
"posted_at": "2026-05-26T15:00:00+00:00"
}
],
"categories": [
{
"id": 5,
"name": "Headless CMS",
"slug": "headless-cms"
}
]
}
}
The response groups results by type. posts contains both blog posts and pages (anything with content_type in [post, page]). categories contains category records matching the query.
Validation
If q is missing or shorter than 2 characters, the API returns 422:
{
"success": false,
"message": "Search query must be at least 2 characters",
"errors": {
"code": "VALIDATION_ERROR"
}
}
What's Searched
For posts and pages: title, short_description, and body (HTML stripped). For categories: name and description.
Search is case-insensitive and uses simple LIKE matching — not full-text indexes (yet). This is fine for sites with up to ~10,000 posts. For larger sites, consider Algolia or Meilisearch as a v2 candidate.
What's NOT Searched
- Unpublished posts and future-scheduled posts (filtered out automatically)
- Draft pages
- Comments (intentionally, to prevent spam-driven pollution of search)
- Settings or admin content