{
  "openapi": "3.1.0",
  "info": {
    "title": "GPT Researcher API",
    "version": "0.14.8",
    "summary": "Autonomous deep-research agent API.",
    "description": "GPT Researcher is an open-source autonomous AI research agent. This OpenAPI specification documents the REST surface exposed by the GPT Researcher self-hosted FastAPI server (https://github.com/assafelovic/gpt-researcher) and the gptr-mcp Model Context Protocol server (https://github.com/assafelovic/gptr-mcp). Endpoints describe the canonical request/response shapes used by the open-source server. Run the server locally to issue real requests; gptr.dev itself is a marketing landing page and does not host a public API endpoint.",
    "contact": {
      "name": "GPT Researcher",
      "url": "https://gptr.dev",
      "email": "hello@gptr.dev"
    },
    "license": {
      "name": "MIT",
      "url": "https://github.com/assafelovic/gpt-researcher/blob/master/LICENSE"
    }
  },
  "servers": [
    {
      "url": "http://localhost:8000",
      "description": "Local self-hosted GPT Researcher FastAPI server"
    },
    {
      "url": "http://localhost:8000/mcp",
      "description": "Local gptr-mcp Streamable HTTP transport"
    }
  ],
  "externalDocs": {
    "description": "Full GPT Researcher documentation",
    "url": "https://docs.gptr.dev"
  },
  "tags": [
    { "name": "research", "description": "Autonomous deep-research operations." },
    { "name": "search", "description": "Fast snippet-level web search." },
    { "name": "report", "description": "Report generation from accumulated research context." },
    { "name": "sources", "description": "Inspecting sources gathered during research." },
    { "name": "system", "description": "Health and metadata." }
  ],
  "paths": {
    "/health": {
      "get": {
        "tags": ["system"],
        "operationId": "getHealth",
        "summary": "Server health check",
        "description": "Returns basic liveness information for the GPT Researcher server.",
        "responses": {
          "200": {
            "description": "Server is healthy.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/HealthResponse" }
              }
            }
          }
        }
      }
    },
    "/research": {
      "post": {
        "tags": ["research"],
        "operationId": "createResearch",
        "summary": "Run a deep-research task",
        "description": "Performs autonomous deep research on the given query. Plans subtopics, fetches and validates sources from a configured retriever, accumulates a research context, and (optionally) writes a long-form report. Typical latency is 30-60 seconds. Use Server-Sent Events at /research/stream for live progress.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/ResearchRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Completed research result with report and source list.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ResearchResponse" }
              }
            }
          },
          "400": {
            "description": "Invalid request body.",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "headers": {
              "Retry-After": { "schema": { "type": "integer" } },
              "X-RateLimit-Limit": { "schema": { "type": "integer" } },
              "X-RateLimit-Remaining": { "schema": { "type": "integer" } }
            },
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }
            }
          }
        }
      }
    },
    "/research/stream": {
      "get": {
        "tags": ["research"],
        "operationId": "streamResearch",
        "summary": "Stream a deep-research task via Server-Sent Events",
        "description": "Streams progressive research events (planning, source-found, source-validated, report-chunk, complete) over SSE. Set Accept: text/event-stream.",
        "parameters": [
          {
            "name": "query",
            "in": "query",
            "required": true,
            "schema": { "type": "string", "minLength": 3 }
          },
          {
            "name": "report_type",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "enum": ["research_report", "outline_report", "resource_report", "detailed_report"] }
          }
        ],
        "responses": {
          "200": {
            "description": "An SSE stream of progress events terminated by a final 'complete' event.",
            "content": {
              "text/event-stream": {
                "schema": { "type": "string", "description": "SSE stream" }
              }
            }
          }
        }
      }
    },
    "/search": {
      "post": {
        "tags": ["search"],
        "operationId": "quickSearch",
        "summary": "Run a fast web search",
        "description": "Low-latency snippet search across the configured retriever (Tavily, Bing, Google, DuckDuckGo, SearXNG). Typical latency 1-5 seconds.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/SearchRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Search results.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SearchResponse" }
              }
            }
          },
          "400": {
            "description": "Invalid request body.",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }
            }
          }
        }
      }
    },
    "/report": {
      "post": {
        "tags": ["report"],
        "operationId": "writeReport",
        "summary": "Write a report from existing research context",
        "description": "Generates a long-form research report (Markdown) from a previously accumulated research context. Useful when you have already populated context via /research and want to re-render the report in a different format.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/ReportRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Generated report.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ReportResponse" }
              }
            }
          }
        }
      }
    },
    "/sources": {
      "get": {
        "tags": ["sources"],
        "operationId": "getSources",
        "summary": "List sources from the most recent research run",
        "responses": {
          "200": {
            "description": "List of source URLs and metadata.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": { "$ref": "#/components/schemas/Source" }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "HealthResponse": {
        "type": "object",
        "required": ["status"],
        "properties": {
          "status": { "type": "string", "enum": ["ok", "degraded"] },
          "version": { "type": "string" },
          "uptime_seconds": { "type": "integer" }
        }
      },
      "ResearchRequest": {
        "type": "object",
        "required": ["query"],
        "properties": {
          "query": { "type": "string", "description": "Research topic, framed as a question or instruction.", "minLength": 3 },
          "report_type": { "type": "string", "enum": ["research_report", "outline_report", "resource_report", "detailed_report"], "default": "research_report" },
          "tone": { "type": "string", "default": "objective" },
          "max_subtopics": { "type": "integer", "default": 3, "minimum": 1, "maximum": 10 },
          "max_iterations": { "type": "integer", "default": 4, "minimum": 1, "maximum": 12 },
          "retriever": { "type": "string", "description": "Retriever to use (tavily, bing, google, duckduckgo, searx, ...).", "default": "tavily" }
        }
      },
      "ResearchResponse": {
        "type": "object",
        "required": ["report", "sources"],
        "properties": {
          "report": { "type": "string", "description": "Long-form research report in Markdown with inline citations." },
          "sources": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/Source" }
          },
          "duration_ms": { "type": "integer" },
          "subtopics": { "type": "array", "items": { "type": "string" } }
        }
      },
      "SearchRequest": {
        "type": "object",
        "required": ["query"],
        "properties": {
          "query": { "type": "string", "minLength": 1 },
          "retriever": { "type": "string", "default": "tavily" },
          "max_results": { "type": "integer", "default": 5, "minimum": 1, "maximum": 20 }
        }
      },
      "SearchResponse": {
        "type": "object",
        "required": ["results"],
        "properties": {
          "results": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/SearchResult" }
          }
        }
      },
      "SearchResult": {
        "type": "object",
        "required": ["url", "title"],
        "properties": {
          "url": { "type": "string", "format": "uri" },
          "title": { "type": "string" },
          "content": { "type": "string" }
        }
      },
      "ReportRequest": {
        "type": "object",
        "required": ["query"],
        "properties": {
          "query": { "type": "string" },
          "context": { "type": "string", "description": "Pre-accumulated research context." },
          "report_type": { "type": "string", "enum": ["research_report", "outline_report", "resource_report", "detailed_report"], "default": "research_report" }
        }
      },
      "ReportResponse": {
        "type": "object",
        "required": ["report"],
        "properties": {
          "report": { "type": "string" }
        }
      },
      "Source": {
        "type": "object",
        "required": ["url"],
        "properties": {
          "url": { "type": "string", "format": "uri" },
          "title": { "type": "string" },
          "snippet": { "type": "string" }
        }
      },
      "Error": {
        "type": "object",
        "required": ["error"],
        "properties": {
          "error": {
            "type": "object",
            "required": ["code", "message"],
            "properties": {
              "code": { "type": "string", "description": "Stable error code, e.g. 'invalid_request', 'rate_limited', 'provider_error'." },
              "message": { "type": "string" },
              "retry_after_seconds": { "type": "integer" },
              "details": { "type": "object", "additionalProperties": true }
            }
          }
        }
      }
    },
    "securitySchemes": {
      "providerKeys": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Provider-Keys",
        "description": "Self-hosted servers read LLM and retriever API keys from environment variables (OPENAI_API_KEY, TAVILY_API_KEY, etc.). No GPT Researcher account is required."
      }
    }
  },
  "x-mcp": {
    "server": "gptr-mcp",
    "manifest": "https://gptr.dev/.well-known/mcp.json",
    "transports": ["stdio", "sse", "streamable-http"],
    "tools": ["deep_research", "quick_search", "write_report", "get_research_sources", "get_research_context"]
  }
}
