Ghost Posts API

Create, read, update, and delete posts. Posts are the primary content resource in Ghost and support rich content via the Lexical editor format.

OpenAPI Specification

ghost-posts-api-openapi.yml Raw ↑
openapi: 3.1.0
info:
  title: Ghost Admin Authors Posts API
  description: The Ghost Admin API provides full read and write access to all content and configuration within a Ghost publication. It enables developers to create, update, and delete posts, pages, tags, members, tiers, newsletters, and offers programmatically. Authentication is handled via JSON Web Tokens generated from an Admin API key, integration tokens, or staff access tokens. The Admin API supports everything the Ghost Admin interface can do and more, making it suitable for building custom publishing workflows, content automation, member management systems, and advanced integrations.
  version: '5.0'
  contact:
    name: Ghost Foundation
    url: https://ghost.org/docs/admin-api/
  termsOfService: https://ghost.org/terms/
servers:
- url: https://{site}.ghost.io/ghost/api/admin
  description: Ghost Pro Hosted Site
  variables:
    site:
      default: your-site
      description: Your Ghost site subdomain
- url: '{protocol}://{domain}/ghost/api/admin'
  description: Self-Hosted Ghost Instance
  variables:
    protocol:
      default: https
      enum:
      - https
      - http
    domain:
      default: localhost:2368
      description: Your Ghost instance domain and port
security:
- adminApiToken: []
tags:
- name: Posts
  description: Create, read, update, and delete posts. Posts are the primary content resource in Ghost and support rich content via the Lexical editor format.
paths:
  /posts/:
    get:
      operationId: adminBrowsePosts
      summary: Browse posts
      description: Retrieve a paginated list of posts with all statuses including draft, scheduled, and published. Supports filtering, ordering, and including related resources.
      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'
    post:
      operationId: adminCreatePost
      summary: Create a post
      description: Create a new post. The title field is required, all other fields are optional and will have defaults applied. Content can be provided in Lexical or HTML format. Tags can be specified by name or as full tag objects. If a tag does not exist, it will be created automatically.
      tags:
      - Posts
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - posts
              properties:
                posts:
                  type: array
                  items:
                    $ref: '#/components/schemas/PostInput'
                  minItems: 1
                  maxItems: 1
      responses:
        '201':
          description: Post created successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  posts:
                    type: array
                    items:
                      $ref: '#/components/schemas/Post'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '422':
          $ref: '#/components/responses/ValidationError'
  /posts/{id}/:
    get:
      operationId: adminReadPost
      summary: Read a post by ID
      description: Retrieve a single post by its unique identifier, including draft and scheduled posts.
      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'
    put:
      operationId: adminUpdatePost
      summary: Update a post
      description: Update an existing post. The updated_at field must be sent with the current value to prevent update collisions. Only the fields being changed need to be included in the request body, along with updated_at.
      tags:
      - Posts
      parameters:
      - $ref: '#/components/parameters/resourceId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - posts
              properties:
                posts:
                  type: array
                  items:
                    $ref: '#/components/schemas/PostInput'
                  minItems: 1
                  maxItems: 1
      responses:
        '200':
          description: Post updated successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  posts:
                    type: array
                    items:
                      $ref: '#/components/schemas/Post'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          description: Update collision due to stale updated_at value
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          $ref: '#/components/responses/ValidationError'
    delete:
      operationId: adminDeletePost
      summary: Delete a post
      description: Permanently delete a post by its unique identifier.
      tags:
      - Posts
      parameters:
      - $ref: '#/components/parameters/resourceId'
      responses:
        '204':
          description: Post deleted successfully
        '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_2'
      - $ref: '#/components/parameters/fields_2'
      - $ref: '#/components/parameters/formats_2'
      responses:
        '200':
          description: A single post
          content:
            application/json:
              schema:
                type: object
                properties:
                  posts:
                    type: array
                    items:
                      $ref: '#/components/schemas/Post_2'
                    minItems: 1
                    maxItems: 1
        '401':
          $ref: '#/components/responses/Unauthorized_2'
        '404':
          $ref: '#/components/responses/NotFound'
