Skip to main content

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:

CodeDescription
NOT_FOUNDResource doesn't exist
UNAUTHORIZEDNot authenticated
FORBIDDENNo permission
VALIDATION_ERRORInvalid input
INSUFFICIENT_CREDITSNot 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:

TierRequests/minute
Free60
Pro300
Business1000
EnterpriseUnlimited

🔍 Explore the API

Use GraphiQL at /graphql to explore the full schema with autocomplete and documentation.