Creating GPT Actions Skip to main content

Creating GPT Actions

Learn how to integrate the functionality of 3rd party services into your custom GPTs.

Caution
This is a rather advanced topic that requires some technical knowledge. Continue reading to learn how GPT Actions work, especially the bottom section if you are not technical and would like support adding actions to your GPT.

Paid ChatGPT plans enable users to create custom GPTs. If you are reading this, you most likely have interacted with them already. If you are not familiar with custom GPT's, read this article: Introduction to Custom GPTs.

Custom GPTs introduced Actions, which allow users to leverage the power of 3rd party APIs to augment the functionality of GPTs, allowing users to interact with these APIs using natural language. With GPT Actions, GPTs can access real-time information, and also dynamically expand their knowledge base depending on user needs without having to front-load unnecessary information, even including access to data that is not accessible by the web.

Here are only a few examples of services that one could connect their GPT to using GPT Actions:

  • Canvas
  • Microsoft Teams
  • Gmail/Outlook
  • Calendar Apps
  • Sharepoint
  • SmartSheet/Trello/Asana

The GPT will analyze the prompt, identify if an API call is necessary for the response, choose the right endpoint call (in case there are multiple endpoints made available to the GPT), and use the API payload to prepare a response. Take the diagram below as a general reference.

Technically, GPT actions allow GPTs to perform CRUD-like operations on a service using their API. The ability for the GPT to perform these operations will depend on:

a) The requirements for the service that you wish to interact with.
b) The GPT configuration.
c) The user's prompt engineering expertise.

This article will explain how to implement read requests (GET) using GPT actions.

Additionally to the instructions that you create for a normal custom GPT, a GPT with actions needs these additional components:

  • Authentication (optional)
  • OpenAPI Specification

To learn how to create, read, and modify OpenAPI schemas, visit this accompanying article: Creating OpenAPI Schemas for Custom GPTs.

We will build 3 custom GPTs to illustrate how these components work: a Weather GPT, a Currency Exchange GPT, and a Calendar Assistant GPT.

Note
If you are using an enterprise-managed license of ChatGPT, you might need an admin to enable GPT Actions and/or to add the domain of the service you are interested in to an approved list.
For users under the CES ChatGPT Edu organization, please contact ai-committee@byu.edu for help.

GPT 1: Weather Search
GPT 2: Currency Chatbot
GPT 3: Calendar Assistant

We will create a Weather Search GPT that communicates with open-meteo.com via API to get a location's current weather.

Step 1: Create GPT and add instructions

  • On the left-hand navigation bar, click on "Explore GPTs".
  • Click on "+ Create" at the top-right corner of the screen.
  • Jump to the Configure tab of the GPT editor, and give your GPT a name and a description.

In the instructions, we will write the following:

Tip
Make your Instructions as detailed as you wish! Sometimes, an API will want a specific pattern when defining their parameter formats. You might also want the GPT to respond with or without emojis, in a specific language, or in table format. The more detailed you are, the more consistent your GPT responses will become.

You provide the latest weather information for a location.
When the user asks for the weather in a particular location, get the coordinates (latitude, longitude) for that location, and call the open-meteo endpoint. Unless indicated otherwise, the temperature_unit will be fahrenheit.
If multiple locations are requested by the user, pass all the latitudes together separated by a comma, as well as the longitudes, in the same order.
Example:
- 	user: What is the weather in BYU Hawaii?
	GPT: latitude=21.6413&longitude=157.9251
- 	user: What is the weather in Salt Lake City, UT and in Bremen, Germany?
	GPT: latitude=40.7608,53.0793&longitude=111.8910,8.8017

Scroll to the bottom of the Configure tab and de-select all capabilities.

Tip
Make sure to de-select all Capabilities, or at least Web Search!
The purpose of GPT Actions is to help the GPT extend its knowledge base and direct it to a source of knowledge (the API server) for what it does not know. If Web Search is enabled, the GPT might default to a web search instead of calling the API through the GPT Action.

Step 2: Create action

Under "Actions" at the bottom of the Configure tab, click on "Create new action".

The API that we are using for this example does not require authentication so we will skip the "Authentication" section.

On the "Schema" section, we will paste the schema below. For detailed instructions on the OpenAPI schema, how to create it, and helpful tips, click here: Creating OpenAPI Schemas for Custom GPTs

openapi: 3.1.0
info:
  title: Open-Meteo Weather Forecast API
  description: |
    Open-Meteo provides free weather forecast APIs for specific latitude and longitude coordinates. 
    This specification covers the forecast endpoint. More endpoints can be added as needed.
  version: 1.0.0