components:
  schemas:
    Post_2:
      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_2'
        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_2'
          nullable: true
    Tag:
      type: object
      description: A tag for organizing and categorizing content.
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier
        name:
          type: string
          description: Tag name
        slug:
          type: string
          description: URL-safe slug
        description:
          type: string
          description: Tag description
          nullable: true
        feature_image:
          type: string
          format: uri
          description: Featured image URL
          nullable: true
        visibility:
          type: string
          description: Visibility setting
          enum:
          - public
          - internal
        og_image:
          type: string
          format: uri
          nullable: true
          description: Open Graph image URL
        og_title:
          type: string
          nullable: true
          description: Open Graph title
        og_description:
          type: string
          nullable: true
          description: Open Graph description
        twitter_image:
          type: string
          format: uri
          nullable: true
          description: Twitter card image URL
        twitter_title:
          type: string
          nullable: true
          description: Twitter card title
        twitter_description:
          type: string
          nullable: true
          description: Twitter card description
        meta_title:
          type: string
          nullable: true
          description: SEO meta title
        meta_description:
          type: string
          nullable: true
          description: SEO meta description
        codeinjection_head:
          type: string
          nullable: true
          description: Code injection in the head
        codeinjection_foot:
          type: string
          nullable: true
          description: Code injection in the foot
        canonical_url:
          type: string
          format: uri
          nullable: true
          description: Canonical URL
        accent_color:
          type: string
          nullable: true
          description: Accent color hex code
          pattern: ^#[0-9a-fA-F]{6}$
        url:
          type: string
          format: uri
          description: Full URL of the tag page
        created_at:
          type: string
          format: date-time
          description: Creation timestamp
        updated_at:
          type: string
          format: date-time
          description: Last update timestamp
    ErrorResponse:
      type: object
      description: Standard Ghost API error response
      properties:
        errors:
          type: array
          items:
            type: object
            properties:
              message:
                type: string
                description: Human-readable error message
              type:
                type: string
                description: Error type identifier
              context:
                type: string
                description: Additional error context
                nullable: true
    Tag_2:
      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
    User:
      type: object
      description: A staff user account in the Ghost publication.
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier
        name:
          type: string
          description: Display name
        slug:
          type: string
          description: URL-safe slug
        email:
          type: string
          format: email
          description: Email address
        profile_image:
          type: string
          format: uri
          description: Profile image URL
          nullable: true
        cover_image:
          type: string
          format: uri
          description: Cover image URL
          nullable: true
        bio:
          type: string
          description: Biography
          nullable: true
        website:
          type: string
          format: uri
          description: Personal website URL
          nullable: true
        location:
          type: string
          description: Location
          nullable: true
        facebook:
          type: string
          description: Facebook username
          nullable: true
        twitter:
          type: string
          description: Twitter handle
          nullable: true
        accessibility:
          type: string
          description: Accessibility settings JSON
          nullable: true
        status:
          type: string
          description: User account status
          enum:
          - active
          - inactive
          - locked
        meta_title:
          type: string
          nullable: true
          description: SEO meta title
        meta_description:
          type: string
          nullable: true
          description: SEO meta description
        tour:
          type: string
          description: Onboarding tour progress JSON
          nullable: true
        last_seen:
          type: string
          format: date-time
          description: Last login timestamp
          nullable: true
        url:
          type: string
          format: uri
          description: Full URL of the author page
        roles:
          type: array
          description: Assigned roles
          items:
            type: object
            properties:
              id:
                type: string
                format: uuid
                description: Role identifier
              name:
                type: string
                description: Role name
              description:
                type: string
                description: Role description
        created_at:
          type: string
          format: date-time
          description: Account creation timestamp
        updated_at:
          type: string
          format: date-time
          description: Last update timestamp
    PostInput:
      type: object
      description: Input fields for creating or updating a post or page.
      properties:
        title:
          type: string
          description: Title of the post
        slug:
          type: string
          description: Custom URL slug
        lexical:
          type: string
          description: Content in Lexical editor format (JSON string)
        html:
          type: string
          description: Content in HTML format, converted to Lexical on save
        status:
          type: string
          description: Publication status
          enum:
          - published
          - draft
          - scheduled
        visibility:
          type: string
          description: Access visibility level
          enum:
          - public
          - members
          - paid
          - tiers
        featured:
          type: boolean
          description: Whether the post is featured
        feature_image:
          type: string
          format: uri
          description: Featured image URL
          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
        custom_excerpt:
          type: string
          description: Custom excerpt
          nullable: true
        codeinjection_head:
          type: string
          description: Code injection in the head
          nullable: true
        codeinjection_foot:
          type: string
          description: Code injection in the foot
          nullable: true
        custom_template:
          type: string
          description: Custom template name
          nullable: true
        canonical_url:
          type: string
          format: uri
          description: Canonical URL
          nullable: true
        published_at:
          type: string
          format: date-time
          description: Scheduled publication time
          nullable: true
        updated_at:
          type: string
          format: date-time
          description: Required for updates to prevent collisions
        tags:
          type: array
          description: Tags to associate, can be name strings or tag objects
          items:
            oneOf:
            - type: object
              properties:
                name:
                  type: string
                slug:
                  type: string
            - $ref: '#/components/schemas/Tag'
        authors:
          type: array
          description: Authors to associate
          items:
            type: object
            properties:
              id:
                type: string
                format: uuid
              slug:
                type: string
              email:
                type: string
                format: email
        email_subject:
          type: string
          description: Custom email newsletter subject
          nullable: true
        og_image:
          type: string
          format: uri
          nullable: true
          description: Open Graph image URL
        og_title:
          type: string
          nullable: true
          description: Open Graph title
        og_description:
          type: string
          nullable: true
          description: Open Graph description
        twitter_image:
          type: string
          format: uri
          nullable: true
          description: Twitter card image URL
        twitter_title:
          type: string
          nullable: true
          description: Twitter card title
        twitter_description:
          type: string
          nullable: true
          description: Twitter card description
        meta_title:
          type: string
          nullable: true
          description: SEO meta title
        meta_description:
          type: string
          nullable: true
          description: SEO meta description
    PaginationMeta:
      type: object
      description: Pagination metadata
      properties:
        pagination:
          type: object
          properties:
            page:
              type: integer
              description: Current page
              minimum: 1
            limit:
              type: integer
              description: Items per page
              minimum: 1
            pages:
              type: integer
              description: Total pages
              minimum: 1
            total:
              type: integer
              description: Total items
              minimum: 0
            next:
              type: integer
              description: Next page number
              nullable: true
            prev:
              type: integer
              description: Previous page number
              nullable: true
    Post:
      type: object
      description: A post or page resource with all content, metadata, and relationships.
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier
        uuid:
          type: string
          format: uuid
          description: Universally unique identifier
        title:
          type: string
          description: Title of the post
        slug:
          type: string
          description: URL-safe slug
        lexical:
          type: string
          description: Post content in Lexical editor format (JSON string)
        html:
          type: string
          description: Rendered HTML content
        plaintext:
          type: string
          description: Plain text content
        comment_id:
          type: string
          description: Commenting system identifier
        feature_image:
          type: string
          format: uri
          description: Featured image URL
          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 featured
        status:
          type: string
          description: Publication status
          enum:
          - published
          - draft
          - scheduled
          - sent
        visibility:
          type: string
          description: Access visibility level
          enum:
          - public
          - members
          - paid
          - tiers
        created_at:
          type: string
          format: date-time
          description: Creation timestamp
        updated_at:
          type: string
          format: date-time
          description: Last update timestamp
        published_at:
          type: string
          format: date-time
          description: Publication timestamp
          nullable: true
        custom_excerpt:
          type: string
          description: Custom excerpt
          nullable: true
        codeinjection_head:
          type: string
          description: Code injection in the page head
          nullable: true
        codeinjection_foot:
          type: string
          description: Code injection in the page foot
          nullable: true
        custom_template:
          type: string
          description: Custom Handlebars template name
          nullable: true
        canonical_url:
          type: string
          format: uri
          description: Canonical URL
          nullable: true
        url:
          type: string
          format: uri
          description: Full URL on the Ghost site
        excerpt:
          type: string
          description: Auto-generated excerpt
        reading_time:
          type: integer
          description: Estimated reading time in minutes
          minimum: 0
        email_subject:
          type: string
          description: Custom email newsletter subject
          nullable: true
        frontmatter:
          type: string
          description: Custom frontmatter
          nullable: true
        og_image:
          type: string
          format: uri
          nullable: true
          description: Open Graph image URL
        og_title:
          type: string
          nullable: true
          description: Open Graph title
        og_description:
          type: string
          nullable: true
          description: Open Graph description
        twitter_image:
          type: string
          format: uri
          nullable: true
          description: Twitter card image URL
        twitter_title:
          type: string
          nullable: true
          description: Twitter card title
        twitter_description:
          type: string
          nullable: true
          description: Twitter card description
        meta_title:
          type: string
          nullable: true
          descri

# --- truncated at 32 KB (37 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/ghost/refs/heads/main/openapi/ghost-posts-api-openapi.yml