API Keys
Creating an API Key
- Go to Project Settings > API Keys
- Click Create API Key
- Enter a descriptive name
- Select permissions:
- Read: Can fetch content (delivery)
- Write: Can create/update content (management)
- Copy and securely store the key
API Key Security
- Store API keys in environment variables
- Never expose keys in client-side code
- Rotate keys periodically
- Revoke unused keys
REST API
Base URL
https://your-domain.com/api/v1/{projectSlug}Authentication
Include your API key in the request header:
X-API-Key: your_api_key_hereOr use Bearer token:
Authorization: Bearer your_api_key_hereList Entries
GET /api/v1/{project}/{contentType}Example:
curl -H "X-API-Key: your_key" \
https://your-domain.com/api/v1/my-project/blogPostGet Single Entry
GET /api/v1/{project}/{contentType}/{id}Query Parameters
| Parameter | Description | Example |
|---|---|---|
limit | Results per page (default 25) | ?limit=10 |
offset | Skip entries | ?offset=20 |
sort | Order results | ?sort=createdAt:desc |
filter | Filter by field | ?filter[status][$eq]=published |
fields | Select fields | ?fields=title,slug |
populate | Include relations | ?populate=author |
Populating Relations
Use the populate parameter to expand relationship fields with full entry data instead of just IDs.
Simple Population
Include one or more relations (comma-separated):
GET /api/v1/{project}/{contentType}?populate=author
GET /api/v1/{project}/{contentType}?populate=author,category,tagsResponse without populate:
{
"id": "entry-123",
"attributes": {
"title": "My Post"
},
"relationships": {
"author": {
"data": { "id": "author-456", "type": "author" }
}
}
}Response with ?populate=author:
{
"id": "entry-123",
"attributes": {
"title": "My Post"
},
"relationships": {
"author": {
"data": {
"id": "author-456",
"type": "author",
"attributes": {
"name": "Jane Doe",
"email": "jane@example.com",
"bio": "Writer and developer"
}
}
}
}
}Populate All Relations
Use * to populate all relationship fields:
GET /api/v1/{project}/{contentType}?populate=*Advanced Population Syntax
Select specific fields from populated relations:
GET /api/v1/{project}/{contentType}?populate[author][fields]=name,emailPopulate nested relations (e.g., author's company):
GET /api/v1/{project}/{contentType}?populate[author][populate]=companyCombine field selection with nested population:
GET /api/v1/{project}/{contentType}?populate[author][fields]=name&populate[author][populate]=companyDot Notation for Nested Relations
You can also use dot notation for nested population:
GET /api/v1/{project}/{contentType}?populate=author.companyThis populates the author relation and its nested company relation.
Filter Operators
| Operator | Description | Example |
|---|---|---|
$eq | Equals | filter[status][$eq]=published |
$ne | Not equals | filter[status][$ne]=draft |
$gt | Greater than | filter[price][$gt]=100 |
$gte | Greater than or equal | filter[price][$gte]=100 |
$lt | Less than | filter[price][$lt]=50 |
$lte | Less than or equal | filter[price][$lte]=50 |
$contains | Contains text | filter[title][$contains]=hello |
Semantic Search (AI-Powered)
Search your content by meaning using AI embeddings. Unlike keyword search, semantic search understands concepts and finds related content even when exact terms don't match.
Content Semantic Search
Add the semantic query parameter to search content by meaning:
GET /api/v1/{project}/{contentType}?semantic=customer+onboardingParameters:
| Parameter | Description | Default |
|---|---|---|
semantic | Natural language search query | - |
threshold | Minimum similarity score (0-1) | 0.7 |
Example:
# Find blog posts about customer onboarding (even if they don't use those exact words)
curl -H "X-API-Key: your_key" \
"https://your-domain.com/api/v1/my-project/blogPost?semantic=customer+onboarding&threshold=0.6"Response includes similarity scores:
{
"data": [
{
"id": "entry-123",
"attributes": {
"title": "Getting Users Started with Your Product"
},
"_similarity": 0.847
}
]
}Similar Content
Find entries similar to a given entry:
GET /api/v1/{project}/{contentType}/{id}/similarParameters:
| Parameter | Description | Default |
|---|---|---|
limit | Maximum results | 5 |
threshold | Minimum similarity score (0-1) | 0.7 |
sameContentType | Only find similar entries of same type | false |
Example:
# Find blog posts similar to a specific post
curl -H "X-API-Key: your_key" \
"https://your-domain.com/api/v1/my-project/blogPost/entry-123/similar?limit=5"Media Document Search
Search inside documents (PDFs, text files) by content:
GET /api/v1/{project}/media?semantic=quarterly+revenueParameters:
| Parameter | Description | Default |
|---|---|---|
semantic | Natural language search query | - |
threshold | Minimum similarity score (0-1) | 0.7 |
mimeType | Filter by MIME type (e.g., application/pdf) | - |
Response includes matched text excerpts:
{
"data": [
{
"id": "media-456",
"filename": "Q3-Report.pdf",
"mimeType": "application/pdf",
"_similarity": 0.823,
"_matchedChunk": {
"index": 3,
"text": "Quarterly revenue increased by 15%..."
}
}
]
}GraphQL API
Endpoint
https://your-domain.com/api/v1/{projectSlug}/graphqlExample Query
query {
blogPosts(limit: 10, sort: "publishedAt:desc") {
data {
id
title
slug
excerpt
author {
name
}
}
meta {
total
hasNextPage
}
}
}Filtering in GraphQL
query {
blogPosts(filter: { status: { eq: "published" } }, limit: 5) {
data {
id
title
}
}
}Mutations (with Write permission)
mutation {
createBlogPost(
data: {
title: "My New Post"
slug: "my-new-post"
content: "Post content here..."
}
) {
id
title
}
}Rate Limits
- Default: 1000 requests per minute
- Rate limit headers included in responses
- Contact support for higher limits
Error Responses
Errors follow a consistent format:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"details": [
{
"field": "title",
"message": "Title is required"
}
]
}
}API Playground
Use the interactive API Playground to:
- Explore available endpoints
- Test requests with your API key
- View response schemas
Access via API Playground in the sidebar.