servers:
  - url: https://api.open-meteo.com/v1
    description: Main Open-Meteo API server
paths:
  /forecast:
    get:
      operationId: getWeatherForecast
      summary: Get weather forecast for a specific location
      description: |
        Retrieves weather forecast data for the given latitude and longitude.
        Optional parameters include hourly, daily, current weather, and more.
      parameters:
        - name: latitude
          in: query
          required: true
          description: Latitude of the location
          schema:
            type: number
            format: float
        - name: longitude
          in: query
          required: true
          description: Longitude of the location
          schema:
            type: number
            format: float
        - name: hourly
          in: query
          required: false
          description: Comma-separated list of hourly variables (e.g., temperature_2m, relative_humidity_2m)
          schema:
            type: string
        - name: daily
          in: query
          required: false
          description: Comma-separated list of daily variables (e.g., temperature_2m_max, precipitation_sum)
          schema:
            type: string
        - name: current_weather
          in: query
          required: false
          description: Include current weather data (true or false)
          schema:
            type: boolean
        - name: timezone
          in: query
          required: false
          description: Timezone for the response (e.g., Europe/Berlin or auto)
          schema:
            type: string
        - name: start_date
          in: query
          required: false
          description: Start date for forecast in YYYY-MM-DD format
          schema:
            type: string
            format: date
        - name: end_date
          in: query
          required: false
          description: End date for forecast in YYYY-MM-DD format
          schema:
            type: string
            format: date
      responses:
        '200':
          description: Successful weather forecast response
          content:
            application/json:
              schema:
                type: object
                properties:
                  latitude:
                    type: number
                  longitude:
                    type: number
                  generationtime_ms:
                    type: number
                  utc_offset_seconds:
                    type: integer
                  timezone:
                    type: string
                  timezone_abbreviation:
                    type: string
                  elevation:
                    type: number
                  current_weather:
                    type: object
                    nullable: true
                    properties:
                      temperature:
                        type: number
                      windspeed:
                        type: number
                      winddirection:
                        type: number
                      weathercode:
                        type: integer
                      time:
                        type: string
                  hourly:
                    type: object
                    nullable: true
                  daily:
                    type: object
                    nullable: true
        '400':
          description: Invalid request parameters
        '500':
          description: Internal server error

If the spec is formatted correctly, you will see the getWeatherForecast action listed under "Available actions" (it might have a different name, depending on the name passed to the operationId in the schema).

Note
While this API service has many more parameterization options, we are only using a few for this demonstration. As you build GPT Actions, determining how many and which parameters and endpoints to include will depend on the use cases for your indented users.

Step 3: Test and refine

Test the GPT by sending a prompt to the GPT in the Preview view of the GPT. Testing in the Preview view allows you to see which parameters the GPT use in the API call. Expanding the debug drop-downs will reveal how the GPT is using the Schema and the Instructions provided.

If everything looks correct, click on "Allow". If the parameters do not look right, you can decline the operation and return to either the instructions or the Schema configuration to make adjustments.

If the GPT was able to get data from the API call, it will use the result to prepare its response. If it did not get any data back, it will indicate so too. In either case, go through a number of cases and evaluate how the GPT responds.

Feel free to modify the Instructions on the Configure view to tell the GPT how it should structure its responses, and any additional rules you want it to follow.

Step 4: Finalize and publish

When you are satisfied with the configuration of the GPT, return to the Configure view of the GPT and under the section "Conversation Starters", add a couple of sample prompts to inform users how they can interact with it. Also upload an image or generate one for your custom GPT.

Finally, click on "Create" at the top right corner. You may choose to enable this GPT for yourself only, to publish it for everyone, or to share it with select users.

For users under the CES ChatGPT Edu organization, test it here: https://chatgpt.com/g/g-67e2e5ab60148191889085549f79bb36-weather-gpt

We will create a Currency Exchange Chatbot that provides the buy and sell prices for different currencies, and also checks the exchange rates between them, using the Coinbase API.

Step 1: Create GPT and add Instructions

Create GPT and name it appropriately..
In the Instructions section, include the following:

You are a chatbot that provides information such as BUY and SELL prices for different currencies, as well as Exchange Rates between them.

When a user asks about the price or exchange rate of a currency, call the appropriate endpoint to get the corresponding information.

Use the the ISO 4217 standard to prepare currency codes.

Example: "what is the cost of one bitcoin in dollars?"

Currency code: "BTC-USD"

Example: "how many dollars will I receive for one euro?"

Currency code: "EUR-USD"

Example: "how much is one ether currently?"

Currency code: "ETH"

