{
  "openapi": "3.1.0",
  "info": {
    "title": "Eriqa Headless API",
    "version": "1.0.0",
    "description": "Programmatic access to Eriqa call intelligence: calls, competency assessments, QA scorecards, reports, insights, coaching plans and playbooks for B2B verbal sales teams. Authenticate with a Personal Access Token (see https://eriqa.io/auth.md). MCP transport lives at https://mcp.eriqa.io.",
    "contact": {
      "name": "Eriqa",
      "url": "https://eriqa.io",
      "email": "hello@eriqa.io"
    },
    "license": { "name": "Proprietary", "url": "https://eriqa.io/terms" }
  },
  "externalDocs": {
    "description": "Human docs and MCP client setup",
    "url": "https://eriqa.io/mcp"
  },
  "servers": [
    {
      "url": "https://yfevoukvzwbhfmkkiprn.supabase.co/functions/v1",
      "description": "Production"
    }
  ],
  "security": [{ "bearerAuth": [] }, { "tokenQuery": [] }],
  "tags": [
    { "name": "tools", "description": "Invoke a headless tool by name (REST façade)." },
    { "name": "mcp",   "description": "MCP Streamable HTTP JSON-RPC endpoint." }
  ],
  "paths": {
    "/headless-api": {
      "post": {
        "tags": ["tools"],
        "operationId": "invokeTool",
        "summary": "Invoke a headless tool",
        "description": "Executes a named tool from the Eriqa headless catalogue and returns its JSON result. Equivalent to the tool an MCP client would call over /headless-mcp, exposed as a plain REST endpoint for agents that don't speak MCP.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/ToolInvocation" },
              "examples": {
                "listCalls": {
                  "summary": "List recent calls for a client",
                  "value": { "tool": "calls_list", "args": { "clientId": "13d54d5a-098f-420c-b78b-5279ec7a3a71", "limit": 20 } }
                },
                "askGrounded": {
                  "summary": "Ask a grounded question",
                  "value": { "tool": "ask", "args": { "question": "Which reps improved most on discovery last week?" } }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tool result",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ToolResult" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/headless-mcp": {
      "post": {
        "tags": ["mcp"],
        "operationId": "mcpJsonRpc",
        "summary": "MCP Streamable HTTP endpoint",
        "description": "JSON-RPC 2.0 endpoint conforming to the Model Context Protocol (spec: https://modelcontextprotocol.io). Preferred entry for MCP-aware clients (Claude, ChatGPT, Cursor, Grok, ChatGPT desktop, Continue). The A2A agent card and MCP server card both point here (via https://mcp.eriqa.io in production).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/JsonRpcRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "JSON-RPC response (may be streamed as text/event-stream)",
            "content": {
              "application/json":    { "schema": { "$ref": "#/components/schemas/JsonRpcResponse" } },
              "text/event-stream":   { "schema": { "type": "string", "description": "SSE stream of JSON-RPC responses" } }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "PAT",
        "description": "Eriqa Personal Access Token: `Authorization: Bearer iqa_pat_…`. Legacy `di_pat_…` tokens remain valid. Issue at https://eriqa.io/app/settings."
      },
      "tokenQuery": {
        "type": "apiKey",
        "in": "query",
        "name": "token",
        "description": "Fallback for MCP clients that cannot inject headers. Prefer bearerAuth."
      }
    },
    "schemas": {
      "ToolInvocation": {
        "type": "object",
        "required": ["tool"],
        "properties": {
          "tool": {
            "type": "string",
            "description": "Tool name. Enumerated at runtime via `tools_list`, representative categories include calls, competency, qa, reports, insights, ask, spotcheck, playbooks, coaching, team, clients, ingestion, automations, briefings, schedules, seat, system, templates, recommendations, citations, calibration, integrations, features."
          },
          "args": {
            "type": "object",
            "description": "Tool-specific arguments. See individual tool schemas over /headless-mcp `tools/list`.",
            "additionalProperties": true
          }
        }
      },
      "ToolResult": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean" },
          "data": { "description": "Tool-specific payload." },
          "error": {
            "type": "object",
            "properties": {
              "code":    { "type": "string" },
              "message": { "type": "string" }
            }
          }
        }
      },
      "JsonRpcRequest": {
        "type": "object",
        "required": ["jsonrpc", "method"],
        "properties": {
          "jsonrpc": { "type": "string", "const": "2.0" },
          "id":      { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "null" }] },
          "method":  { "type": "string", "description": "MCP method (e.g. `initialize`, `tools/list`, `tools/call`)." },
          "params":  { "type": "object", "additionalProperties": true }
        }
      },
      "JsonRpcResponse": {
        "type": "object",
        "properties": {
          "jsonrpc": { "type": "string", "const": "2.0" },
          "id":      { "oneOf": [{ "type": "string" }, { "type": "number" }, { "type": "null" }] },
          "result":  {},
          "error": {
            "type": "object",
            "properties": {
              "code":    { "type": "integer" },
              "message": { "type": "string" },
              "data":    {}
            }
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": { "type": "string" },
          "message": { "type": "string" }
        }
      }
    },
    "responses": {
      "BadRequest":   { "description": "Invalid input.",           "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "Unauthorized": { "description": "Missing or invalid PAT.",  "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "Forbidden":    { "description": "Token lacks required scope.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "RateLimited":  { "description": "Rate or LLM-token cap exceeded.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
    }
  }
}
