GraphQL API
LusterCMS exposes a comprehensive GraphQL API for all operations.
Endpoint
POST /graphql
The same endpoint serves the GraphiQL UI for exploration.
Authentication
Include JWT token in the Authorization header:
Authorization: Bearer <access_token>
Obtain tokens via the login mutation or REST endpoint.
Common Queries
Content Entries
# List entries
query GetEntries {
entries(
contentType: "page"
status: PUBLISHED
limit: 10
offset: 0
) {
id
title
slug
status
createdAt
updatedAt
}
}
# Get single entry
query GetEntry {
entry(id: "uuid-here") {
id
title
slug
content
blocks
seo {
title
description
}
}
}
# Get entry by slug
query GetEntryBySlug {
entryBySlug(slug: "about-us", contentType: "page") {
id
title
content
}
}
Media
# List media
query GetMedia {
media(
limit: 20
filter: { type: IMAGE }
) {
id
filename
url
mimeType
size
aiAltText
sizes {
label
url
width
height
}
}
}
# Get single media
query GetMediaItem {
mediaItem(id: "uuid-here") {
id
filename
url
metadata
}
}
Users
# Current user
query Me {
me {
id
email
name
role
permissions
}
}
# List users (admin)
query GetUsers {
users {
id
email
name
role
createdAt
}
}
Common Mutations
Content
# Create/Update entry
mutation UpsertEntry {
upsertEntry(input: {
id: null # null for create, ID for update
contentType: "page"
title: "New Page"
slug: "new-page"
content: "Page content here..."
status: DRAFT
blocks: []
}) {
id
title
status
}
}
# Publish entry
mutation PublishEntry {
publishEntry(id: "uuid-here") {
id
status
publishedAt
}
}
# Delete entry
mutation DeleteEntry {
deleteEntry(id: "uuid-here") {
success
}
}
Media
# Update media metadata
mutation UpdateMedia {
updateMedia(id: "uuid-here", input: {
altText: "Description of image"
tags: ["hero", "banner"]
}) {
id
altText
tags
}
}
# Delete media
mutation DeleteMedia {
deleteMedia(id: "uuid-here") {
success
}
}
AI Features
# Improve text
mutation ImproveText {
improveText(
text: "Make this text better"
style: PROFESSIONAL
) {
text
creditsUsed
}
}
# Generate SEO meta
mutation GenerateSeoMeta {
generateSeoMeta(entryId: "uuid-here") {
title
description
keywords
creditsUsed
}
}
# Generate alt text for image
mutation GenerateAltText {
generateAltText(mediaId: "uuid-here") {
altText
creditsUsed
}
}
Authentication
# Login
mutation Login {
login(email: "user@example.com", password: "secret") {
accessToken
refreshToken
user {
id
email
}
}
}
# Refresh token
mutation RefreshToken {
refreshToken(token: "refresh-token-here") {
accessToken
refreshToken
}
}
Subscriptions
Real-time updates via WebSocket:
# Content updates
subscription OnContentUpdate {
contentUpdated(contentType: "page") {
id
title
updatedAt
}
}
# Collaboration presence
subscription OnPresenceUpdate {
presenceUpdated(entryId: "uuid-here") {
userId
userName
cursor
status
}
}
Error Handling
Errors follow GraphQL conventions:
{
"data": null,
"errors": [
{
"message": "Entry not found",
"locations": [{"line": 2, "column": 3}],
"path": ["entry"],
"extensions": {
"code": "NOT_FOUND"
}
}
]
}
Common error codes:
| Code | Description |
|---|---|
NOT_FOUND | Resource doesn't exist |
UNAUTHORIZED | Not authenticated |
FORBIDDEN | No permission |
VALIDATION_ERROR | Invalid input |
INSUFFICIENT_CREDITS | Not enough AI credits |
Pagination
Use limit and offset for pagination:
query GetEntries {
entries(limit: 10, offset: 20) {
id
title
}
entriesCount(contentType: "page")
}
Filtering
Many queries support filters:
query FilteredEntries {
entries(
contentType: "post"
filter: {
status: PUBLISHED
author: "user-id"
createdAfter: "2025-01-01"
tags: ["featured"]
}
) {
id
title
}
}
Rate Limiting
API requests are rate-limited:
| Tier | Requests/minute |
|---|---|
| Free | 60 |
| Pro | 300 |
| Business | 1000 |
| Enterprise | Unlimited |
🔍 Explore the API
Use GraphiQL at /graphql to explore the full schema with autocomplete and documentation.