In the "Capabilities" section, de-select all but "Code Interpreter & Data Analysis". With Code Interpreter enabled, you will be able to ask your GPT to use the information provided with the Coinbase actions and create different types of analyses using Python.

Step 2: Create action

Paste the following OpenAPI Schema:

openapi: 3.1.0
info:
  title: Coinbase API
  description: API for retrieving exchange rates and cryptocurrency prices from Coinbase.
  version: 1.0.0
servers:
  - url: https://api.coinbase.com/v2
    description: Coinbase API server

paths:
  /exchange-rates:
    get:
      operationId: getExchangeRates
      summary: Get exchange rates
      description: Retrieve exchange rates for a specified cryptocurrency.
      parameters:
        - name: currency
          in: query
          required: true
          description: The base currency (e.g., BTC, ETH).
          schema:
            type: string
      responses:
        '200':
          description: Exchange rates data
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      currency:
                        type: string
                      rates:
                        type: object
                        additionalProperties:
                          type: string
        '400':
          description: Bad request (invalid currency)
        '500':
          description: Internal server error

  /prices/{currency_pair}/buy:
    get:
      operationId: getBuyPrice
      summary: Get buy price
      description: Retrieve the buy price for a specific currency pair.
      parameters:
        - name: currency_pair
          in: path
          required: true
          description: Currency pair (e.g., BTC-USD).
          schema:
            type: string
      responses:
        '200':
          description: Buy price data
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      base:
                        type: string
                      currency:
                        type: string
                      amount:
                        type: string
        '400':
          description: Bad request (invalid currency pair)
        '500':
          description: Internal server error

  /prices/{currency_pair}/sell:
    get:
      operationId: getSellPrice
      summary: Get sell price
      description: Retrieve the sell price for a specific currency pair.
      parameters:
        - name: currency_pair
          in: path
          required: true
          description: Currency pair (e.g., BTC-USD).
          schema:
            type: string
      responses:
        '200':
          description: Sell price data
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      base:
                        type: string
                      currency:
                        type: string
                      amount:
                        type: string
        '400':
          description: Bad request (invalid currency pair)
        '500':
          description: Internal server error

If the spec is created correctly, you will see three actions listed under "Available actions".

Steps 3-4: Refer to the Weather Search GPT example

For users with a CES ChatGPT Edu license, check out this GPT here: https://chatgpt.com/g/g-67e1aa70769c81918261a99ac87b8a2e-currency-exchange-gpt

We will now create a Calendar Assistant GPT which will connect to our Google calendars, get information about events, and even create new ones for us.

This GPT is different from the previous examples in an important aspect: it requires authentication and authorization, which, in simple terms, is allowing the GPT to sign in to an account on our behalf and perform some operations for us.

Note
There are two main ways to implement authentication in custom GPTs: API keys and OAuth. For GPTs that should provide customized responses based on who the user is, you should use OAuth (personal calendar, email inbox, etc.). Users will be redirected to the service login page and will need to sign-in to the service before using the custom GPT. For GPTs that are meant to provide access to a shared resource without needing to sign in, use API keys. The information that any user gets from the custom GPT will be the same.
Tip
While going through the steps to create this GPT is not that different from the others, including authorization into the GPT adds more complexity into the project. Each service introduces different ways to enable authorization so we will not delve into the process of enabling authorization for Google Calendar, but we will link a tutorial to do that and go from there.

This tutorial is in a big part pulling information from the GPT Actions Library in the OpenAI Cookbook: GPT Actions library - Google Calendar

Prerequisites: Enable the Google Calendar API

Before creating the GPT that connects to Google Calendar, you will need to enable the API for it. Visit the Google Calendar tutorial in the GPT Actions library and follow the instructions under "Google Calendar Configuration Steps". Here is the direct link: GPT Actions library - Google Calendar Configuration Steps.

Note
The tutorial for Google Calendar Configuration Steps mentions a "Go To New Experience" option. This option is now called "OAuth consent screen"

Step 1: Create GPT

Create a GPT and give it a name. In my case, I will call it "Google Calendar Assistant GPT".

For this GPT, we will not include instructions. If you want to define a specific behavior or response pattern, you may do it.

Step 2: Create Action

Click on "Create new action" at the bottom of the Configure view.

Click on the gear icon under "Authentication" and select "OAuth".

From the Google Cloud Console, enter the Client ID and the Client Secret in the corresponding places.

Enter the following details:

  • Authorization URL: https://accounts.google.com/o/oauth2/auth
  • Token URL: https://oauth2.googleapis.com/token
  • Scopes: https://www.googleapis.com/auth/calendar

