ChatGPT plugins provide a new medium for developers to take advantage of OpenAI’s powerful GPT-4 model. plugins give ChatGPT access to tools via a REST API. When a plugin is installed in a user’s ChatGPT session, the model may decide to use the plugin as a part of it’s response.
You can develop plugins that enable ChatGPT to plan travel, go shopping, or do complex mathematics. In this tutorial, you’ll learn the basics of developing a ChatGPT plugin using Elixir and Phoenix.
This tutorial assumes you have Elixir and Phoenix installed. For information about how to create a plugin in other languages, see:
Create a new Phoenix project by running:
mix phx.new elixir_chatgpt_plugin --no-html --no-live --no-assetsThis example excludes front-end specific assets because ChatGPT plugins are API-only. You can omit these flags from the generation if you plan to have a frontend for your application. This will create a new Phoenix project.
By default, Phoenix ships with a Postgres database. This example won’t require the use of a database, but you should set it up before running your server to avoid errors:
mix ecto.setupYou can confirm your Phoenix application is setup properly by running iex -S mix phx.server and navigating to the /dev/dashboard:

Now you’re ready to create the plugin API!
ChatGPT interacts with plugins via a defined REST API. To start defining your REST API, create a new route in lib/elixir_plugin_web/router.ex inside the /api scope:
  scope "/api", ElixirChatgptPluginWeb do
    pipe_through :api
    get "/hello", ChatGPTController, :hello
  endThis will create a new route at /api/hello which dispatches to the ChatGPTController.hello/2 method. Next, create lib/elixir_plugin_web/controllers/chat_gpt_controller.ex and define a new controller:
defmodule ElixirChatgptPluginWeb.ChatGPTController do
  use ElixirChatgptPluginWeb, :controller
endNext, define the hello/2 method:
  def hello(conn, _params) do
    json(conn, %{"message": "Hello from the plugin!"})
  endThis will return a JSON response from the server with the message Hello from the plugin!. Your entire controller will look like this:
defmodule ElixirChatgptPluginWeb.ChatGPTController do
  use ElixirChatgptPluginWeb, :controller
  def hello(conn, _params) do
    json(conn, %{"message": "Hello from the plugin!"})
  end
endWith your API defined, you need to define an OpenAPI Spec. Phoenix doesn’t automatically generate OpenAPI specs, so you need to generate them yourself.
The OpenAPI Spec is how your ChatGPT plugin knows which endpoints are available to interact with. ChatGPT will use your OpenAPI spec to structure its requests and parse the responses from your plugin. For your Elixir plugin, create a new folder priv/static and add a new openapi.yaml file to the directory. Open up openapi.yaml and add the following:
openapi: 3.0.0
info:
  title: Elixir ChatGPT Plugin
  version: 1.0.0
servers:
  - url: http://localhost:4000/api
paths:
  /hello:
    get:
      summary: Say hello
      description: Says hello from the plugin
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
      operationId: sayHelloThis spec defines your single /hello endpoint which is available from the url http://localhost:4000/api/hello. Now you’re ready to define the ai-plugin.json for your Elixir plugin.
Every ChatGPT plugin must ship with a plugin manifest hosted on the same domain as the API. ChatGPT looks for the plugin specifically at the path /.well-known/ai-plugin.json. You can read more about the specifics of the plugin manifest in our What is the ChatGPT plugin manifest? post.
For your plugin, start by creating a new directory priv/static/.well-known. Next, create a new file in that directory called ai-plugin.json. Then, add the following to ai-plugin.json:
{
  "schema_version": "v1",
  "name_for_human": "My First plugin",
  "name_for_model": "elixir_plugin",
  "description_for_human": "My first ChatGPT plugin",
  "description_for_model": "plugin which says hello.",
  "auth": {
    "type": "none"
  },
  "api": {
    "type": "openapi",
    "url": "http://localhost:4000/openapi.yaml",
    "is_user_authenticated": false
  },
  "logo_url": "http://localhost:4000/logo.png",
  "contact_email": "support@example.com",
  "legal_info_url": "http://www.example.com/legal"
}In this example, the “auth” field is set to “none” because this plugin doesn’t require authentication. However, depending on your use case, you might need your plugin to handle authentication. For more information about how to implement authentication in a ChatGPT plugin, you can refer to our ChatGPT Plugin Authentication Guide.
Now you need to set your application up to serve the static openapi.yaml and .well-known/ai-plugin.json. You can do so by navigating to lib/elixir_chatgpt_plugin.ex and adding both to the static_paths/0 function:
  def static_paths, do: ~w(.well-known openapi.yaml assets fonts images favicon.ico robots.txt)And that’s all you need! You can verify it worked by starting your server and accessing both files from the browser.
In order to test your plugin locally before deploying to production, you need to configure your application to allow Cross-Origin Resource Sharing (CORS) from the ChatGPT website. CORS enables ChatGPT to request access to resources from your locally running webserver. To setup CORS with Elixir and Phoenix, you can use a CORS Plug. First, install the cors_plug package by adding it to your application’s dependencies:
  defp deps do
    [
      # ... other deps here ...
      {:plug_cowboy, "~> 2.5"},
      {:cors_plug, "~> 3.0"}
    ]
  endThen run mix deps.get to install your new dependencies. Finally, add the following line to lib/elixir_chatgpt_plugin_web/endpoint.ex:
  # CORS Config for local development
  plug CORSPlug,
    origin: ["http://localhost:4000", https://chat.openai.com"],
    methods: ["GET", "POST"],
    headers: ["*"]This will configure CORS correctly in your application for local development. Now you’re all set for testing!
First, start your plugin server locally by running:
iex -S mix phx.serverYou can verify it worked by navigating to http://localhost:4000/dev/dashboard in your browser:

Next, navigate to the ChatGPT UI and select the plugin model:

Then, you’ll want to select the plugins dropdown, navigate to the plugin store, and click “Develop your own plugin” in the bottom right:

Finally, type your localhost URL into the plugin form:

After awhile, you’ll see the following:

Click “Install localhost plugin” to continue. With your plugin enabled, you can start to interact with it using ChatGPT. For example, try typing in “Say hello from my plugin” into the chat window:

Congratulations! You’ve successfully made your first ChatGPT plugin with Elixir and Phoenix and confirmed it works locally. Next, check out our deployment and hosting guide to learn about deploying your plugin to production.
Get updates on new content, exclusive offers, and exclusive materials by subscribing to our newsletter.