Skip to main content
Marble’s content model is intentionally small. Everything centers on the post, which is connected to authors, a category, tags, and optional custom fields. Understanding how these relate makes it straightforward to query and render content from your frontend.

The entities at a glance

EntityWhat it isRelationship to a post
PostA single piece of content (an article, a changelog entry, a page).The core entity.
AuthorA byline — name, bio, avatar, and social links.A post has one or more authors.
CategoryA single primary grouping for a post.A post belongs to exactly one category.
TagA lightweight, flexible label.A post can have many tags.
Custom fieldWorkspace-defined metadata.Optional extra values on a post.
Every entity is scoped to a workspace and has a URL-friendly slug that’s unique within that workspace. You can fetch most resources by either their id or their slug.

Posts

A post is the unit of content you write in the editor. Beyond its title and body, a post carries the metadata your frontend needs to render and route it. Key fields returned by the API:
FieldDescription
idUnique identifier.
slugURL-friendly identifier, unique per workspace.
titleThe post title.
descriptionShort summary, useful for previews and SEO meta tags.
contentThe body, returned as HTML or Markdown (see content format).
statuspublished or draft.
featuredWhether the post is flagged as featured.
coverImageURL of the cover image, or null.
publishedAtPublish timestamp (ISO 8601, UTC).
updatedAtLast-updated timestamp.
authorsArray of author objects.
categoryThe post’s single category.
tagsArray of tag objects.
fieldsCustom field values, keyed by field key.

Content format

Post content can be delivered as HTML (default) or Markdown using the format query parameter — useful if you’d rather render Markdown yourself on the frontend:
curl -H "Authorization: YOUR_API_KEY" \
  "https://api.marblecms.com/v1/posts?format=markdown"

Status and drafts

A post is either published or draft. By default the API returns only published posts. Pass status=draft or status=all to include unpublished content — handy for building a preview environment.

Authors

An author is a byline you attach to posts. Authors are managed at the workspace level and reused across posts, so updating an author’s bio updates it everywhere. An author includes name, slug, bio, image, role, and an array of socials (each with a platform and url). A post can have multiple authors, with one designated as the primary author.
Authors are distinct from workspace members. A member has dashboard access; an author is a byline that may or may not correspond to a member. See Workspaces & Teams.

Categories

A category is the single, primary grouping for a post — think “Engineering”, “Product”, or “Changelog”. Each post belongs to exactly one category, which makes categories ideal for top-level sections and routing (e.g. /blog/[category]/[slug]). A category has a name, slug, and optional description. You can filter posts by category, or exclude categories, when listing posts:
# Only posts in the "engineering" or "product" categories
curl -H "Authorization: YOUR_API_KEY" \
  "https://api.marblecms.com/v1/posts?categories=engineering,product"

# Everything except the "changelog" category
curl -H "Authorization: YOUR_API_KEY" \
  "https://api.marblecms.com/v1/posts?excludeCategories=changelog"

Tags

A tag is a lightweight, flexible label. Unlike categories, a post can have many tags, making them well suited to cross-cutting topics like “javascript”, “tutorial”, or “release”. Tags have the same shape as categories (name, slug, description) and support the same include/exclude filtering via the tags and excludeTags parameters.
Category vs. tag: use a single category for the primary section a post belongs to, and tags for the many topics it touches.

Custom fields

Custom fields let you extend the post schema with workspace-specific metadata — a release date, a priority score, a list of related links — without changing your code on the CMS side. Field values come back on each post under fields, keyed by the field’s key. See Custom Fields for setup and the full list of field types.

How it maps to the API

When you fetch a post, the related entities are embedded directly in the response, so a single request gives you everything you need to render it:
{
  "post": {
    "id": "cryitfjp5678mn09qrstuvwx",
    "slug": "getting-started-with-nextjs",
    "title": "Getting Started with Next.js",
    "status": "published",
    "description": "A beginner's guide to Next.js",
    "coverImage": "https://media.marblecms.com/cover.jpg",
    "publishedAt": "2024-01-15T10:00:00Z",
    "authors": [
      { "name": "John Doe", "slug": "john-doe", "image": "...", "socials": [] }
    ],
    "category": { "name": "Engineering", "slug": "engineering" },
    "tags": [{ "name": "Next.js", "slug": "nextjs" }],
    "fields": { "release_date": "2024-01-15" },
    "content": "<p>Hello world</p>"
  }
}

Next steps

Custom Fields

Extend posts with your own metadata.

Filtering

Query posts by category, tag, and search.

API Reference

Full endpoint reference for every resource.

TypeScript SDK

Typed access to posts, authors, categories, and tags.