Ghost Content API

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, and all responses are returned in JSON format.

OpenAPI Specification

ghost-content-api-openapi.yml Raw ↑
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