GraphQL API

Explore FlowCMS's powerful GraphQL API. Query, mutate, and subscribe to content changes in real-time. Our schema-first approach gives you exactly the data you need — nothing more, nothing less.

Endpoint https://api.flowcms.io/graphql 📋
Method POST 📋
Auth Bearer Token 📋

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.

💡
Pro Tip: GraphQL lets you request exactly the fields you need in a single request. Avoid over-fetching and under-fetching data compared to traditional REST APIs.
GraphQL
# 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:

Authorization: Bearer fc_live_your_api_token_here
cURL
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 } } } }"}'
⚠️
Security Note: Never expose your API tokens in client-side code. Use environment variables and server-side proxying for production applications.

Rate Limiting #

GraphQL requests are rate-limited based on your plan tier. Rate limit information is returned in response headers.

Starter
1,000
requests / hour
Professional
50,000
requests / hour
Enterprise
Unlimited
custom limits
Response Headers
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.

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

Query content(id: ID!): Content

Fetch a single content item by its unique ID.

Parameters
Parameter Type Required Description
id ID! Required The unique content item ID
Query
{
  content(id: "cnt_abc123") {
    id
    title
    slug
    body
    status
    publishedAt
    updatedAt
    author {
      id
      name
      email
    }
    media {
      url
      alt
    }
  }
}
Query contentBySlug(slug: String!): Content

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")
Query
{
  contentBySlug(slug: "getting-started-with-flowcms") {
    id
    title
    slug
    body
    excerpt
    featuredImage {
      url
      width
      height
    }
  }
}
Query contents(first: Int, after: String, filter: ContentFilterInput, sort: String): ContentConnection

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")
Query
{
  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
    }
  }
}
Query media(id: ID): MediaItem

Fetch media item metadata by its ID.

Query
{
  media(id: "med_xyz789") {
    id
    filename
    url
    mimeType
    size
    width
    height
    alt
    uploadedAt
  }
}
Query currentUser: User

Fetch the currently authenticated user's profile.

Query
{
  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.

Mutation createContent(input: CreateContentInput!): Content!

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
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"]
  }
}
Mutation updateContent(id: ID!, input: UpdateContentInput!): Content!

Update an existing content item. Only provide the fields you want to change.

Mutation
mutation UpdatePost (
  $id: ID!
  $input: UpdateContentInput!
) {
  updateContent(id: $id, input: $input) {
    id
    title
    body
    updatedAt
  }
}
Mutation deleteContent(id: ID!): Boolean!

Permanently delete a content item. This action cannot be undone.

Mutation
mutation DeletePost ($id: ID!) {
  deleteContent(id: $id)
}

# Response
{
  "data": {
    "deleteContent": true
  }
}
Mutation publishContent(id: ID!): Content!

Publish a draft content item, making it publicly accessible.

Mutation
mutation PublishPost ($id: ID!) {
  publishContent(id: $id) {
    id
    status
    publishedAt
  }
}
Mutation uploadMedia(file: Upload!, alt: String): MediaItem!

Upload a media file to FlowCMS. Returns the media item with CDN URL.

💡
Note: File uploads use the @upload directive. Requires a GraphQL client that supports multipart requests (e.g., Apollo Client, GraphiQL).
Mutation
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.

ℹ️
WebSocket Endpoint: wss://api.flowcms.io/graphql — Subscriptions automatically fall back to SSE if WebSocket is unavailable.
Sub contentCreated: Content!

Triggered when a new content item is created.

Subscription
subscription OnContentCreated {
  contentCreated {
    id
    title
    slug
    status
    author {
      name
    }
  }
}
Sub contentUpdated: Content!

Triggered when a content item is updated.

Subscription
subscription OnContentUpdated {
  contentUpdated {
    id
    title
    updatedAt
  }
}
Sub contentPublished: Content!

Triggered when a content item is published. Useful for triggering build pipelines or cache invalidation.

Subscription
subscription OnContentPublished {
  contentPublished {
    id
    slug
    status
    publishedAt
  }
}

Schema Types #

Explore the GraphQL types that make up the FlowCMS API schema.

Type Content A content item in FlowCMS
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
Type ContentConnection Paginated content results (Relay spec)
Field Type Description
edges [ContentEdge!]! Array of edges
pageInfo PageInfo! Pagination metadata
Type MediaItem Uploaded media asset
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
Type User A FlowCMS user account
Field Type Description
id ID! Unique identifier
name String! Display name
email String! Email address
role String! User role (admin, editor, viewer)
avatar String Avatar URL
Enum ContentStatus Possible content statuses
Value Description
DRAFT Unpublished draft
PUBLISHED Live and publicly accessible
ARCHIVED Archived and hidden
Enum SortOrder Sort direction
Value Description
ASC Ascending order
DESC Descending order
Input CreateContentInput Input for creating content
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
Input ContentFilterInput Filter content items
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.

Query Editor
Response
{  "data": { "contents": { "edges": [ { "node": { "id": "cnt_8f3k2m9p", "title": "Getting Started with FlowCMS GraphQL", "slug": "getting-started-with-flowcms-graphql", "status": "PUBLISHED", "publishedAt": "2025-01-15T10:30:00Z", "author": { "name": "Sarah Chen", "avatar": "https://cdn.flowcms.io/avatars/sarah.jpg" }, "tags": ["graphql", "tutorial", "cms"] } }, { "node": { "id": "cnt_7d2j1l8n", "title": "Building Real-Time Apps with Subscriptions", "slug": "real-time-apps-subscriptions", "status": "PUBLISHED", "publishedAt": "2025-01-12T14:15:00Z", "author": { "name": "Marcus Rivera", "avatar": "https://cdn.flowcms.io/avatars/marcus.jpg" }, "tags": ["graphql", "subscriptions", "real-time"] } } ], "pageInfo": { "hasNextPage": true, "endCursor": "YXJyYXljb25uZWN0aW9uOjE=" } } } }
Query Variables