Endpoints
The CMS API exposes five read-only GET endpoints. Every endpoint requires the X-App-Key header.
Not every call is metered
Endpoints marked Included in plan are normally served from the pre-computed cache and do not count against your plan's request meter. See Request Metering for the full rules.
Endpoint Summary
| # | Path | Purpose | Metered? |
|---|---|---|---|
| 1 | /_schemas |
List every published content type (catalog). | Included in plan |
| 2 | /_schemas/{contentType} |
Read a single content type's schema. | Included in plan |
| 3 | /{contentType} |
List entries with filter, sort, and pagination. | Partially — see Search Entries |
| 4 | /{contentType}/{uuid} |
Read a single entry by its UUID. | Included in plan |
| 5 | /{contentType}/search |
Full-text search over a content type. | Always counted |
URL ordering
The path segment search is reserved for the search endpoint. You cannot have an entry whose UUID is literally search.
1. List Content Types
Returns a catalog of every content type published for the tenant, along with its fields and which of them are filterable, sortable, and searchable.
GET /api/v1/_schemas
Headers
| Header | Value |
|---|---|
X-App-Key |
{YOUR_APP_KEY} |
Accept |
application/json |
Example Request
GET /api/v1/_schemas HTTP/1.1
Host: cms.appambit.com
X-App-Key: {YOUR_APP_KEY}
Example Response
{
"data": [
{
"slug": "blog_posts",
"name": "Blog Posts",
"description": "Marketing blog entries",
"icon": "heroicon-o-document-text",
"entry_count": 42,
"fields": ["title", "slug", "content", "category", "featured_image", "author_id"],
"filterable_fields": ["category", "status", "slug"],
"sortable_fields": ["title", "published_at"],
"searchable_fields": ["title", "content"]
},
{
"slug": "authors",
"name": "Authors",
"description": "Post authors",
"icon": "heroicon-o-user",
"entry_count": 5,
"fields": ["name", "email", "bio"],
"filterable_fields": [],
"sortable_fields": ["name"],
"searchable_fields": ["name", "bio"]
}
]
}
2. Get a Content Type Schema
Returns the full schema of a single content type, including a detailed breakdown of every field (type, label, required flag, searchable flag).
GET /api/v1/_schemas/{contentType}
URL Parameters
| Parameter | Type | Example | Description |
|---|---|---|---|
contentType |
string | blog_posts |
The slug of the content type to describe. |
Example Request
GET /api/v1/_schemas/blog_posts HTTP/1.1
Host: cms.appambit.com
X-App-Key: {YOUR_APP_KEY}
Example Response
{
"data": {
"slug": "blog_posts",
"name": "Blog Posts",
"description": "Marketing blog entries",
"icon": "heroicon-o-document-text",
"fields": [
{ "name": "title", "type": "text", "required": true, "label": "Title", "searchable": true },
{ "name": "content", "type": "rich_text", "required": true, "label": "Content", "searchable": true },
{ "name": "category", "type": "select", "required": false, "label": "Category", "searchable": false },
{ "name": "featured_image", "type": "media", "required": false, "label": "Featured Image", "searchable": false },
{ "name": "author_id", "type": "relation", "required": false, "label": "Author", "searchable": false }
],
"filterable_fields": ["category", "status", "slug"],
"sortable_fields": ["title", "published_at"],
"searchable_fields": ["title", "content"]
}
}
See Field Types for the full list of supported type values.
3. List Entries
Returns a paginated list of entries for a content type. Supports filtering, sorting, pagination, and sparse fieldsets — see Query Parameters for the details.
GET /api/v1/{contentType}
Metering rules for this endpoint
GET /{contentType}(no query, or onlypage/per_page) → Included in plan.GET /{contentType}?filter[{field}]={value}with a single equality on a filterable field → Included in plan.GET /{contentType}?sort=[-]{field}with a single sortable field → Included in plan.- Any operator filter (
gte,contains,in, …), a single equality filter combined with asort, any combination of two or more filters, or any filter on a field that is not marked filterable → counted against your plan.
URL Parameters
| Parameter | Type | Example | Description |
|---|---|---|---|
contentType |
string | blog_posts |
The slug of the content type to list. |
Query Parameters
See the full reference in Query Parameters. The most common ones:
| Parameter | Type | Description | Example |
|---|---|---|---|
filter[field] |
string | Equality filter (shorthand). | filter[category]=tech |
filter[field][op] |
string | Operator filter. | filter[views][gte]=100 |
sort |
string | Field name, prefix with - for descending. |
sort=-published_at |
page |
integer | 1-based page number. Defaults to 1. |
page=2 |
per_page |
integer | Items per page. Max 100. Defaults to 20. |
per_page=10 |
fields |
string | Comma-separated list of fields to return. | fields=title,slug,published_at |
Example Request
GET /api/v1/blog_posts?filter[category]=tech&sort=-published_at&per_page=10 HTTP/1.1
Host: cms.appambit.com
X-App-Key: {YOUR_APP_KEY}
Example Response
{
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "10 Laravel Tips",
"slug": "10-laravel-tips",
"category": "tech",
"featured_image": "b3c1f2.jpg",
"featured_image_url": "https://cms.appambit.com/{YOUR_APP_KEY}/cms/media/b3c1f2.jpg",
"author_id": "a11b22c3-d4e5-f6a7-b8c9-d0e1f2a3b4c5",
"published_at": "2025-01-20T15:30:00+00:00",
"created_at": "2025-01-19T10:00:00+00:00",
"updated_at": "2025-01-20T15:30:00+00:00"
}
],
"meta": {
"current_page": 1,
"per_page": 10,
"total": 8,
"last_page": 1
}
}
4. Get a Single Entry
Returns a single entry by its UUID. Direct UUID lookups are always served from cache.
GET /api/v1/{contentType}/{uuid}
URL Parameters
| Parameter | Type | Example | Description |
|---|---|---|---|
contentType |
string | blog_posts |
The slug of the content type. |
uuid |
string | 550e8400-e29b-41d4-a716-446655440000 |
The UUID of the entry. |
Query Parameters
| Parameter | Type | Description | Example |
|---|---|---|---|
populate |
string | Comma-separated list of relation fields to expand inline. See Relations. | populate=author_id |
Using populate is counted
The plain entry response is always served from cache (free). Adding ?populate=... forces a dynamic read because embedded related entries are not pre-computed, so the request will count against your plan.
Example Request
GET /api/v1/blog_posts/550e8400-e29b-41d4-a716-446655440000 HTTP/1.1
Host: cms.appambit.com
X-App-Key: {YOUR_APP_KEY}
Example Response
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "10 Laravel Tips",
"slug": "10-laravel-tips",
"content": "<p>…</p>",
"category": "tech",
"featured_image": "b3c1f2.jpg",
"featured_image_url": "https://cms.appambit.com/{YOUR_APP_KEY}/cms/media/b3c1f2.jpg",
"author_id": "a11b22c3-d4e5-f6a7-b8c9-d0e1f2a3b4c5",
"published_at": "2025-01-20T15:30:00+00:00",
"created_at": "2025-01-19T10:00:00+00:00",
"updated_at": "2025-01-20T15:30:00+00:00"
}
}
5. Search Entries
Full-text search across the fields of a content type that were marked searchable in the schema.
GET /api/v1/{contentType}/search
Search is always metered
Because every query string is unique, search results can't be pre-computed. Every search request counts against your plan's request meter. If you know the exact field and value, prefer filter instead.
URL Parameters
| Parameter | Type | Example | Description |
|---|---|---|---|
contentType |
string | blog_posts |
The slug of the content type to search. |
Query Parameters
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
q |
string | Yes | The search term. Must be between 2 and 200 characters. | q=laravel performance |
filter |
map | No | The same filter syntax as the list endpoint. Applied on top of the search ranking. | filter[status]=published |
sort |
string | No | Override the default relevance ordering. Follows the same rules as the list endpoint. | sort=-published_at |
page |
integer | No | 1-based page number. Defaults to 1. |
page=2 |
per_page |
integer | No | Items per page. Max 100. Defaults to 20. |
per_page=10 |
Search results are ordered by relevance by default: full-word matches outrank partial matches.
Example Request
GET /api/v1/blog_posts/search?q=laravel%20performance&per_page=20 HTTP/1.1
Host: cms.appambit.com
X-App-Key: {YOUR_APP_KEY}
Example Response
{
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "Optimizing Laravel Performance",
"slug": "optimizing-laravel-performance",
"category": "tech",
"published_at": "2025-01-20T15:30:00+00:00"
},
{
"id": "770f8400-e29b-41d4-a716-446655440111",
"title": "Database Performance in Laravel",
"slug": "database-performance-in-laravel",
"category": "tech",
"published_at": "2025-01-14T09:10:00+00:00"
}
],
"meta": {
"current_page": 1,
"per_page": 20,
"total": 7,
"last_page": 1,
"query": "laravel performance"
}
}
The meta.query field echoes back the search term you sent, which makes it easy to keep UI state in sync.
Search responses are not cached on the client
Search endpoints respond with Cache-Control: no-cache, no-store so that clients and intermediate caches always see fresh results.