How to Integrate External APIs Like Pipedrive CRM with OpenAI Plugins

To integrate an external API like Pipedrive CRM with OpenAI plugins, create a self-contained plugin directory with a plugin.json manifest, an OpenAPI specification, a human-readable skill markdown file, and a lightweight runtime server that translates OpenAI-generated requests into authenticated Pipedrive REST calls.

The OpenAI plugins repository uses a declarative, file-based convention that lets any RESTful service be exposed to the model. Integrating an external API like Pipedrive CRM requires placing a manifest, schema, skill document, and optional server code in a dedicated folder under plugins/. This pattern is already used by existing integrations such as Twilio and Zoom, making it straightforward to adapt for new services.

Plugin Directory Structure and Key Files

Every integration in the openai/plugins repository is a self-contained directory. For Pipedrive CRM, the standard layout follows the same convention used by Twilio and Zoom:

This mirrors the structure found in existing plugins, such as plugins/twilio-developer-kit/.codex-plugin/plugin.json and plugins/zoom/skills/zoom-apps-sdk/SKILL.md.

Step 1: Create the Plugin Manifest

The plugin.json file tells the OpenAI runtime what the plugin does, which endpoints it exposes, and how authentication works. According to the repository schema used by existing plugins, the manifest includes fields for human- and model-readable names, an auth object, and an api block pointing to an OpenAPI spec.

{
  "schema_version": "v1",
  "name_for_human": "Pipedrive CRM",
  "name_for_model": "pipedrive",
  "description_for_human": "Access your Pipedrive deals, contacts, and activities.",
  "description_for_model": "Provides CRUD operations for Pipedrive objects (deals, persons, organizations).",
  "auth": {
    "type": "oauth",
    "client_id": "YOUR_CLIENT_ID",
    "authorization_url": "https://oauth.pipedrive.com/oauth/authorize",
    "token_url": "https://oauth.pipedrive.com/oauth/token",
    "scopes": ["deals:read", "persons:read"]
  },
  "api": {
    "type": "openapi",
    "url": "https://raw.githubusercontent.com/openai/plugins/main/plugins/pipedrive/openapi.yaml"
  },
  "logo_url": "https://github.com/openai/plugins/raw/main/plugins/pipedrive/assets/logo.png",
  "contact_email": "[email protected]",
  "legal_info_url": "https://example.com/legal"
}

Placing this file at plugins/pipedrive/.codex-plugin/plugin.json registers the plugin with the marketplace.

Step 2: Define the OpenAPI Specification

The OpenAI runtime relies on an OpenAPI document to understand request parameters, response schemas, and available operations. For Pipedrive CRM, plugins/pipedrive/openapi.yaml maps the Pipedrive REST API to a typed contract that the model can reason about.

openapi: 3.0.1
info:
  title: Pipedrive Plugin API
  version: v1
servers:
  - url: https://api.pipedrive.com/v1
paths:
  /deals:
    get:
      operationId: listDeals
      summary: List deals belonging to the authenticated user
      parameters:
        - name: limit
          in: query
          schema:
            type: integer
            default: 10
      responses:
        '200':
          description: A list of deals
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DealList'
components:
  schemas:
    Deal:
      type: object
      properties:
        id:
          type: integer
        title:
          type: string
        value:
          type: number
    DealList:
      type: array
      items:
        $ref: '#/components/schemas/Deal'

This specification lives at plugins/pipedrive/openapi.yaml and is referenced by the manifest URL.

Step 3: Implement the Runtime Server

A lightweight server receives the OpenAI-generated request and translates it into an authenticated call to Pipedrive. The repository contains many small server scripts—such as plugins/zotero/skills/zotero/scripts/zotero.py—that demonstrate this pattern. For Pipedrive, a FastAPI handler at plugins/pipedrive/server.py forwards requests using a Bearer token from OAuth.

from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import OAuth2AuthorizationCodeBearer
import httpx

app = FastAPI()
oauth2_scheme = OAuth2AuthorizationCodeBearer(
    authorizationUrl="https://oauth.pipedrive.com/oauth/authorize",
    tokenUrl="https://oauth.pipedrive.com/oauth/token"
)

BASE_URL = "https://api.pipedrive.com/v1"

async def pipedrive_client(token: str):
    async with httpx.AsyncClient(headers={"Authorization": f"Bearer {token}"}) as client:
        yield client

