openapi: 3.1.0
info:
title: Ghost Content API
description: >-
The Ghost Content API is a RESTful, read-only API that delivers published
content from a Ghost site to any client. It provides access to posts, pages,
tags, authors, tiers, and settings resources. Access is controlled via a
Content API key provided as a query parameter, and all responses are returned
in JSON format. The API supports browse and read request types with powerful
filtering using the NQL query language, making it ideal for building custom
front-ends, static sites, mobile apps, and other content-driven applications
powered by Ghost as a headless CMS.
version: '5.0'
contact:
name: Ghost Foundation
url: https://ghost.org/docs/content-api/
termsOfService: https://ghost.org/terms/
externalDocs:
description: Ghost Content API Documentation
url: https://ghost.org/docs/content-api/
servers:
- url: https://{site}.ghost.io/ghost/api/content
description: Ghost Pro Hosted Site
variables:
site:
default: your-site
description: Your Ghost site subdomain
- url: '{protocol}://{domain}/ghost/api/content'
description: Self-Hosted Ghost Instance
variables:
protocol:
default: https
enum:
- https
- http
domain:
default: localhost:2368
description: Your Ghost instance domain and port
tags:
- name: Authors
description: >-
Authors represent the staff users who create content in a Ghost
publication.
- name: Pages
description: >-
Pages are static content resources in Ghost, similar to posts but used for
standalone pages like About or Contact.
- name: Posts
description: >-
Posts are the primary content resource in Ghost. Browse and read published
posts with full support for filtering, including by tag, author, and
featured status.
- name: Settings
description: >-
Settings provide access to global publication settings including title,
description, navigation, and other configuration values.
- name: Tiers
description: >-
Tiers represent the membership levels available for a Ghost publication,
including free and paid options.
security:
- contentApiKey: []
paths:
/posts/:
get:
operationId: browsePosts
summary: Browse posts
description: >-
Retrieve a paginated list of published posts. Supports filtering by tag,
author, featured status, and other fields using Ghost's NQL query
language. Results can be ordered and limited, and related resources like
authors and tags can be included.
tags:
- Posts
parameters:
- $ref: '#/components/parameters/includePostRelations'
- $ref: '#/components/parameters/fields'
- $ref: '#/components/parameters/filter'
- $ref: '#/components/parameters/limit'
- $ref: '#/components/parameters/page'
- $ref: '#/components/parameters/order'
- $ref: '#/components/parameters/formats'
responses:
'200':
description: A list of posts
content:
application/json:
schema:
type: object
properties:
posts:
type: array
items:
$ref: '#/components/schemas/Post'
meta:
$ref: '#/components/schemas/PaginationMeta'
'401':
$ref: '#/components/responses/Unauthorized'
/posts/{id}/:
get:
operationId: readPostById
summary: Read a post by ID
description: >-
Retrieve a single published post by its unique identifier. Related
resources like authors and tags can be included.
tags:
- Posts
parameters:
- $ref: '#/components/parameters/resourceId'
- $ref: '#/components/parameters/includePostRelations'
- $ref: '#/components/parameters/fields'
- $ref: '#/components/parameters/formats'
responses:
'200':
description: A single post
content:
application/json:
schema:
type: object
properties:
posts:
type: array
items:
$ref: '#/components/schemas/Post'
minItems: 1
maxItems: 1
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/posts/slug/{slug}/:
get:
operationId: readPostBySlug
summary: Read a post by slug
description: >-
Retrieve a single published post by its URL slug. This is useful when you
know the post's URL but not its ID.
tags:
- Posts
parameters:
- $ref: '#/components/parameters/resourceSlug'
- $ref: '#/components/parameters/includePostRelations'
- $ref: '#/components/parameters/fields'
- $ref: '#/components/parameters/formats'
responses:
'200':
description: A single post
content:
application/json:
schema:
type: object
properties:
posts:
type: array
items:
$ref: '#/components/schemas/Post'
minItems: 1
maxItems: 1
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/pages/:
get:
operationId: browsePages
summary: Browse pages
description: >-
Retrieve a paginated list of published pages. Pages function similarly to
posts but are used for static content. Supports the same filtering,
ordering, and inclusion options as posts.
tags:
- Pages
parameters:
- $ref: '#/components/parameters/includePostRelations'
- $ref: '#/components/parameters/fields'
- $ref: '#/components/parameters/filter'
- $ref: '#/components/parameters/limit'
- $ref: '#/components/parameters/page'
- $ref: '#/components/parameters/order'
- $ref: '#/components/parameters/formats'
responses:
'200':
description: A list of pages
content:
application/json:
schema:
type: object
properties:
pages:
type: array
items:
$ref: '#/components/schemas/Page'
meta:
$ref: '#/components/schemas/PaginationMeta'
'401':
$ref: '#/components/responses/Unauthorized'
/pages/{id}/:
get:
operationId: readPageById
summary: Read a page by ID
description: >-
Retrieve a single published page by its unique identifier.
tags:
- Pages
parameters:
- $ref: '#/components/parameters/resourceId'
- $ref: '#/components/parameters/includePostRelations'
- $ref: '#/components/parameters/fields'
- $ref: '#/components/parameters/formats'
responses:
'200':
description: A single page
content:
application/json:
schema:
type: object
properties:
pages:
type: array
items:
$ref: '#/components/schemas/Page'
minItems: 1
maxItems: 1
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/pages/slug/{slug}/:
get:
operationId: readPageBySlug
summary: Read a page by slug
description: >-
Retrieve a single published page by its URL slug.
tags:
- Pages
parameters:
- $ref: '#/components/parameters/resourceSlug'
- $ref: '#/components/parameters/includePostRelations'
- $ref: '#/components/parameters/fields'
- $ref: '#/components/parameters/formats'
responses:
'200':
description: A single page
content:
application/json:
schema:
type: object
properties:
pages:
type: array
items:
$ref: '#/components/schemas/Page'
minItems: 1
maxItems: 1
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/tags/:
get:
operationId: browseTags
summary: Browse tags
description: >-
Retrieve a paginated list of tags used to organize content. Supports
filtering, ordering, and including the count of posts associated with
each tag.
tags: []
parameters:
- $ref: '#/components/parameters/includeTagRelations'
- $ref: '#/components/parameters/fields'
- $ref: '#/components/parameters/filter'
- $ref: '#/components/parameters/limit'
- $ref: '#/components/parameters/page'
- $ref: '#/components/parameters/order'
responses:
'200':
description: A list of tags
content:
application/json:
schema:
type: object
properties:
tags:
type: array
items:
$ref: '#/components/schemas/Tag'
meta:
$ref: '#/components/schemas/PaginationMeta'
'401':
$ref: '#/components/responses/Unauthorized'
/tags/{id}/:
get:
operationId: readTagById
summary: Read a tag by ID
description: >-
Retrieve a single tag by its unique identifier.
tags: []
parameters:
- $ref: '#/components/parameters/resourceId'
- $ref: '#/components/parameters/includeTagRelations'
- $ref: '#/components/parameters/fields'
responses:
'200':
description: A single tag
content:
application/json:
schema:
type: object
properties:
tags:
type: array
items:
$ref: '#/components/schemas/Tag'
minItems: 1
maxItems: 1
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/tags/slug/{slug}/:
get:
operationId: readTagBySlug
summary: Read a tag by slug
description: >-
Retrieve a single tag by its URL slug.
tags: []
parameters:
- $ref: '#/components/parameters/resourceSlug'
- $ref: '#/components/parameters/includeTagRelations'
- $ref: '#/components/parameters/fields'
responses:
'200':
description: A single tag
content:
application/json:
schema:
type: object
properties:
tags:
type: array
items:
$ref: '#/components/schemas/Tag'
minItems: 1
maxItems: 1
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/authors/:
get:
operationId: browseAuthors
summary: Browse authors
description: >-
Retrieve a paginated list of authors (staff users) for the publication.
Supports including a count of posts per author using the
include=count.posts parameter.
tags:
- Authors
parameters:
- $ref: '#/components/parameters/includeAuthorRelations'
- $ref: '#/components/parameters/fields'
- $ref: '#/components/parameters/filter'
- $ref: '#/components/parameters/limit'
- $ref: '#/components/parameters/page'
- $ref: '#/components/parameters/order'
responses:
'200':
description: A list of authors
content:
application/json:
schema:
type: object
properties:
authors:
type: array
items:
$ref: '#/components/schemas/Author'
meta:
$ref: '#/components/schemas/PaginationMeta'
'401':
$ref: '#/components/responses/Unauthorized'
/authors/{id}/:
get:
operationId: readAuthorById
summary: Read an author by ID
description: >-
Retrieve a single author by their unique identifier.
tags:
- Authors
parameters:
- $ref: '#/components/parameters/resourceId'
- $ref: '#/components/parameters/includeAuthorRelations'
- $ref: '#/components/parameters/fields'
responses:
'200':
description: A single author
content:
application/json:
schema:
type: object
properties:
authors:
type: array
items:
$ref: '#/components/schemas/Author'
minItems: 1
maxItems: 1
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/authors/slug/{slug}/:
get:
operationId: readAuthorBySlug
summary: Read an author by slug
description: >-
Retrieve a single author by their URL slug.
tags:
- Authors
parameters:
- $ref: '#/components/parameters/resourceSlug'
- $ref: '#/components/parameters/includeAuthorRelations'
- $ref: '#/components/parameters/fields'
responses:
'200':
description: A single author
content:
application/json:
schema:
type: object
properties:
authors:
type: array
items:
$ref: '#/components/schemas/Author'
minItems: 1
maxItems: 1
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/tiers/:
get:
operationId: browseTiers
summary: Browse tiers
description: >-
Retrieve a paginated list of membership tiers configured for the
publication. Tiers define the access levels and pricing for members.
Use filter=visibility:public to retrieve only publicly visible tiers.
tags:
- Tiers
parameters:
- $ref: '#/components/parameters/fields'
- $ref: '#/components/parameters/filter'
- $ref: '#/components/parameters/limit'
- $ref: '#/components/parameters/page'
- $ref: '#/components/parameters/order'
responses:
'200':
description: A list of tiers
content:
application/json:
schema:
type: object
properties:
tiers:
type: array
items:
$ref: '#/components/schemas/Tier'
meta:
$ref: '#/components/schemas/PaginationMeta'
'401':
$ref: '#/components/responses/Unauthorized'
/tiers/{id}/:
get:
operationId: readTierById
summary: Read a tier by ID
description: >-
Retrieve a single membership tier by its unique identifier.
tags:
- Tiers
parameters:
- $ref: '#/components/parameters/resourceId'
- $ref: '#/components/parameters/fields'
responses:
'200':
description: A single tier
content:
application/json:
schema:
type: object
properties:
tiers:
type: array
items:
$ref: '#/components/schemas/Tier'
minItems: 1
maxItems: 1
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/settings/:
get:
operationId: readSettings
summary: Read settings
description: >-
Retrieve all public settings for the Ghost publication, including title,
description, logo, icon, cover image, language, timezone, navigation,
and other site-wide configuration values.
tags:
- Settings
responses:
'200':
description: Publication settings
content:
application/json:
schema:
type: object
properties:
settings:
$ref: '#/components/schemas/Settings'
'401':
$ref: '#/components/responses/Unauthorized'
components:
securitySchemes:
contentApiKey:
type: apiKey
in: query
name: key
description: >-
Content API key obtained from a custom integration in Ghost Admin.
Content API keys are safe for use in browsers and other insecure
environments as they only provide access to public data.
parameters:
resourceId:
name: id
in: path
required: true
description: The unique identifier of the resource
schema:
type: string
format: uuid
resourceSlug:
name: slug
in: path
required: true
description: The URL slug of the resource
schema:
type: string
includePostRelations:
name: include
in: query
required: false
description: >-
Comma-separated list of related resources to include. Supported values
are authors and tags.
schema:
type: string
enum:
- authors
- tags
- authors,tags
includeTagRelations:
name: include
in: query
required: false
description: >-
Include a count of posts associated with each tag.
schema:
type: string
enum:
- count.posts
includeAuthorRelations:
name: include
in: query
required: false
description: >-
Include a count of posts associated with each author.
schema:
type: string
enum:
- count.posts
fields:
name: fields
in: query
required: false
description: >-
Comma-separated list of fields to return in the response. Use this to
limit the size of the response by only requesting the fields you need.
schema:
type: string
filter:
name: filter
in: query
required: false
description: >-
Apply fine-grained filters using Ghost's NQL query language. Examples
include featured:true, tag:getting-started, visibility:public, and
combinations using plus and comma operators.
schema:
type: string
limit:
name: limit
in: query
required: false
description: >-
Maximum number of resources to return per page. Defaults to 15. Use all
to return all resources without pagination.
schema:
oneOf:
- type: integer
minimum: 1
- type: string
enum:
- all
default: 15
page:
name: page
in: query
required: false
description: >-
Page number for paginated results. Defaults to 1.
schema:
type: integer
minimum: 1
default: 1
order:
name: order
in: query
required: false
description: >-
Field and direction to order results by, for example published_at DESC
or title ASC.
schema:
type: string
formats:
name: formats
in: query
required: false
description: >-
Comma-separated list of content formats to include. By default only html
is returned. Use formats=html,plaintext to also include plaintext.
schema:
type: string
enum:
- html
- plaintext
- html,plaintext
responses:
Unauthorized:
description: Authentication failed or API key is missing
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
NotFound:
description: The requested resource was not found
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
schemas:
Post:
type: object
description: >-
A post represents a piece of published content in a Ghost publication.
properties:
id:
type: string
format: uuid
description: Unique identifier for the post
uuid:
type: string
format: uuid
description: Universally unique identifier for the post
title:
type: string
description: Title of the post
slug:
type: string
description: URL-safe slug derived from the title
html:
type: string
description: HTML content of the post
plaintext:
type: string
description: Plain text content of the post, available when requested via formats
comment_id:
type: string
description: Identifier used for the commenting system
feature_image:
type: string
format: uri
description: URL of the featured image for the post
nullable: true
feature_image_alt:
type: string
description: Alt text for the featured image
nullable: true
feature_image_caption:
type: string
description: Caption for the featured image
nullable: true
featured:
type: boolean
description: Whether the post is marked as featured
visibility:
type: string
description: Visibility level of the post
enum:
- public
- members
- paid
- tiers
created_at:
type: string
format: date-time
description: Timestamp when the post was created
updated_at:
type: string
format: date-time
description: Timestamp when the post was last updated
published_at:
type: string
format: date-time
description: Timestamp when the post was published
nullable: true
custom_excerpt:
type: string
description: Custom excerpt for the post
nullable: true
codeinjection_head:
type: string
description: Code injected into the head of the post page
nullable: true
codeinjection_foot:
type: string
description: Code injected into the foot of the post page
nullable: true
custom_template:
type: string
description: Custom template assigned to the post
nullable: true
canonical_url:
type: string
format: uri
description: Canonical URL for the post
nullable: true
url:
type: string
format: uri
description: Full URL of the post on the Ghost site
excerpt:
type: string
description: Auto-generated excerpt from the post content
reading_time:
type: integer
description: Estimated reading time in minutes
minimum: 0
access:
type: boolean
description: Whether the current request has access to the full post content
og_image:
type: string
format: uri
description: Open Graph image URL
nullable: true
og_title:
type: string
description: Open Graph title
nullable: true
og_description:
type: string
description: Open Graph description
nullable: true
twitter_image:
type: string
format: uri
description: Twitter card image URL
nullable: true
twitter_title:
type: string
description: Twitter card title
nullable: true
twitter_description:
type: string
description: Twitter card description
nullable: true
meta_title:
type: string
description: SEO meta title
nullable: true
meta_description:
type: string
description: SEO meta description
nullable: true
email_subject:
type: string
description: Custom subject for email newsletters
nullable: true
frontmatter:
type: string
description: Custom frontmatter data
nullable: true
tags:
type: array
description: Tags associated with the post, included when requested
items:
$ref: '#/components/schemas/Tag'
authors:
type: array
description: Authors of the post, included when requested
items:
$ref: '#/components/schemas/Author'
primary_author:
description: Primary author of the post, included when authors are requested
$ref: '#/components/schemas/Author'
primary_tag:
description: Primary tag of the post, included when tags are requested
$ref: '#/components/schemas/Tag'
nullable: true
Page:
type: object
description: >-
A page represents static content in a Ghost publication, sharing the
same structure as a post but used for standalone pages.
allOf:
- $ref: '#/components/schemas/Post'
Tag:
type: object
description: >-
A tag is used to organize and categorize content in Ghost. Tags with
slugs starting with hash are internal tags not visible to readers.
properties:
id:
type: string
format: uuid
description: Unique identifier for the tag
name:
type: string
description: Name of the tag
slug:
type: string
description: URL-safe slug for the tag
description:
type: string
description: Description of the tag
nullable: true
feature_image:
type: string
format: uri
description: Featured image URL for the tag
nullable: true
visibility:
type: string
description: Visibility of the tag
enum:
- public
- internal
og_image:
type: string
format: uri
description: Open Graph image for the tag page
nullable: true
og_title:
type: string
description: Open Graph title for the tag page
nullable: true
og_description:
type: string
description: Open Graph description for the tag page
nullable: true
twitter_image:
type: string
format: uri
description: Twitter card image for the tag page
nullable: true
twitter_title:
type: string
description: Twitter card title for the tag page
nullable: true
twitter_description:
type: string
description: Twitter card description for the tag page
nullable: true
meta_title:
type: string
description: SEO meta title for the tag page
nullable: true
meta_description:
type: string
description: SEO meta description for the tag page
nullable: true
codeinjection_head:
type: string
description: Code injected into the head on tag pages
nullable: true
codeinjection_foot:
type: string
description: Code injected into the foot on tag pages
nullable: true
canonical_url:
type: string
format: uri
description: Canonical URL for the tag page
nullable: true
accent_color:
type: string
description: Accent color for the tag
nullable: true
pattern: '^#[0-9a-fA-F]{6}$'
url:
type: string
format: uri
description: Full URL of the tag page
count:
type: object
description: Count data, included when requested via include=count.posts
properties:
posts:
type: integer
description: Number of posts with this tag
minimum: 0
Author:
type: object
description: >-
An author represents a staff user who creates content in a Ghost
publication.
properties:
id:
type: string
format: uuid
description: Unique identifier for the author
name:
type: string
description: Display name of the author
slug:
type: string
description: URL-safe slug for the author
profile_image:
type: string
format: uri
description: Profile image URL
nullable: true
cover_image:
type: string
format: uri
description: Cover image URL for the author page
nullable: true
bio:
type: string
description: Author biography
nullable: true
website:
type: string
format: uri
description: Author personal website URL
nullable: true
location:
type: string
description: Author location
nullable: true
facebook:
type: string
description: Facebook username
nullable: true
twitter:
type: string
description: Twitter handle
nullable: true
meta_title:
type: string
description: SEO meta title for the author page
nullable: true
meta_description:
type: string
description: SEO meta description for the author page
nullable: true
url:
type: string
format: uri
description: Full URL of the author page
count:
type: object
description: Count data, included when requested via include=count.posts
properties:
posts:
type: integer
description: Number of posts by this author
minimum: 0
Tier:
type: object
description: >-
A tier represents a membership level in a Ghost publication with
associated pricing and benefits.
properties:
id:
type: string
format: uuid
description: Unique identifier for the tier
name:
type: string
description: Name of the tier
slug:
type: string
description: URL-safe slug for the tier
description:
type: string
description: Description of the tier
nullable: true
active:
type: boolean
description: Whether the tier is currently active
type:
type: string
description: Type of tier
enum:
- free
- paid
welcome_page_url:
type: string
format: uri
description: URL of the welcome page shown after signup
nullable: true
created_at:
type: string
format: date-time
description: Timestamp when the tier was created
updated_at:
type: string
format: date-time
description: Timestamp when the tier was last updated
visibility:
type: string
description: Visibility of the tier
enum:
- public
- none
monthly_price:
type: integer
description: M
# --- truncated at 32 KB (37 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/ghost/refs/heads/main/openapi/ghost-content-api-openapi.yml