Overview #
The FlowCMS GraphQL API provides a unified interface to query, create, update, and delete content across your organization. With support for real-time subscriptions, filtering, pagination, and sorting, you can build powerful content-driven applications.
# Your first FlowCMS GraphQL query
{
contents(first: 5, filter: { status: PUBLISHED }) {
edges {
node {
id
title
slug
status
author {
name
avatar
}
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
Authentication #
All GraphQL requests require authentication via Bearer token. Include your API token in the Authorization header of every request.
🔐 Authentication Header
Include the following header in all GraphQL requests:
curl https://api.flowcms.io/graphql \
-X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer fc_live_abc123..." \
-d '{"query": "{ contents(first: 5) { edges { node { title } } } }"}'
Rate Limiting #
GraphQL requests are rate-limited based on your plan tier. Rate limit information is returned in response headers.
Starter
Professional
Enterprise
X-RateLimit-Limit: 50000
X-RateLimit-Remaining: 49987
X-RateLimit-Reset: 1704067200
X-Request-ID: req_abc123def456
Error Handling #
FlowCMS returns standardized GraphQL errors. Each error includes a code, message, and optional path to the problematic field.
{
"data": null,
"errors": [
{
"message": "Content with slug 'old-post' not found",
"extensions": {
"code": "NOT_FOUND",
"statusCode": 404,
"path": ["contentBySlug"]
}
}
]
}
| Error Code | HTTP Status | Description |
|---|---|---|
| UNAUTHENTICATED | 401 | Missing or invalid API token |
| FORBIDDEN | 403 | Insufficient permissions |
| NOT_FOUND | 404 | Requested resource not found |
| VALIDATION_ERROR | 422 | Input validation failed |
| RATE_LIMITED | 429 | Rate limit exceeded |
| INTERNAL_ERROR | 500 | Server error |
Queries #
Queries let you read and retrieve content from FlowCMS. Use pagination, filtering, and sorting to get exactly the data you need.
Fetch a single content item by its unique ID.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | ID! | Required | The unique content item ID |
{
content(id: "cnt_abc123") {
id
title
slug
body
status
publishedAt
updatedAt
author {
id
name
email
}
media {
url
alt
}
}
}
Fetch a single content item by its unique slug. Ideal for URL-based routing.
| Parameter | Type | Required | Description |
|---|---|---|---|
| slug | String! | Required | The content slug (e.g., "my-blog-post") |
{
contentBySlug(slug: "getting-started-with-flowcms") {
id
title
slug
body
excerpt
featuredImage {
url
width
height
}
}
}
Fetch a paginated list of content items with filtering and sorting support.
| Parameter | Type | Required | Description |
|---|---|---|---|
| first | Int | Optional | Number of items (default: 10, max: 100) |
| after | String | Optional | Cursor for pagination |
| filter | ContentFilterInput | Optional | Filter criteria object |
| sort | String | Optional | Sort field (e.g., "-createdAt") |
{
contents(
first: 10
filter: {
status: PUBLISHED
contentType: "blog"
search: "graphql"
}
sort: "-publishedAt"
) {
edges {
cursor
node {
id
title
slug
excerpt
status
publishedAt
tags
}
}
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
}
}
Fetch media item metadata by its ID.
{
media(id: "med_xyz789") {
id
filename
url
mimeType
size
width
height
alt
uploadedAt
}
}
Fetch the currently authenticated user's profile.
{
currentUser {
id
name
email
role
avatar
organization {
name
slug
}
}
}
Mutations #
Mutations allow you to create, update, delete, and publish content. All mutations return the affected resource.
Create a new content item. The item is created in DRAFT status by default.
| Parameter | Type | Required | Description |
|---|---|---|---|
| title | String! | Required | Content title |
| slug | String | Optional | URL slug (auto-generated from title if omitted) |
| body | String! | Required | Content body (supports Markdown & HTML) |
| contentType | String | Optional | Content type key (default: "page") |
| tags | [String] | Optional | Array of tags |
| mediaIds | [ID] | Optional | Associated media items |
mutation CreatePost ($input: CreateContentInput!) {
createContent(input: $input) {
id
title
slug
status
createdAt
}
}
# Variables
{
"input": {
"title": "Getting Started with GraphQL",
"body": "## Introduction...",
"contentType": "blog",
"tags": ["graphql", "tutorial"]
}
}
Update an existing content item. Only provide the fields you want to change.
mutation UpdatePost (
$id: ID!
$input: UpdateContentInput!
) {
updateContent(id: $id, input: $input) {
id
title
body
updatedAt
}
}
Permanently delete a content item. This action cannot be undone.
mutation DeletePost ($id: ID!) {
deleteContent(id: $id)
}
# Response
{
"data": {
"deleteContent": true
}
}
Publish a draft content item, making it publicly accessible.
mutation PublishPost ($id: ID!) {
publishContent(id: $id) {
id
status
publishedAt
}
}
Upload a media file to FlowCMS. Returns the media item with CDN URL.
@upload directive. Requires a GraphQL client that supports multipart requests (e.g., Apollo Client, GraphiQL).
mutation UploadImage (
$file: Upload!
$alt: String
) {
uploadMedia(file: $file, alt: $alt) {
id
url
filename
mimeType
size
}
}
Subscriptions #
Subscriptions provide real-time updates via WebSocket. Connect to stay informed about content changes as they happen.
wss://api.flowcms.io/graphql — Subscriptions automatically fall back to SSE if WebSocket is unavailable.
Triggered when a new content item is created.
subscription OnContentCreated {
contentCreated {
id
title
slug
status
author {
name
}
}
}
Triggered when a content item is updated.
subscription OnContentUpdated {
contentUpdated {
id
title
updatedAt
}
}
Triggered when a content item is published. Useful for triggering build pipelines or cache invalidation.
subscription OnContentPublished {
contentPublished {
id
slug
status
publishedAt
}
}
Schema Types #
Explore the GraphQL types that make up the FlowCMS API schema.
| Field | Type | Description |
|---|---|---|
| id | ID! | Unique identifier |
| title | String! | Content title |
| slug | String! | URL-friendly slug |
| body | String! | Content body (Markdown/HTML) |
| excerpt | String | Short summary |
| status | ContentStatus! | Current status (DRAFT, PUBLISHED, ARCHIVED) |
| tags | [String] | Content tags |
| author | User | Content author |
| media | [MediaItem] | Associated media |
| createdAt | DateTime! | Creation timestamp |
| updatedAt | DateTime! | Last update timestamp |
| publishedAt | DateTime | Publication timestamp |
| Field | Type | Description |
|---|---|---|
| edges | [ContentEdge!]! | Array of edges |
| pageInfo | PageInfo! | Pagination metadata |
| Field | Type | Description |
|---|---|---|
| id | ID! | Unique identifier |
| filename | String! | Original filename |
| url | String! | CDN URL |
| mimeType | String! | MIME type (e.g., "image/jpeg") |
| size | Int! | File size in bytes |
| width | Int | Image width (if applicable) |
| height | Int | Image height (if applicable) |
| alt | String | Alt text for accessibility |
| uploadedAt | DateTime! | Upload timestamp |
| Field | Type | Description |
|---|---|---|
| id | ID! | Unique identifier |
| name | String! | Display name |
| String! | Email address | |
| role | String! | User role (admin, editor, viewer) |
| avatar | String | Avatar URL |
| Value | Description |
|---|---|
| DRAFT | Unpublished draft |
| PUBLISHED | Live and publicly accessible |
| ARCHIVED | Archived and hidden |
| Value | Description |
|---|---|
| ASC | Ascending order |
| DESC | Descending order |
| Field | Type | Description |
|---|---|---|
| title | String! | Content title |
| slug | String | URL slug |
| body | String! | Content body |
| excerpt | String | Short summary |
| contentType | String | Content type key |
| tags | [String] | Tags array |
| mediaIds | [ID] | Associated media IDs |
| Field | Type | Description |
|---|---|---|
| status | ContentStatus | Filter by status |
| contentType | String | Filter by content type |
| search | String | Full-text search |
| tag | String | Filter by tag |
| authorId | ID | Filter by author |
| dateFrom | DateTime | Published after |
| dateTo | DateTime | Published before |
Interactive Playground #
Test GraphQL queries directly in your browser. Write queries on the left and see results on the right.