{
  "openapi": "3.1.0",
  "info": {
    "title": "FuturesDesk Public Agent API",
    "version": "1.0.0",
    "description": "Read-only, research-only public agent surfaces. API success never grants wagering, publication, spending, or mutation authority."
  },
  "servers": [
    { "url": "https://api.futuresdesk.io" }
  ],
  "paths": {
    "/api/agent/market-tape-decode": {
      "post": {
        "operationId": "decodeMarketTape",
        "summary": "Classify supplied market-tape evidence",
        "description": "Deterministically separates comparable movement, public concentration, catalyst evidence, named-book flow evidence, sharp-action claims, and edge.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/MarketTapeInput" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Evidence classification",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/MarketTapeResponse" }
              }
            }
          },
          "400": {
            "description": "Invalid input with machine-readable repair guidance"
          },
          "429": {
            "description": "Rate limited; honor Retry-After when supplied"
          }
        }
      }
    },
    "/api/heisman/market-topology": {
      "get": {
        "operationId": "getHeismanMarketTopology",
        "summary": "Read governed Heisman market topology",
        "description": "Returns a public allowlist projection. Canonical-read failure returns 503 with stale-labelled fallback rather than current-looking data.",
        "parameters": [
          { "name": "candidate", "in": "query", "description": "Bounded player key from candidates[].player_key; if unknown, request ?limit=1 first.", "schema": { "type": "string" } },
          { "name": "book", "in": "query", "schema": { "type": "string" } },
          { "name": "direct_only", "in": "query", "schema": { "type": "boolean" } },
          { "name": "sharp_only", "in": "query", "schema": { "type": "boolean" } },
          { "name": "state", "in": "query", "schema": { "type": "string" } },
          { "name": "limit", "in": "query", "description": "Bound candidate rows to 1-10 without changing derived state.", "schema": { "type": "integer", "minimum": 1, "maximum": 10 } }
        ],
        "responses": {
          "200": { "description": "Current governed topology" },
          "400": { "description": "Invalid filter; response includes repair detail, contract, and compact current-sample URL." },
          "404": { "description": "Candidate not found; response preserves snapshot metadata and includes a compact current-sample URL." },
          "503": { "description": "Canonical read unavailable; returned fallback is explicitly stale" }
        }
      }
    }
  },
  "x-futuresdesk-agent-quickstart": {
    "preferred_capability": "getHeismanMarketTopology",
    "current_sample": "GET /api/heisman/market-topology?limit=1",
    "failure_probe": "GET /api/heisman/market-topology?candidate=not-a-real-player",
    "repair_rule": "Follow fix.current_sample from the returned 4xx response and retry the same Heisman capability path.",
    "avoid_human_ui": true,
    "why": "Use the smallest current governed machine payload first; human-facing UI is not required for generic agent acceptance."
  },
  "components": {
    "schemas": {
      "MarketTapeInput": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "market",
          "openingLine",
          "currentLine",
          "sameBook",
          "sameMarket",
          "sameTerms",
          "sameJurisdiction",
          "timestampsKnown",
          "publicPct",
          "catalyst",
          "flowEvidence",
          "namedSourceVerified"
        ],
        "properties": {
          "market": { "type": "string", "enum": ["SPREAD", "TOTAL", "MONEYLINE", "PROP"] },
          "openingLine": { "type": ["number", "null"] },
          "currentLine": { "type": ["number", "null"] },
          "sameBook": { "type": "boolean" },
          "sameMarket": { "type": "boolean" },
          "sameTerms": { "type": "boolean" },
          "sameJurisdiction": { "type": "boolean" },
          "timestampsKnown": { "type": "boolean" },
          "publicPct": { "type": ["number", "null"], "minimum": 0, "maximum": 100 },
          "catalyst": { "type": "string", "enum": ["CONFIRMED", "POSSIBLE", "NONE_FOUND", "UNKNOWN"] },
          "flowEvidence": { "type": "string", "enum": ["NONE", "TICKET_SPLIT", "HANDLE_SPLIT", "LIABILITY_REPORT"] },
          "namedSourceVerified": { "type": "boolean" }
        }
      },
      "MarketTapeResponse": {
        "type": "object",
        "required": ["ok", "contract", "authority", "input", "result"],
        "properties": {
          "ok": { "const": true },
          "contract": { "const": "FD-PUBLIC-AGENT-MARKET-TAPE-v1" },
          "generated_at": { "type": "string", "format": "date-time" },
          "authority": {
            "type": "object",
            "properties": {
              "mode": { "const": "research_only" },
              "wager_authority": { "const": false },
              "publication_authority": { "const": false },
              "mutation_authority": { "const": false }
            }
          },
          "input": { "$ref": "#/components/schemas/MarketTapeInput" },
          "result": { "type": "object" }
        }
      }
    }
  }
}
