{
  "openapi": "3.1.0",
  "info": {
    "title": "Top 11 API",
    "version": "1.1.0",
    "description": "Read API for Top 11 independent rankings. Free, unauthenticated reads. Data is CC BY 4.0.",
    "contact": {
      "email": "agents@11.market",
      "url": "https://topelevens.com/for-agents"
    },
    "license": {
      "name": "CC BY 4.0",
      "url": "https://creativecommons.org/licenses/by/4.0/"
    }
  },
  "servers": [
    {
      "url": "https://topelevens.com/api"
    }
  ],
  "paths": {
    "/lists": {
      "get": {
        "summary": "List every published ranking",
        "operationId": "listLists",
        "responses": {
          "200": {
            "description": "Index of available lists",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/lists/{slug}": {
      "get": {
        "summary": "Get the full ranking for a list",
        "operationId": "getList",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "example": "fractional-cfo"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Full structured ranking JSON"
          },
          "404": {
            "description": "List not found"
          }
        }
      }
    },
    "/lists/{slug}/{rank}": {
      "get": {
        "summary": "Get a single entry by rank",
        "operationId": "getEntry",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "rank",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 11
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Single ranked entry"
          },
          "404": {
            "description": "Entry not found"
          }
        }
      }
    },
    "/lists/{slug}/md": {
      "get": {
        "summary": "Markdown mirror of a list",
        "operationId": "getListMarkdown",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "text/markdown"
          }
        }
      }
    },
    "/lists/{slug}/csv": {
      "get": {
        "summary": "CSV export of a list",
        "operationId": "getListCsv",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "text/csv"
          }
        }
      }
    },
    "/lists/{slug}/{rank}/md": {
      "get": {
        "summary": "Markdown passage for one entry",
        "operationId": "getEntryMarkdown",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "rank",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 11
            }
          }
        ],
        "responses": {
          "200": {
            "description": "text/markdown"
          }
        }
      }
    },
    "/lists/{slug}/recommend": {
      "get": {
        "summary": "Problem -> pick matcher",
        "operationId": "recommend",
        "description": "Hand over a user's problem/segment/budget; returns the top matched picks with reasons.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "problem",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "The user's need in plain language."
          },
          {
            "name": "segment",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "budget",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "$",
                "$$",
                "$$$"
              ]
            }
          },
          {
            "name": "max_risk",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "none",
                "low",
                "moderate",
                "elevated"
              ]
            },
            "description": "Exclude firms whose verified public risk signals exceed this level."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 11
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Ranked matched picks with reasons"
          },
          "404": {
            "description": "List not found"
          }
        }
      }
    },
    "/recommend": {
      "get": {
        "summary": "Cross-list problem -> pick matcher (no slug)",
        "operationId": "recommendGlobal",
        "description": "Hand over a need in plain language (q); Top 11 auto-picks the most relevant list and returns matched picks with reasons. Pass slug to force a list.",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "The user's need in plain language."
          },
          {
            "name": "segment",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "budget",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "$",
                "$$",
                "$$$"
              ]
            }
          },
          {
            "name": "max_risk",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "none",
                "low",
                "moderate",
                "elevated"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 11
            }
          },
          {
            "name": "slug",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Force a specific list instead of auto-picking."
          }
        ],
        "responses": {
          "200": {
            "description": "Matched list + ranked picks with reasons"
          }
        }
      }
    }
  }
}