Skip to main content

Documentation

Learn how to use the Headless platform

API Usage

3 min read

Access your content programmatically via REST or GraphQL APIs.

API Keys

Creating an API Key

  1. Go to Project Settings > API Keys
  2. Click Create API Key
  3. Enter a descriptive name
  4. Select permissions:
    • Read: Can fetch content (delivery)
    • Write: Can create/update content (management)
  5. 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

Text
https://your-domain.com/api/v1/{projectSlug}

Authentication

Include your API key in the request header:

Text
X-API-Key: your_api_key_here

Or use Bearer token:

Text
Authorization: Bearer your_api_key_here

List Entries

HTTP
GET /api/v1/{project}/{contentType}

Example:

Bash
curl -H "X-API-Key: your_key" \
  https://your-domain.com/api/v1/my-project/blogPost

Get Single Entry

HTTP
GET /api/v1/{project}/{contentType}/{id}

Query Parameters

ParameterDescriptionExample
limitResults per page (default 25)?limit=10
offsetSkip entries?offset=20
sortOrder results?sort=createdAt:desc
filterFilter by field?filter[status][$eq]=published
fieldsSelect fields?fields=title,slug
populateInclude 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):

HTTP
GET /api/v1/{project}/{contentType}?populate=author
GET /api/v1/{project}/{contentType}?populate=author,category,tags

Response without populate:

JSON
{
  "id": "entry-123",
  "attributes": {
    "title": "My Post"
  },
  "relationships": {
    "author": {
      "data": { "id": "author-456", "type": "author" }
    }
  }
}

Response with ?populate=author:

JSON
{
  "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:

HTTP
GET /api/v1/{project}/{contentType}?populate=*

Advanced Population Syntax

Select specific fields from populated relations:

HTTP
GET /api/v1/{project}/{contentType}?populate[author][fields]=name,email

Populate nested relations (e.g., author's company):

HTTP
GET /api/v1/{project}/{contentType}?populate[author][populate]=company

Combine field selection with nested population:

HTTP
GET /api/v1/{project}/{contentType}?populate[author][fields]=name&populate[author][populate]=company

Dot Notation for Nested Relations

You can also use dot notation for nested population:

HTTP
GET /api/v1/{project}/{contentType}?populate=author.company

This populates the author relation and its nested company relation.

Filter Operators

OperatorDescriptionExample
$eqEqualsfilter[status][$eq]=published
$neNot equalsfilter[status][$ne]=draft
$gtGreater thanfilter[price][$gt]=100
$gteGreater than or equalfilter[price][$gte]=100
$ltLess thanfilter[price][$lt]=50
$lteLess than or equalfilter[price][$lte]=50
$containsContains textfilter[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.

Add the semantic query parameter to search content by meaning:

HTTP
GET /api/v1/{project}/{contentType}?semantic=customer+onboarding

Parameters:

ParameterDescriptionDefault
semanticNatural language search query-
thresholdMinimum similarity score (0-1)0.7

Example:

Bash
# 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:

JSON
{
  "data": [
    {
      "id": "entry-123",
      "attributes": {
        "title": "Getting Users Started with Your Product"
      },
      "_similarity": 0.847
    }
  ]
}

Similar Content

Find entries similar to a given entry:

HTTP
GET /api/v1/{project}/{contentType}/{id}/similar

Parameters:

ParameterDescriptionDefault
limitMaximum results5
thresholdMinimum similarity score (0-1)0.7
sameContentTypeOnly find similar entries of same typefalse

Example:

Bash
# 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"

Search inside documents (PDFs, text files) by content:

HTTP
GET /api/v1/{project}/media?semantic=quarterly+revenue

Parameters:

ParameterDescriptionDefault
semanticNatural language search query-
thresholdMinimum similarity score (0-1)0.7
mimeTypeFilter by MIME type (e.g., application/pdf)-

Response includes matched text excerpts:

JSON
{
  "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

Text
https://your-domain.com/api/v1/{projectSlug}/graphql

Example Query

GraphQL
query {
  blogPosts(limit: 10, sort: "publishedAt:desc") {
    data {
      id
      title
      slug
      excerpt
      author {
        name
      }
    }
    meta {
      total
      hasNextPage
    }
  }
}

Filtering in GraphQL

GraphQL
query {
  blogPosts(filter: { status: { eq: "published" } }, limit: 5) {
    data {
      id
      title
    }
  }
}

Mutations (with Write permission)

GraphQL
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:

JSON
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Validation failed",
    "details": [
      {
        "field": "title",
        "message": "Title is required"
      }
    ]
  }
}

API Playground

Use the interactive API Playground to:

  1. Explore available endpoints
  2. Test requests with your API key
  3. View response schemas

Access via API Playground in the sidebar.