Leave the default Token Exchange Method.

Save.

Generate the OpenAPI schema for your action and paste it in the Schema box.

openapi: 3.1.0
info:
  title: Google Calendar API
  description: This API allows you to read and create events in a user's Google Calendar.
  version: 1.0.0
servers:
  - url: https://www.googleapis.com/calendar/v3
    description: Google Calendar API server
 
paths:
  /calendars/primary/events:
    get:
      summary: List events from the primary calendar
      description: Retrieve a list of events from the user's primary Google Calendar.
      operationId: listEvents
      tags:
        - Calendar
      parameters:
        - name: timeMin
          in: query
          description: The lower bound (inclusive) of the events to retrieve, in RFC3339 format.
          required: false
          schema:
            type: string
            format: date-time
            example: "2024-11-01T00:00:00Z"
        - name: timeMax
          in: query
          description: The upper bound (exclusive) of the events to retrieve, in RFC3339 format.
          required: false
          schema:
            type: string
            format: date-time
            example: "2024-12-01T00:00:00Z"
        - name: maxResults
          in: query
          description: The maximum number of events to return.
          required: false
          schema:
            type: integer
            default: 10
        - name: singleEvents
          in: query
          description: Whether to expand recurring events into instances. Defaults to `false`.
          required: false
          schema:
            type: boolean
            default: true
        - name: orderBy
          in: query
          description: The order of events. Can be "startTime" or "updated".
          required: false
          schema:
            type: string
            enum:
              - startTime
              - updated
            default: startTime
      responses:
        '200':
          description: A list of events
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                          description: The event ID
                        summary:
                          type: string
                          description: The event summary (title)
                        start:
                          type: object
                          properties:
                            dateTime:
                              type: string
                              format: date-time
                              description: The start time of the event
                            date:
                              type: string
                              format: date
                              description: The start date of the all-day event
                        end:
                          type: object
                          properties:
                            dateTime:
                              type: string
                              format: date-time
                              description: The end time of the event
                            date:
                              type: string
                              format: date
                              description: The end date of the all-day event
                        location:
                          type: string
                          description: The location of the event
                        description:
                          type: string
                          description: A description of the event
        '401':
          description: Unauthorized access due to missing or invalid OAuth token
        '400':
          description: Bad request, invalid parameters
 
    post:
      summary: Create a new event on the primary calendar
      description: Creates a new event on the user's primary Google Calendar.
      operationId: createEvent
      tags:
        - Calendar
      requestBody:
        description: The event data to create.
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                summary:
                  type: string
                  description: The title of the event
                  example: "Team Meeting"
                location:
                  type: string
                  description: The location of the event
                  example: "Conference Room 1"
                description:
                  type: string
                  description: A detailed description of the event
                  example: "Discuss quarterly results"
                start:
                  type: object
                  properties:
                    dateTime:
                      type: string
                      format: date-time
                      description: Start time of the event
                      example: "2024-11-30T09:00:00Z"
                    timeZone:
                      type: string
                      description: Time zone of the event start
                      example: "UTC"
                end:
                  type: object
                  properties:
                    dateTime:
                      type: string
                      format: date-time
                      description: End time of the event
                      example: "2024-11-30T10:00:00Z"
                    timeZone:
                      type: string
                      description: Time zone of the event end
                      example: "UTC"
                attendees:
                  type: array
                  items:
                    type: object
                    properties:
                      email:
                        type: string
                        description: The email address of an attendee
                        example: "attendee@example.com"
              required:
                - summary
                - start
                - end
      responses:
        '201':
          description: Event created successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                    description: The ID of the created event
                  summary:
                    type: string
                    description: The event summary (title)
                  start:
                    type: object
                    properties:
                      dateTime:
                        type: string
                        format: date-time
                        description: The start time of the event
                  end:
                    type: object
                    properties:
                      dateTime:
                        type: string
                        format: date-time
                        description: The end time of the event
        '400':
          description: Bad request, invalid event data
        '401':
          description: Unauthorized access due to missing or invalid OAuth token
        '500':
          description: Internal server error

If the schema is correct, you will see listEvents and createEvent actions under "Available Actions".

Step 3: Return to the OpenAI Cookbook and complete the section "Setting Callback URL"

Step 4: Finalize (refer to steps 3-4 from Weather GPT example)

View a conversation that I had with my Calendar Assistant GPT: Calendar Assistant GPT Conversation

Get Help Creating GPTs with Actions

There are many more ways to create and configure GPT Actions. If you are interested in creating one but do not know where to start, please contact the BYU AI Committee at ai-committee@byu.edu.