@app.get("/deals")
async def list_deals(limit: int = 10, token: str = Depends(oauth2_scheme)):
    async for client in pipedrive_client(token):
        resp = await client.get(f"{BASE_URL}/deals?limit={limit}")
        if resp.status_code != 200:
            raise HTTPException(status_code=resp.status_code, detail="Pipedrive error")
        return resp.json()

The list_deals function demonstrates how the runtime bridges the model's intent to the external API.

Step 4: Write the Skill Documentation

Skills are the primary documentation source for the plugin store and for model-side prompting. The file plugins/pipedrive/skills/pipedrive/SKILL.md should explain capabilities, request/response schemas, and usage examples. A well-structured reference can be found in plugins/zoom/skills/zoom-apps-sdk/SKILL.md.


# Pipedrive CRM Plugin

## Overview

This plugin lets the model retrieve and manage deals, contacts, and activities from your Pipedrive account.

## Endpoints

- **listDeals(limit)** – Returns up to `limit` deals.
- **getDeal(deal_id)** – Retrieves a single deal.
- **createDeal(title, value, ...)** – Creates a new deal.

## Example Prompt

> *“Show me the five most recent high‑value deals in my pipeline.”*

The model will call `listDeals(limit=5)` and then filter the response for deals where `value > 10000`.

## Authentication

When first used, the user will be guided through the Pipedrive OAuth flow defined in the manifest.

This markdown file allows both users and the model to understand how to interact with the integration.

Handle Authentication with OAuth

Most external APIs require OAuth 2.0 or an API token. The auth object inside plugin.json declares the flow, and the runtime surfaces it to the user. This pattern is already implemented by plugins such as Asana and Box in the openai/plugins repository. For Pipedrive, the manifest specifies type: oauth, the authorization endpoint, token endpoint, and required scopes. The FastAPI server then consumes the token via OAuth2AuthorizationCodeBearer to sign outbound requests to https://api.pipedrive.com/v1.

Test and Publish the Plugin

The repository ships integration tests for each plugin. Before publishing, add a test that mocks Pipedrive endpoints to verify end-to-end behavior. Once the manifest at plugins/pipedrive/.codex-plugin/plugin.json, the OpenAPI spec at plugins/pipedrive/openapi.yaml, the skill at plugins/pipedrive/skills/pipedrive/SKILL.md, and the server at plugins/pipedrive/server.py are in place, push the directory to the main branch. According to the openai/plugins source code, the marketplace automatically reads the manifest and renders the skill documentation.

Summary

  • Create a plugin directory under plugins/pipedrive/ following the self-contained pattern used by Twilio and Zoom.
  • Write plugin.json at plugins/pipedrive/.codex-plugin/plugin.json to declare metadata, OAuth, and the OpenAPI spec URL.
  • Define openapi.yaml to give the model a typed contract for Pipedrive endpoints such as /deals.
  • Build a lightweight server (e.g., FastAPI at plugins/pipedrive/server.py) to translate OpenAI requests into authenticated Pipedrive REST calls.
  • Document capabilities in plugins/pipedrive/skills/pipedrive/SKILL.md so the model and users understand available operations.
  • Test locally using the repository's integration test suite, then publish by merging to main.

Frequently Asked Questions

How does the OpenAI runtime know which endpoints a plugin exposes?

The runtime reads the api.url field inside plugins/pipedrive/.codex-plugin/plugin.json, which points to an OpenAPI specification. This spec defines the available paths, operation IDs, request parameters, and response schemas, allowing the model to reason about which functions to call.

What authentication methods are supported when integrating external APIs with OpenAI plugins?

The manifest supports OAuth 2.0 flows and API tokens through the auth object. As implemented in the openai/plugins repository, plugins such as Asana and Box already use these declarations, and the runtime surfaces the appropriate flow to the user before making authenticated requests.

Can I reuse existing server patterns from the repository for my Pipedrive integration?

Yes. The repository includes minimal server scripts such as plugins/zotero/skills/zotero/scripts/zotero.py that you can copy and adapt. For Pipedrive, a FastAPI server at plugins/pipedrive/server.py can forward incoming requests to https://api.pipedrive.com/v1 using the Bearer token provided by the OAuth scheme.

Where should skill documentation be placed so the marketplace can find it?

Place the human-readable skill file at plugins/pipedrive/skills/pipedrive/SKILL.md. According to the openai/plugins source code, this path follows the same convention as plugins/zoom/skills/zoom-apps-sdk/SKILL.md, and the marketplace renders this documentation alongside the plugin manifest.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →