openapi: 3.0.3 info: title: Ghost Content and Admin APIs description: >- Ghost is an open-source (MIT) publishing platform for professional publications, newsletters, memberships, and paid subscriptions. Every Ghost site - whether self-hosted or on managed Ghost(Pro) - exposes two documented public REST APIs under https://{admin_domain}/ghost/api/. The Content API is read-only and is authenticated with a Content API key passed as the `key` query parameter; it serves published posts, pages, authors, tags, tiers, and public settings for consumption by front-ends and static sites. The Admin API is read-write and is authenticated with an Admin API key that is used to sign a short-lived JWT sent as `Authorization: Ghost {token}` (a staff access token or user session may also be used). It manages posts, pages, members, tags, labels, tiers, offers, newsletters, users, images, themes, and webhooks. The `{admin_domain}` server variable is the site's domain (for Ghost(Pro), typically a `*.ghost.io` domain). All requests must use HTTPS. The `Accept-Version` header (for example `v5.0`) declares the minimum compatible API version. version: '5.0' contact: name: Ghost url: https://ghost.org license: name: MIT url: https://github.com/TryGhost/Ghost/blob/main/LICENSE servers: - url: https://{admin_domain}/ghost/api description: A Ghost site's API root (self-hosted or Ghost(Pro)) variables: admin_domain: default: demo.ghost.io description: The domain of the Ghost site (Ghost(Pro) uses *.ghost.io). security: - contentApiKey: [] - adminJwt: [] tags: - name: Content - Posts description: Read-only published posts. - name: Content - Pages description: Read-only published pages. - name: Content - Authors description: Read-only authors. - name: Content - Tags description: Read-only tags. - name: Content - Tiers description: Read-only public subscription tiers. - name: Content - Settings description: Read-only public site settings. - name: Admin - Posts description: Read-write posts. - name: Admin - Pages description: Read-write pages. - name: Admin - Members description: Read-write members. - name: Admin - Tags description: Read-write tags. - name: Admin - Labels description: Read-write member labels. - name: Admin - Tiers description: Read-write subscription tiers. - name: Admin - Offers description: Read-write promotional offers. - name: Admin - Newsletters description: Read-write newsletters. - name: Admin - Users description: Read-only staff users. - name: Admin - Site description: Read-only public site metadata. - name: Admin - Images description: Image uploads. - name: Admin - Themes description: Theme upload and activation. - name: Admin - Webhooks description: Outbound webhook management. paths: # ------------------------- CONTENT API ------------------------- /content/posts/: get: operationId: browseContentPosts tags: [Content - Posts] summary: Browse posts description: Returns a paginated list of published posts. parameters: - $ref: '#/components/parameters/ContentKey' - $ref: '#/components/parameters/Include' - $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 with pagination meta. '401': $ref: '#/components/responses/Unauthorized' /content/posts/{id}/: get: operationId: readContentPostById tags: [Content - Posts] summary: Read a post by ID parameters: - $ref: '#/components/parameters/ContentKey' - $ref: '#/components/parameters/PathId' - $ref: '#/components/parameters/Include' responses: '200': description: The requested post. '404': $ref: '#/components/responses/NotFound' /content/posts/slug/{slug}/: get: operationId: readContentPostBySlug tags: [Content - Posts] summary: Read a post by slug parameters: - $ref: '#/components/parameters/ContentKey' - $ref: '#/components/parameters/PathSlug' - $ref: '#/components/parameters/Include' responses: '200': description: The requested post. '404': $ref: '#/components/responses/NotFound' /content/pages/: get: operationId: browseContentPages tags: [Content - Pages] summary: Browse pages parameters: - $ref: '#/components/parameters/ContentKey' - $ref: '#/components/parameters/Filter' - $ref: '#/components/parameters/Limit' - $ref: '#/components/parameters/Page' responses: '200': description: A list of pages. /content/pages/{id}/: get: operationId: readContentPageById tags: [Content - Pages] summary: Read a page by ID parameters: - $ref: '#/components/parameters/ContentKey' - $ref: '#/components/parameters/PathId' responses: '200': description: The requested page. /content/pages/slug/{slug}/: get: operationId: readContentPageBySlug tags: [Content - Pages] summary: Read a page by slug parameters: - $ref: '#/components/parameters/ContentKey' - $ref: '#/components/parameters/PathSlug' responses: '200': description: The requested page. /content/authors/: get: operationId: browseContentAuthors tags: [Content - Authors] summary: Browse authors parameters: - $ref: '#/components/parameters/ContentKey' - $ref: '#/components/parameters/Include' - $ref: '#/components/parameters/Limit' - $ref: '#/components/parameters/Page' responses: '200': description: A list of authors. /content/authors/{id}/: get: operationId: readContentAuthorById tags: [Content - Authors] summary: Read an author by ID parameters: - $ref: '#/components/parameters/ContentKey' - $ref: '#/components/parameters/PathId' responses: '200': description: The requested author. /content/authors/slug/{slug}/: get: operationId: readContentAuthorBySlug tags: [Content - Authors] summary: Read an author by slug parameters: - $ref: '#/components/parameters/ContentKey' - $ref: '#/components/parameters/PathSlug' responses: '200': description: The requested author. /content/tags/: get: operationId: browseContentTags tags: [Content - Tags] summary: Browse tags parameters: - $ref: '#/components/parameters/ContentKey' - $ref: '#/components/parameters/Include' - $ref: '#/components/parameters/Limit' - $ref: '#/components/parameters/Page' responses: '200': description: A list of tags. /content/tags/{id}/: get: operationId: readContentTagById tags: [Content - Tags] summary: Read a tag by ID parameters: - $ref: '#/components/parameters/ContentKey' - $ref: '#/components/parameters/PathId' responses: '200': description: The requested tag. /content/tags/slug/{slug}/: get: operationId: readContentTagBySlug tags: [Content - Tags] summary: Read a tag by slug parameters: - $ref: '#/components/parameters/ContentKey' - $ref: '#/components/parameters/PathSlug' responses: '200': description: The requested tag. /content/tiers/: get: operationId: browseContentTiers tags: [Content - Tiers] summary: Browse public subscription tiers parameters: - $ref: '#/components/parameters/ContentKey' - $ref: '#/components/parameters/Include' - $ref: '#/components/parameters/Filter' responses: '200': description: A list of public tiers with pricing. /content/settings/: get: operationId: browseContentSettings tags: [Content - Settings] summary: Read public site settings parameters: - $ref: '#/components/parameters/ContentKey' responses: '200': description: Public settings for the site. # ------------------------- ADMIN API ------------------------- /admin/posts/: get: operationId: browseAdminPosts tags: [Admin - Posts] summary: Browse posts parameters: - $ref: '#/components/parameters/AcceptVersion' - $ref: '#/components/parameters/Include' - $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. '401': $ref: '#/components/responses/Unauthorized' post: operationId: addAdminPost tags: [Admin - Posts] summary: Create a post parameters: - $ref: '#/components/parameters/AcceptVersion' - $ref: '#/components/parameters/Source' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/PostsRequest' responses: '201': description: The created post. /admin/posts/{id}/: get: operationId: readAdminPostById tags: [Admin - Posts] summary: Read a post by ID parameters: - $ref: '#/components/parameters/AcceptVersion' - $ref: '#/components/parameters/PathId' - $ref: '#/components/parameters/Formats' responses: '200': description: The requested post. put: operationId: editAdminPost tags: [Admin - Posts] summary: Update a post description: >- Updates a post. The current updated_at value must be supplied in the payload for collision detection. parameters: - $ref: '#/components/parameters/AcceptVersion' - $ref: '#/components/parameters/PathId' - $ref: '#/components/parameters/Source' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/PostsRequest' responses: '200': description: The updated post. delete: operationId: deleteAdminPost tags: [Admin - Posts] summary: Delete a post parameters: - $ref: '#/components/parameters/AcceptVersion' - $ref: '#/components/parameters/PathId' responses: '204': description: The post was deleted. /admin/posts/slug/{slug}/: get: operationId: readAdminPostBySlug tags: [Admin - Posts] summary: Read a post by slug parameters: - $ref: '#/components/parameters/AcceptVersion' - $ref: '#/components/parameters/PathSlug' responses: '200': description: The requested post. /admin/pages/: get: operationId: browseAdminPages tags: [Admin - Pages] summary: Browse pages parameters: - $ref: '#/components/parameters/AcceptVersion' - $ref: '#/components/parameters/Filter' - $ref: '#/components/parameters/Limit' - $ref: '#/components/parameters/Page' responses: '200': description: A list of pages. post: operationId: addAdminPage tags: [Admin - Pages] summary: Create a page parameters: - $ref: '#/components/parameters/AcceptVersion' - $ref: '#/components/parameters/Source' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/PagesRequest' responses: '201': description: The created page. /admin/pages/{id}/: get: operationId: readAdminPageById tags: [Admin - Pages] summary: Read a page by ID parameters: - $ref: '#/components/parameters/AcceptVersion' - $ref: '#/components/parameters/PathId' responses: '200': description: The requested page. put: operationId: editAdminPage tags: [Admin - Pages] summary: Update a page parameters: - $ref: '#/components/parameters/AcceptVersion' - $ref: '#/components/parameters/PathId' - $ref: '#/components/parameters/Source' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/PagesRequest' responses: '200': description: The updated page. delete: operationId: deleteAdminPage tags: [Admin - Pages] summary: Delete a page parameters: - $ref: '#/components/parameters/AcceptVersion' - $ref: '#/components/parameters/PathId' responses: '204': description: The page was deleted. /admin/members/: get: operationId: browseAdminMembers tags: [Admin - Members] summary: Browse members parameters: - $ref: '#/components/parameters/AcceptVersion' - $ref: '#/components/parameters/Include' - $ref: '#/components/parameters/Filter' - $ref: '#/components/parameters/Limit' - $ref: '#/components/parameters/Page' responses: '200': description: A list of members. post: operationId: addAdminMember tags: [Admin - Members] summary: Create a member parameters: - $ref: '#/components/parameters/AcceptVersion' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/MembersRequest' responses: '201': description: The created member. /admin/members/{id}/: get: operationId: readAdminMemberById tags: [Admin - Members] summary: Read a member by ID parameters: - $ref: '#/components/parameters/AcceptVersion' - $ref: '#/components/parameters/PathId' responses: '200': description: The requested member. put: operationId: editAdminMember tags: [Admin - Members] summary: Update a member parameters: - $ref: '#/components/parameters/AcceptVersion' - $ref: '#/components/parameters/PathId' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/MembersRequest' responses: '200': description: The updated member. /admin/tags/: get: operationId: browseAdminTags tags: [Admin - Tags] summary: Browse tags parameters: - $ref: '#/components/parameters/AcceptVersion' - $ref: '#/components/parameters/Limit' - $ref: '#/components/parameters/Page' responses: '200': description: A list of tags. post: operationId: addAdminTag tags: [Admin - Tags] summary: Create a tag parameters: - $ref: '#/components/parameters/AcceptVersion' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TagsRequest' responses: '201': description: The created tag. /admin/tags/{id}/: put: operationId: editAdminTag tags: [Admin - Tags] summary: Update a tag parameters: - $ref: '#/components/parameters/AcceptVersion' - $ref: '#/components/parameters/PathId' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TagsRequest' responses: '200': description: The updated tag. delete: operationId: deleteAdminTag tags: [Admin - Tags] summary: Delete a tag parameters: - $ref: '#/components/parameters/AcceptVersion' - $ref: '#/components/parameters/PathId' responses: '204': description: The tag was deleted. /admin/labels/: get: operationId: browseAdminLabels tags: [Admin - Labels] summary: Browse member labels parameters: - $ref: '#/components/parameters/AcceptVersion' responses: '200': description: A list of labels. post: operationId: addAdminLabel tags: [Admin - Labels] summary: Create a label parameters: - $ref: '#/components/parameters/AcceptVersion' requestBody: required: true content: application/json: schema: type: object responses: '201': description: The created label. /admin/labels/{id}/: put: operationId: editAdminLabel tags: [Admin - Labels] summary: Update a label parameters: - $ref: '#/components/parameters/AcceptVersion' - $ref: '#/components/parameters/PathId' requestBody: required: true content: application/json: schema: type: object responses: '200': description: The updated label. delete: operationId: deleteAdminLabel tags: [Admin - Labels] summary: Delete a label parameters: - $ref: '#/components/parameters/AcceptVersion' - $ref: '#/components/parameters/PathId' responses: '204': description: The label was deleted. /admin/tiers/: get: operationId: browseAdminTiers tags: [Admin - Tiers] summary: Browse tiers parameters: - $ref: '#/components/parameters/AcceptVersion' - $ref: '#/components/parameters/Include' responses: '200': description: A list of tiers. post: operationId: addAdminTier tags: [Admin - Tiers] summary: Create a tier parameters: - $ref: '#/components/parameters/AcceptVersion' requestBody: required: true content: application/json: schema: type: object responses: '201': description: The created tier. /admin/tiers/{id}/: put: operationId: editAdminTier tags: [Admin - Tiers] summary: Update a tier parameters: - $ref: '#/components/parameters/AcceptVersion' - $ref: '#/components/parameters/PathId' requestBody: required: true content: application/json: schema: type: object responses: '200': description: The updated tier. /admin/offers/: get: operationId: browseAdminOffers tags: [Admin - Offers] summary: Browse offers parameters: - $ref: '#/components/parameters/AcceptVersion' responses: '200': description: A list of offers. post: operationId: addAdminOffer tags: [Admin - Offers] summary: Create an offer parameters: - $ref: '#/components/parameters/AcceptVersion' requestBody: required: true content: application/json: schema: type: object responses: '201': description: The created offer. /admin/offers/{id}/: put: operationId: editAdminOffer tags: [Admin - Offers] summary: Update an offer parameters: - $ref: '#/components/parameters/AcceptVersion' - $ref: '#/components/parameters/PathId' requestBody: required: true content: application/json: schema: type: object responses: '200': description: The updated offer. /admin/newsletters/: get: operationId: browseAdminNewsletters tags: [Admin - Newsletters] summary: Browse newsletters parameters: - $ref: '#/components/parameters/AcceptVersion' responses: '200': description: A list of newsletters. post: operationId: addAdminNewsletter tags: [Admin - Newsletters] summary: Create a newsletter parameters: - $ref: '#/components/parameters/AcceptVersion' requestBody: required: true content: application/json: schema: type: object responses: '201': description: The created newsletter. /admin/newsletters/{id}/: put: operationId: editAdminNewsletter tags: [Admin - Newsletters] summary: Update a newsletter parameters: - $ref: '#/components/parameters/AcceptVersion' - $ref: '#/components/parameters/PathId' requestBody: required: true content: application/json: schema: type: object responses: '200': description: The updated newsletter. /admin/users/: get: operationId: browseAdminUsers tags: [Admin - Users] summary: Browse staff users parameters: - $ref: '#/components/parameters/AcceptVersion' - $ref: '#/components/parameters/Include' responses: '200': description: A list of staff users. /admin/users/{id}/: get: operationId: readAdminUserById tags: [Admin - Users] summary: Read a staff user by ID parameters: - $ref: '#/components/parameters/AcceptVersion' - $ref: '#/components/parameters/PathId' responses: '200': description: The requested user. /admin/users/slug/{slug}/: get: operationId: readAdminUserBySlug tags: [Admin - Users] summary: Read a staff user by slug parameters: - $ref: '#/components/parameters/AcceptVersion' - $ref: '#/components/parameters/PathSlug' responses: '200': description: The requested user. /admin/site/: get: operationId: readAdminSite tags: [Admin - Site] summary: Read public site metadata description: Returns basic public site data including title, url, and version. parameters: - $ref: '#/components/parameters/AcceptVersion' responses: '200': description: The site metadata. /admin/images/upload/: post: operationId: uploadAdminImage tags: [Admin - Images] summary: Upload an image description: >- Uploads an image using multipart/form-data and returns the stored URL for referencing the image in post or page content. parameters: - $ref: '#/components/parameters/AcceptVersion' requestBody: required: true content: multipart/form-data: schema: type: object properties: file: type: string format: binary purpose: type: string enum: [image, profile_image, icon] ref: type: string responses: '201': description: The uploaded image URL. /admin/themes/upload/: post: operationId: uploadAdminTheme tags: [Admin - Themes] summary: Upload a theme description: Uploads a theme as a zip package using multipart/form-data. parameters: - $ref: '#/components/parameters/AcceptVersion' requestBody: required: true content: multipart/form-data: schema: type: object properties: file: type: string format: binary responses: '201': description: The uploaded theme. /admin/themes/{name}/activate/: put: operationId: activateAdminTheme tags: [Admin - Themes] summary: Activate a theme parameters: - $ref: '#/components/parameters/AcceptVersion' - name: name in: path required: true schema: type: string responses: '200': description: The activated theme. /admin/webhooks/: post: operationId: addAdminWebhook tags: [Admin - Webhooks] summary: Create a webhook description: >- Registers an outbound webhook that fires on a Ghost event (for example post.published, member.added). There is no endpoint to read existing webhooks. parameters: - $ref: '#/components/parameters/AcceptVersion' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/WebhooksRequest' responses: '201': description: The created webhook. /admin/webhooks/{id}/: put: operationId: editAdminWebhook tags: [Admin - Webhooks] summary: Update a webhook parameters: - $ref: '#/components/parameters/AcceptVersion' - $ref: '#/components/parameters/PathId' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/WebhooksRequest' responses: '200': description: The updated webhook. delete: operationId: deleteAdminWebhook tags: [Admin - Webhooks] summary: Delete a webhook parameters: - $ref: '#/components/parameters/AcceptVersion' - $ref: '#/components/parameters/PathId' responses: '204': description: The webhook was deleted. components: securitySchemes: contentApiKey: type: apiKey in: query name: key description: >- Content API key from a Custom Integration, passed as the `key` query parameter. Safe for browser use; grants read-only access to public data. adminJwt: type: http scheme: bearer bearerFormat: JWT description: >- Admin API access. An Admin API key (id:secret) is used to sign a short-lived JWT sent as `Authorization: Ghost {token}`. A staff access token or an authenticated user session may also be used. parameters: ContentKey: name: key in: query required: true description: Content API key. schema: type: string AcceptVersion: name: Accept-Version in: header required: false description: Minimum compatible API version, for example v5.0. schema: type: string example: v5.0 PathId: name: id in: path required: true description: The resource ID. schema: type: string PathSlug: name: slug in: path required: true description: The resource slug. schema: type: string Include: name: include in: query required: false description: Comma-separated related data to include (for example authors,tags). schema: type: string Fields: name: fields in: query required: false description: Comma-separated list of fields to return. schema: type: string Filter: name: filter in: query required: false description: Ghost NQL filter expression. schema: type: string Limit: name: limit in: query required: false description: Number of records per page (default 15, or 'all'). schema: type: string default: '15' Page: name: page in: query required: false description: Page number of results to return. schema: type: integer default: 1 Order: name: order in: query required: false description: Sort order, for example 'published_at desc'. schema: type: string Formats: name: formats in: query required: false description: Content formats to return, for example 'html,lexical'. schema: type: string Source: name: source in: query required: false description: Set to 'html' to supply post/page content as HTML instead of Lexical. schema: type: string enum: [html] responses: Unauthorized: description: Authentication failed or was missing. NotFound: description: The requested resource was not found. schemas: PostsRequest: type: object properties: posts: type: array items: type: object properties: title: type: string lexical: type: string html: type: string status: type: string enum: [draft, published, scheduled] updated_at: type: string format: date-time PagesRequest: type: object properties: pages: type: array items: type: object MembersRequest: type: object properties: members: type: array items: type: object properties: email: type: string name: type: string note: type: string TagsRequest: type: object properties: tags: type: array items: type: object properties: name: type: string slug: type: string description: type: string WebhooksRequest: type: object properties: webhooks: type: array items: type: object properties: event: type: string example: post.published target_url: type: string format: uri name: type: string secret: type: string