API Reference
Complete reference for all GraphQL operations, types, and inputs available in the StormyCMS Public API.
Base URL
https://api.stormycms.com/graphqlAuthentication
All requests must include authentication headers:
| Header | Value | Required |
|---|---|---|
x-site-api-key | sk_site_... | Yes |
x-client-id | Your site's client ID | Yes |
Content-Type | application/json | Yes |
Alternative authentication using Bearer token:
| Header | Value | Required |
|---|---|---|
Authorization | Bearer sk_site_... | Yes |
x-client-id | Your site's client ID | Yes |
Content-Type | application/json | Yes |
Rate Limits
- Site API Keys: 10,000 requests per hour per key
- Rate limit headers are included in responses:
X-RateLimit-Limit: Maximum requests per hourX-RateLimit-Remaining: Remaining requestsX-RateLimit-Reset: Unix timestamp when limit resets
Queries
Page Queries
page(id: ID!)
Retrieve a specific page by its ID.
Parameters:
id(ID!) - Unique identifier of the page
Returns: Page
Example:
query { page(id: "page_123") { id meta { title description keywords } layout_id components { id name text } }}pages(limit: Int, offset: Int)
Get a paginated list of pages.
Parameters:
limit(Int, optional) - Maximum pages to return (default: 20, max: 100)offset(Int, optional) - Pages to skip for pagination (default: 0)
Returns: [Page!]!
Example:
query { pages(limit: 10, offset: 20) { id meta { title } created_at }}all_layouts()
Retrieve all available layouts in the system.
Returns: [Layout!]!
Layout Queries
layout(id: ID!)
Retrieve a specific layout by its ID.
Parameters:
id(ID!) - Unique identifier of the layout
Returns: Layout
layouts()
Get all layouts.
Returns: [Layout!]!
Site Queries
getSite(id: ID!)
Get site information. Only accessible with the site's own API key.
Parameters:
id(ID!) - Unique identifier of the site
Returns: Site
Mutations
Page Mutations
create_page(meta: MetadataInput!, components: [ComponentInput!]!, layout_id: ID!, component_ids: [ID!]!)
Create a new page. Requires site admin permissions.
Parameters:
meta(MetadataInput!) - Page metadatacomponents([ComponentInput!]!) - Array of componentslayout_id(ID!) - Layout to associate with the pagecomponent_ids([ID!]!) - Array of existing component IDs
Returns: Page
update_page(id: ID!, meta: MetadataInput!, components: [ComponentInput!]!, layout_id: ID!, component_ids: [ID!]!)
Update an existing page. Requires site editor permissions.
Parameters:
id(ID!) - ID of the page to updatemeta(MetadataInput!) - Updated metadatacomponents([ComponentInput!]!) - Updated componentslayout_id(ID!) - Updated layout IDcomponent_ids([ID!]!) - Updated component IDs
Returns: Page
delete_page(id: ID!)
Delete a page.
Parameters:
id(ID!) - ID of the page to delete
Returns: Page
Layout Mutations
create_layout(name: String!, components: [ComponentInput!]!, component_ids: [ID!]!)
Create a new layout.
Parameters:
name(String!) - Name of the layoutcomponents([ComponentInput!]!) - Array of componentscomponent_ids([ID!]!) - Array of component IDs
Returns: Layout
update_layout(id: ID!, name: String!, components: [ComponentInput!]!, component_ids: [ID!]!)
Update an existing layout.
Parameters:
id(ID!) - ID of the layout to updatename(String!) - Updated namecomponents([ComponentInput!]!) - Updated componentscomponent_ids([ID!]!) - Updated component IDs
Returns: Layout
delete_layout(id: ID!)
Delete a layout.
Parameters:
id(ID!) - ID of the layout to delete
Returns: Layout
Types
Page
type Page { id: ID! # Unique identifier meta: Metadata! # Page metadata layouts: [Layout!]! # Associated layouts layout_id: ID! # Primary layout components: [Component!]! # Page components component_ids: [ID!]! # Component IDs site_id: ID! # Site ID}Layout
type Layout { id: ID! # Unique identifier name: String! # Layout name props: [[String!]!]! # Translated properties components: [Component!]! # Layout components component_ids: [ID!]! # Component IDs outlet_id: ID! # Content outlet ID child_layout_id: ID # Child layout ID (optional)}Site
type Site { id: ID! # Unique identifier name: String! # Site name owner_id: ID! # Owner user ID admin_ids: [UserIdWithDate!]! # Admin users contributor_ids: [UserIdWithDate!]! # Contributors client_id: String! # OAuth client ID redirect_urls: [String!]! # OAuth redirect URLs created_at: String! # Creation timestamp}Metadata
type Metadata { title: String! # Page title description: String! # SEO description keywords: [String!]! # SEO keywords}Component
type Component { id: ID! # Unique identifier name: String! # Component type/name props: [[String!]!]! # Translated properties text: String! # Text content child_ids: [ID!]! # Child component IDs}UserIdWithDate
type UserIdWithDate { user_id: ID! # User ID add_date: String! # When user was added}Input Types
MetadataInput
input MetadataInput { title: String # Optional title description: String # Optional description keywords: [String] # Optional keywords}ComponentInput
input ComponentInput { id: ID # Optional ID name: String # Optional component name props: [PropInput] # Optional properties text: [TranslationInput] # Optional text content child_ids: [ID] # Optional child IDs}PropInput
input PropInput { key: String! # Property key translations: [TranslationInput]! # Property translations}TranslationInput
input TranslationInput { locale: String! # Language code (e.g., "en", "es") value: String! # Translated value}Error Responses
HTTP Status Codes
| Code | Meaning |
|---|---|
| 200 | Success |
| 400 | Bad Request - Invalid query or variables |
| 401 | Unauthorized - Invalid or missing API key |
| 403 | Forbidden - Insufficient permissions |
| 429 | Too Many Requests - Rate limit exceeded |
| 500 | Internal Server Error |
GraphQL Errors
GraphQL errors are returned in the response body:
{ "errors": [ { "message": "Page not found", "locations": [{ "line": 2, "column": 3 }], "path": ["page"], "extensions": { "code": "NOT_FOUND" } } ], "data": null}Common error codes:
NOT_FOUND- Resource doesn't existUNAUTHORIZED- Authentication requiredFORBIDDEN- Insufficient permissionsVALIDATION_ERROR- Invalid input dataRATE_LIMITED- Too many requests
SDK Examples
JavaScript/TypeScript
class StormyCMS { private apiKey: string; private clientId: string; private baseUrl: string;
constructor(apiKey: string, clientId: string) { this.apiKey = apiKey; this.clientId = clientId; this.baseUrl = 'https://api.stormycms.com/graphql'; }
async query(query: string, variables?: any) { const response = await fetch(this.baseUrl, { method: 'POST', headers: { 'Content-Type': 'application/json', 'x-site-api-key': this.apiKey, 'x-client-id': this.clientId, }, body: JSON.stringify({ query, variables }), });
if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); }
const result = await response.json();
if (result.errors) { throw new Error(result.errors[0].message); }
return result.data; }
async getPage(id: string) { return this.query(` query GetPage($id: ID!) { page(id: $id) { id meta { title description } components { id name text } } } `, { id }); }}cURL
curl -X POST https://api.stormycms.com/graphql \ -H "Content-Type: application/json" \ -H "x-site-api-key: sk_site_abc123def456" \ -H "x-client-id: YOUR_CLIENT_ID" \ -d '{ "query": "query { pages(limit: 5) { id meta { title } } }" }'Next Steps
- Getting Started - Set up your account
- GraphQL Queries - Learn to fetch data
- GraphQL Mutations - Learn to modify data
- Examples - Practical implementations
Last updated: 2/27/26, 3:48 AM