How to Build a Custom GPT for Your Ghost Blog

Step-by-step guide to creating an AI-powered FAQ assistant for your Ghost blog

The 🤖 Rakihub GPT serves as an example of what we'll build.

Create a custom integration

Navigate to Ghost settings > Integrations, and create a custom integration. Copy the Content API key that you receive after setting it up.

Create a GPT

Next, navigate to ChatGPT My GPTs > Create a GPT, create a GPT.

Create a GPT

Configure the GPT

Give your GPT an appropriate name, description, and instructions. Here’s an example from Rakihub GPT :

Rakihub GPT

The instructions:

You are designed to answer questions based on blog posts from the RakiHub blog. You should retrieve and processes blog content to provide accurate and relevant information. You can summarize articles, give key takeaways, and answer specific questions related to topics covered in the blog.

You DO NOT: 
1. Don't answering questions that go beyond the scope of the blog content or involve making up information that isn’t found in the blog.
2. Avoid giving opinions or advice that is not backed by the content in the blog posts.

Set up actions

To connect the GPT with your Ghost blog posts, you'll need to set up an action.

Ghost GPT action
  • Authentication: set it to "none"
  • Schema: the OpenAPI schema for Ghost API, which tells how to query your Ghost blog public posts. Below is an example from Rakihub GPT . You can copy and replace the https://yoursitedomain with your Ghost blog domain, <content API key> with the content API key you get during the custom integration step.
  • Privacy policy: a link to the privacy policy informing the user what you, the creator of this product(the GPT), are doing with their data.
openapi: 3.1.0
info:
  title: Ghost Blog API
  description: Fetch posts from a Ghost blog with specified fields.
  version: 1.0.0
servers:
  - url: https://yoursitedomain
    description: Rakihub Ghost Blog Server
paths:
  /ghost/api/content/posts/?key=<content API key>&:
    get:
      operationId: getPosts
      summary: Retrieve blog posts with selected fields.
      parameters:
        - name: include
          in: query
          required: true
          description: Specific fields to retrieve for each post, separated by commas. Only "authors", "tags" are valid value for this field.
          schema:
            type: string
            default: authors,tags
          example: authors,tags
        - name: fields
          in: query
          required: true
          description: Specific fields to retrieve for each post, separated by commas.
          schema:
            type: string
            default: id,slug,title,excerpt,url,updated_at,visibility,plaintext
          example: id,slug,title,excerpt,url,updated_at,visibility,plaintext
        - name: limit
          in: query
          required: false
          description: Limit the number of posts returned.
          schema:
            type: integer
            default: 9999
          example: 100
        - name: page
          in: query
          required: false
          description: The page number to retrieve for paginated results.
          schema:
            type: integer
      responses:
        "200":
          description: A list of blog posts with pagination metadata.
          content:
            application/json:
              schema:
                type: object
                properties:
                  posts:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                          description: The unique identifier for the post.
                        slug:
                          type: string
                          description: The post slug (URL-friendly title).
                        title:
                          type: string
                          description: The title of the post.
                        updated_at:
                          type: string
                          format: date-time
                          description: The last time the post was updated.
                        visibility:
                          type: string
                          description: The visibility of the post (public or members).
                        plaintext:
                          type: string
                          description: The plain text content of the post (without HTML).
                  meta:
                    type: object
                    properties:
                      pagination:
                        type: object
                        properties:
                          page:
                            type: integer
                            description: The current page number.
                          limit:
                            type: integer
                            description: The limit for the number of posts per page.
                          pages:
                            type: integer
                            description: The total number of pages.
                          total:
                            type: integer
                            description: The total number of posts.
                          next:
                            type: integer
                            description: The next page number, if available.
                          prev:
                            type: integer
                            description: The previous page number, if available.
        "400":
          description: Bad Request - Invalid parameters.
        "401":
          description: Unauthorized - Invalid or missing API key.

Once all the configs are saved, your Ghost GPT will be ready!

📮Contact us at [email protected]