{
 "openapi": "3.1.0",
 "info": {
  "title": "Vortex Data API",
  "version": "1",
  "summary": "Free, public, read-only Solana validator data.",
  "license": {
   "name": "CC BY 4.0",
   "url": "https://creativecommons.org/licenses/by/4.0/"
  },
  "description": "Free, public, read-only JSON API for Solana validator data from Vortex, for mainnet-beta and testnet: the validator directory and operational status, stake, delegators and stake pools, block income and MEV, Alpenglow voting participation and block production, per-slot consensus facts, client versions, geography, governance votes, feature gates and SIMDs.\n\nEvery data endpoint answers GET, with its parameters in the query string, and POST, with the same fields as a JSON body (`content-type: application/json`). Field names are camelCase on the wire. List parameters are comma-separated strings in the GET form. An omitted `epoch` means the current one.\n\nAlpenglow has been live on mainnet since epoch 1064: votes are BLS certificates, not transactions, and there are no vote credits or Proof of History. Endpoints tagged or described as Tower serve the history before the cutover.\n\nThis spec documents every route and the main response schemas; the other responses are described in full in https://api.vx.tools/llms.txt, the canonical reference.",
  "contact": {
   "name": "Vortex",
   "url": "https://vx.tools"
  }
 },
 "security": [],
 "externalDocs": {
  "description": "Full reference (llms.txt)",
  "url": "https://api.vx.tools/llms.txt"
 },
 "servers": [
  {
   "url": "https://api.vx.tools",
   "description": "mainnet-beta"
  },
  {
   "url": "https://api.testnet.vx.tools",
   "description": "testnet"
  }
 ],
 "tags": [
  {
   "name": "Service",
   "description": "The server itself and its documents."
  },
  {
   "name": "Validators (now)",
   "description": "The live validator set: directory, status, stake, geography."
  },
  {
   "name": "Validators (history)",
   "description": "One validator over epochs: stake changes, delegators, host and vote-account changes, income, governance. Tower-era vote endpoints are historical."
  },
  {
   "name": "Stake pools",
   "description": "Stake pools' holdings per epoch."
  },
  {
   "name": "Cluster",
   "description": "Cluster-wide distributions, live throughput and blocks, client versions, activity."
  },
  {
   "name": "Governance (mainnet)",
   "description": "svmgov governance proposals and votes."
  },
  {
   "name": "Feature gates",
   "description": "Feature gates, SIMDs and cluster announcements."
  },
  {
   "name": "Leaderboards",
   "description": "Per-epoch leaderboards; the voting leaderboard is Tower-era history."
  },
  {
   "name": "Alpenglow",
   "description": "Alpenglow consensus: participation, production, per-slot facts, rank maps, live votes."
  }
 ],
 "paths": {
  "/": {
   "get": {
    "operationId": "getRoot",
    "tags": [
     "Service"
    ],
    "summary": "Landing page (HTML) linking these docs",
    "description": "A small static HTML page (`text/html; charset=utf-8`) naming the API and linking /llms.txt, /openapi.json, the dashboard and vx.tools. Cache-Control: public, max-age=300. Use /version as a health check.\n\nFull reference: the `GET /` section of https://api.vx.tools/llms.txt.",
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControlStatic"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "text/html; charset=utf-8": {
        "schema": {
         "type": "string"
        }
       }
      }
     }
    }
   }
  },
  "/robots.txt": {
   "get": {
    "operationId": "getRobotsTxt",
    "tags": [
     "Service"
    ],
    "summary": "Crawler policy: everything allowed",
    "description": "`User-agent: *` / `Allow: /`, no sitemap. Search engines are kept out of raw JSON by the `X-Robots-Tag: noindex` header on JSON responses instead, so agents can still fetch the API for their users.\n\nFull reference: the `GET /robots.txt` section of https://api.vx.tools/llms.txt.",
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControlStatic"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "text/plain; charset=utf-8": {
        "schema": {
         "type": "string"
        }
       }
      }
     }
    }
   }
  },
  "/llms.txt": {
   "get": {
    "operationId": "getLlmsTxt",
    "tags": [
     "Service"
    ],
    "summary": "This reference (also /llms-full.txt)",
    "description": "This reference, as `text/plain; charset=utf-8`; the two routes serve the same file. It opens in the llmstxt.org shape (title, summary, a links section) and goes on with the full reference. Cache-Control: public, max-age=300; 503 with a short text body if the file is missing.\n\nFull reference: the `GET /llms.txt / GET /llms-full.txt` section of https://api.vx.tools/llms.txt.",
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControlStatic"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "text/plain; charset=utf-8": {
        "schema": {
         "type": "string"
        }
       }
      }
     }
    }
   }
  },
  "/llms-full.txt": {
   "get": {
    "operationId": "getLlmsFullTxt",
    "tags": [
     "Service"
    ],
    "summary": "This reference (same file as /llms.txt)",
    "description": "This reference, as `text/plain; charset=utf-8`; the two routes serve the same file. It opens in the llmstxt.org shape (title, summary, a links section) and goes on with the full reference. Cache-Control: public, max-age=300; 503 with a short text body if the file is missing.\n\nFull reference: the `GET /llms.txt / GET /llms-full.txt` section of https://api.vx.tools/llms.txt.",
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControlStatic"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "text/plain; charset=utf-8": {
        "schema": {
         "type": "string"
        }
       }
      }
     }
    }
   }
  },
  "/openapi.json": {
   "get": {
    "operationId": "getOpenapiJson",
    "tags": [
     "Service"
    ],
    "summary": "OpenAPI 3.1 spec of every endpoint",
    "description": "The OpenAPI 3.1 spec of every route on this server: parameters in both GET (query string) and POST (JSON body) form, Cache-Control, and schemas for the main responses (the rest point back here). Cache-Control: public, max-age=300.\n\nFull reference: the `GET /openapi.json` section of https://api.vx.tools/llms.txt.",
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControlStatic"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "This document."
        }
       }
      }
     }
    }
   }
  },
  "/version": {
   "get": {
    "operationId": "getVersion",
    "tags": [
     "Service"
    ],
    "summary": "{ \"sha\", \"cluster\" }: the git commit this server runs; every response also carries it as the `x-vortex-build` header",
    "description": "The git commit this server was built from and the cluster it serves. Every response also carries the commit as the `x-vortex-build` header.\n\nFull reference: the `GET /version` section of https://api.vx.tools/llms.txt.",
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Version"
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/ready": {
   "get": {
    "operationId": "getReady",
    "tags": [
     "Service"
    ],
    "summary": "Readiness: 200 once warmed up, else 503 naming what is pending",
    "description": "Readiness, for zero-downtime (blue/green) deploys: 200 once this process has finished its startup warm-up (the clock, directory, tenure and epoch-total snapshots read, the warmers behind the heavy cached endpoints done with their first pass), else 503 with the same body naming what is still pending. Reads in-memory flags only, never the database. `/version` is the liveness check. Cache-Control: no-store. Also answers HEAD.\n\nFull reference: the `GET /ready` section of https://api.vx.tools/llms.txt.",
    "responses": {
     "200": {
      "description": "Ready",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Ready"
        }
       }
      }
     },
     "503": {
      "description": "Still warming up (or the singleton lock file cannot be opened)",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Ready"
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/usage": {
   "get": {
    "operationId": "getUsage",
    "tags": [
     "Service"
    ],
    "summary": "Operators only (403 elsewhere): request counts, bigtable reads",
    "description": "Operational, not part of the data API, and private: answered only on the API host itself and to the operators' agent host; anyone else gets 403. Request counts per endpoint, method, caller origin and status class since the counter file was created (persisted across restarts). Used to decide what can be deprecated. Cache-Control: no-store. Requests to /usage itself are not counted.\n\nFull reference: the `GET /usage` section of https://api.vx.tools/llms.txt.",
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET /usage` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/admin": {
   "get": {
    "operationId": "getAdmin",
    "tags": [
     "Service"
    ],
    "summary": "Operators only: the latency page for a browser (HTML)",
    "description": "A static HTML page (`text/html; charset=utf-8`) holding no data: it asks for the admin token, keeps it for the tab's session and reads /admin/latency with it. 404 when no admin token is configured.\n\nFull reference: the `GET /admin/latency` section of https://api.vx.tools/llms.txt.",
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "text/html; charset=utf-8": {
        "schema": {
         "type": "string"
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/admin/latency": {
   "get": {
    "operationId": "getAdminLatency",
    "tags": [
     "Service"
    ],
    "summary": "Operators only (admin token): per-route latency percentiles",
    "description": "Operational, not part of the data API, and private: needs `Authorization: Bearer <admin token>` (401 without it) and answers 404 on an instance with no admin token configured. Per method and matched route over the window: count, errors (5xx and 408), other 4xx, mean, p50, p90, p99 and max, measured until the response headers leave. Cache-Control: no-store.\n\nFull reference: the `GET /admin/latency` section of https://api.vx.tools/llms.txt.",
    "security": [
     {
      "adminToken": []
     }
    ],
    "parameters": [
     {
      "name": "window",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "enum": [
        "5m",
        "1h",
        "24h"
       ],
       "default": "1h"
      },
      "description": "How far back: 5 minutes, 1 hour or 24 hours (whole slices, so `from` can be up to one slice earlier)."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET /admin/latency` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/epochs/current": {
   "get": {
    "operationId": "getEpochsCurrent",
    "tags": [
     "Service"
    ],
    "summary": "Current epoch, Alpenglow phase, progress",
    "description": "The current epoch of the cluster this instance serves (mainnet-beta on api.vx.tools), plus its TowerBFT -> Alpenglow (SIMD-0326) transition state. Mainnet has run Alpenglow since epoch 1064 (`phase: \"active\"`, `cutoverEpoch: 1064`); the field stays for history and for clusters still moving.\n\nFull reference: the `GET|POST /epochs/current` section of https://api.vx.tools/llms.txt.",
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/EpochsCurrent"
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postEpochsCurrent",
    "tags": [
     "Service"
    ],
    "summary": "Current epoch, Alpenglow phase, progress",
    "description": "The POST form of `GET /epochs/current`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "No fields; an empty body or `{}`.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {}
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/EpochsCurrent"
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/validators": {
   "get": {
    "operationId": "getValidators",
    "tags": [
     "Validators (now)"
    ],
    "summary": "Directory: identity, vote account, name (info=true: website, details, icon)",
    "description": "Directory of every validator we know about. Sorted by nodeAddress for byte-identical responses across refreshes. Cached with Cache-Control: public, max-age=60, stale-while-revalidate=300.\n\nFull reference: the `GET|POST /validators` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "info",
      "in": "query",
      "required": false,
      "schema": {
       "type": "boolean"
      },
      "description": "Add `website`, `details` and `iconUrl` (default false)."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ValidatorDirectory"
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postValidators",
    "tags": [
     "Validators (now)"
    ],
    "summary": "Directory: identity, vote account, name (info=true: website, details, icon)",
    "description": "The POST form of `GET /validators`, with the same answer: `info` is read from the query string on either method, never a body.",
    "parameters": [
     {
      "name": "info",
      "in": "query",
      "required": false,
      "schema": {
       "type": "boolean"
      },
      "description": "Add `website`, `details` and `iconUrl` (default false)."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ValidatorDirectory"
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/validators/stake": {
   "get": {
    "operationId": "getValidatorsStake",
    "tags": [
     "Validators (now)"
    ],
    "summary": "Stake, commission, moving (warming/cooling) stake",
    "description": "Current-epoch stake and advertised commission for one validator. Accepts EITHER `identity` OR `voteKey`; `voteKey` wins if both are given.\n\nFull reference: the `GET|POST /validators/stake` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "identity",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
     },
     {
      "name": "voteKey",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Vote account or node identity (base58); either kind is accepted."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /validators/stake` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postValidatorsStake",
    "tags": [
     "Validators (now)"
    ],
    "summary": "Stake, commission, moving (warming/cooling) stake",
    "description": "The POST form of `GET /validators/stake`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "identity": {
          "type": [
           "string",
           "null"
          ],
          "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
         },
         "voteKey": {
          "type": [
           "string",
           "null"
          ],
          "description": "Vote account or node identity (base58); either kind is accepted."
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /validators/stake` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/validators/commission": {
   "get": {
    "operationId": "getValidatorsCommission",
    "tags": [
     "Validators (now)"
    ],
    "summary": "Commission change events",
    "description": "Commission-change events for one validator's vote account over the last N epochs, oldest first, from the ingested transaction stream.\n\nFull reference: the `GET|POST /validators/commission` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "identity",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
     },
     {
      "name": "voteKey",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Vote account or node identity (base58); either kind is accepted."
     },
     {
      "name": "limit",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "type": "object"
         },
         "description": "Shape: see the `GET|POST /validators/commission` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postValidatorsCommission",
    "tags": [
     "Validators (now)"
    ],
    "summary": "Commission change events",
    "description": "The POST form of `GET /validators/commission`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "identity": {
          "type": [
           "string",
           "null"
          ],
          "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
         },
         "voteKey": {
          "type": [
           "string",
           "null"
          ],
          "description": "Vote account or node identity (base58); either kind is accepted."
         },
         "limit": {
          "type": "integer",
          "minimum": 0
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "type": "object"
         },
         "description": "Shape: see the `GET|POST /validators/commission` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/validators/status": {
   "get": {
    "operationId": "getValidatorsStatus",
    "tags": [
     "Validators (now)"
    ],
    "summary": "One validator's operational checks",
    "description": "Operational status of one validator, with a verdict per check. Built from in-memory snapshots refreshed in the background (gossip and vote accounts every 60 s, vote-account state every 5 min, on-chain validator info and SFDP data hourly, tenure when its records change, at most every 5 min; BAM Boost distributions every 10 min, DoubleZero every 5 min); no I/O per request. `bamBoost` (mainnet): the JitoSOL the identity can still claim from Jito's BAM Boost, what it claimed and what expired, with the `bam_boost` check warning while something is claimable. `doubleZero` (mainnet): the DoubleZero devices the identity is connected to, from DZ's ledger every 5 min. Cache-Control: public, max-age=30, stale-while-revalidate=60.\n\nFull reference: the `GET|POST /validators/status` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "identity",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
     },
     {
      "name": "voteKey",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Vote account or node identity (base58); either kind is accepted."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /validators/status` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postValidatorsStatus",
    "tags": [
     "Validators (now)"
    ],
    "summary": "One validator's operational checks",
    "description": "The POST form of `GET /validators/status`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "identity": {
          "type": [
           "string",
           "null"
          ],
          "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
         },
         "voteKey": {
          "type": [
           "string",
           "null"
          ],
          "description": "Vote account or node identity (base58); either kind is accepted."
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /validators/status` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/validators/status/summary": {
   "get": {
    "operationId": "getValidatorsStatusSummary",
    "tags": [
     "Validators (now)"
    ],
    "summary": "Every validator's status, one row each",
    "description": "Every staked validator's status in one response, for tables. Each row is /validators/status for that validator projected to sortable facts plus the check verdicts WITHOUT their summaries. Built from the same snapshot with the same rules, so a verdict here never disagrees with the per-validator page. Sorted by identity. Cache-Control: public, max-age=30, stale-while-revalidate=60.\n\nFull reference: the `GET|POST /validators/status/summary` section of https://api.vx.tools/llms.txt.",
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /validators/status/summary` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postValidatorsStatusSummary",
    "tags": [
     "Validators (now)"
    ],
    "summary": "Every validator's status, one row each",
    "description": "The POST form of `GET /validators/status/summary`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "No fields; an empty body or `{}`.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {}
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /validators/status/summary` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/validators/geo": {
   "get": {
    "operationId": "getValidatorsGeo",
    "tags": [
     "Validators (now)"
    ],
    "summary": "Geolocation, now or per epoch",
    "description": "Every staked validator with its geolocation (gossip address through DB-IP lite; see /validators). Sorted by nodeAddress. Cache-Control: public, max-age=60, stale-while-revalidate=300; a past epoch's answer max-age=3600.\n\nFull reference: the `GET|POST /validators/geo` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "epoch",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Where validators were in this epoch (its recorded gossip addresses); default: where they are now."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /validators/geo` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postValidatorsGeo",
    "tags": [
     "Validators (now)"
    ],
    "summary": "Geolocation, now or per epoch",
    "description": "The POST form of `GET /validators/geo`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "epoch": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "Where validators were in this epoch (its recorded gossip addresses); default: where they are now."
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /validators/geo` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/validators/names": {
   "get": {
    "operationId": "getValidatorsNames",
    "tags": [
     "Validators (now)"
    ],
    "summary": "Names of every identity, past ones too",
    "description": "Every node identity with a name, validating today or not: the name it published on chain (validator-info) or a curated one, which wins, as /validators uses. For naming keys outside today's set: past epochs' validators (/cluster/geo-history identities, host and stake histories, counterparts). ~3,300 on mainnet, ~200 KB. Cache-Control: public, max-age=300, stale-while-revalidate=3600.\n\nFull reference: the `GET|POST /validators/names` section of https://api.vx.tools/llms.txt.",
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /validators/names` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postValidatorsNames",
    "tags": [
     "Validators (now)"
    ],
    "summary": "Names of every identity, past ones too",
    "description": "The POST form of `GET /validators/names`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "No fields; an empty body or `{}`.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {}
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /validators/names` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/cluster/throughput": {
   "get": {
    "operationId": "getClusterThroughput",
    "tags": [
     "Cluster"
    ],
    "summary": "Transactions and slots per minute, last 30 min to 6 h",
    "description": "Transactions per second over time, as the explorer's chart: one point per minute from the cluster's performance samples (getRecentPerformanceSamples, read by our writer every minute). Params: window  `30m` (default), `2h`, `6h`, or any `<n>m` / `<n>h` up to 6 h Response: { \"windowSecs\": u64, \"readAt\": unix_s,              // when the samples were read \"points\": [                    // oldest first { \"t\": unix_s,               // when the sample ended (approximate: //   counted back from readAt by periods) \"periodSecs\": u16,         // 60 \"slot\": u64,               // its last slot \"slots\": u64, \"transactions\": u64, \"nonVoteTransactions\": u64 | null,  // = transactions under Alpenglow \"tps\": f64 } ] }           // transactions / periodSecs No block count: samples count slots, not blocks (see /cluster/blocks). 400 for a bad window, 404 until the writer has written samples. Cache-Control max-age=30.\n\nFull reference: the `GET|POST /cluster/throughput` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "window",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "`30m`, `2h`, `6h` (minutes `m` or hours `h`, up to 6 h); 30 min when omitted."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /cluster/throughput` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postClusterThroughput",
    "tags": [
     "Cluster"
    ],
    "summary": "Transactions and slots per minute, last 30 min to 6 h",
    "description": "The POST form of `GET /cluster/throughput`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "window": {
          "type": [
           "string",
           "null"
          ],
          "description": "`30m`, `2h`, `6h` (minutes `m` or hours `h`, up to 6 h); 30 min when omitted."
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /cluster/throughput` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/cluster/blocks": {
   "get": {
    "operationId": "getClusterBlocks",
    "tags": [
     "Cluster"
    ],
    "summary": "Blocks, transactions, compute units and block income per 10 s or more, last 30 min to 6 h",
    "description": "Confirmed blocks over time: how many, their transactions (TPS history from the block store), the compute units they consumed and the leaders' income from them, totalled by our block ingestor per 10 s of block time as it ingests each block (rewritten every 20 s) and summed here into the bucket size asked for. Mainnet only: 404 on testnet.\n\nCache-Control max-age=10.\n\nFull reference: the `GET|POST /cluster/blocks` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "window",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "As `/cluster/throughput`: `30m`, `2h`, `6h` (minutes `m` or hours `h`, up to 6 h); 30 min when omitted."
     },
     {
      "name": "bucket",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "`10s`, `30s`, `1m`, `5m` (seconds `s` or minutes `m`): a multiple of the stored 10 s, at most the window and at most 720 per window; 1 min when omitted."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /cluster/blocks` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postClusterBlocks",
    "tags": [
     "Cluster"
    ],
    "summary": "Blocks, transactions, compute units and block income per 10 s or more, last 30 min to 6 h",
    "description": "The POST form of `GET /cluster/blocks`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "window": {
          "type": [
           "string",
           "null"
          ],
          "description": "As `/cluster/throughput`: `30m`, `2h`, `6h` (minutes `m` or hours `h`, up to 6 h); 30 min when omitted."
         },
         "bucket": {
          "type": [
           "string",
           "null"
          ],
          "description": "`10s`, `30s`, `1m`, `5m` (seconds `s` or minutes `m`): a multiple of the stored 10 s, at most the window and at most 720 per window; 1 min when omitted."
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /cluster/blocks` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/cluster/blocks/recent": {
   "get": {
    "operationId": "getClusterBlocksRecent",
    "tags": [
     "Cluster"
    ],
    "summary": "The newest blocks one by one: transactions, compute units, income",
    "description": "The newest confirmed blocks one by one, for a chart that moves per block (rolling TPS, compute units per block). Mainnet only (testnet has no block ingestor: 404). Written by the block ingestor every 2 s; it trails the chain by its ingest lag, usually ~20 slots (~5 s): `ingestion.blocks` on /epochs/current says how far. Params: slots       slots back from the newest block (default 512, at most 1024) afterSlot   only blocks after this slot: pass the last one you have Response: { \"readAt\": unix_s,              // when the row was written \"newestSlot\": u64 | null,      // newest block stored, returned or not \"blocks\": [                    // slot ascending; skipped slots absent { \"slot\": u64, \"t\": unix_s,               // its block_time \"transactions\": u64,       // all of them (no votes in Alpenglow blocks) \"computeUnits\": u64,       // consumed \"baseFees\": u64,           // lamports, the leader's share (as /blocks/income) \"priorityFees\": u64, \"mevTips\": u64 } ] } TPS over a span: sum transactions / (t of last − t of first); block_time is whole seconds, so take spans of several seconds. 400 for slots 0 or over 1024. Cache-Control max-age=1.\n\nFull reference: the `GET|POST /cluster/blocks/recent` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "slots",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Slots back from the newest block (default 512, at most 1024)."
     },
     {
      "name": "afterSlot",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Only blocks after this slot: a poller passes the last it has."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /cluster/blocks/recent` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postClusterBlocksRecent",
    "tags": [
     "Cluster"
    ],
    "summary": "The newest blocks one by one: transactions, compute units, income",
    "description": "The POST form of `GET /cluster/blocks/recent`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "slots": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "Slots back from the newest block (default 512, at most 1024)."
         },
         "afterSlot": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "Only blocks after this slot: a poller passes the last it has."
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /cluster/blocks/recent` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/cluster/halt": {
   "get": {
    "operationId": "getClusterHalt",
    "tags": [
     "Cluster"
    ],
    "summary": "The last slots before a halt",
    "description": "What the last slots before a halt looked like: by default the window ending at the last slot the chain reached (`chain.lastSlot` on /epochs/current), so it reads the run-up to a halt; `slot` picks any other window. Alpenglow slots only (the footers are its source).\n\nFull reference: the `GET|POST /cluster/halt` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "slot",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "The window's last slot; default the last slot the chain reached (`chain.lastSlot`)."
     },
     {
      "name": "slots",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Slots in the window, 1..=1000; default 300."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /cluster/halt` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postClusterHalt",
    "tags": [
     "Cluster"
    ],
    "summary": "The last slots before a halt",
    "description": "The POST form of `GET /cluster/halt`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "slot": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "The window's last slot; default the last slot the chain reached (`chain.lastSlot`)."
         },
         "slots": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "Slots in the window, 1..=1000; default 300."
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /cluster/halt` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/cluster/distribution": {
   "get": {
    "operationId": "getClusterDistribution",
    "tags": [
     "Cluster"
    ],
    "summary": "Stake by client and location, now",
    "description": "Cluster-wide activated-stake distribution by client and by location, from the same 60 s snapshot as /validators/status. Every list is sorted by stake, largest first. Cache-Control: public, max-age=60, stale-while-revalidate=300.\n\nFull reference: the `GET|POST /cluster/distribution` section of https://api.vx.tools/llms.txt.",
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /cluster/distribution` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postClusterDistribution",
    "tags": [
     "Cluster"
    ],
    "summary": "Stake by client and location, now",
    "description": "The POST form of `GET /cluster/distribution`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "No fields; an empty body or `{}`.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {}
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /cluster/distribution` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/cluster/required-versions": {
   "get": {
    "operationId": "getClusterRequiredVersions",
    "tags": [
     "Cluster"
    ],
    "summary": "SFDP required versions",
    "description": "The Solana Foundation Delegation Program's required client versions per epoch, for both clusters, as published at api.solana.org (refreshed hourly). Cache-Control: public, max-age=300, stale-while-revalidate=3600.\n\nFull reference: the `GET|POST /cluster/required-versions` section of https://api.vx.tools/llms.txt.",
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /cluster/required-versions` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postClusterRequiredVersions",
    "tags": [
     "Cluster"
    ],
    "summary": "SFDP required versions",
    "description": "The POST form of `GET /cluster/required-versions`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "No fields; an empty body or `{}`.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {}
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /cluster/required-versions` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/blocks/income": {
   "get": {
    "operationId": "getBlocksIncome",
    "tags": [
     "Validators (history)"
    ],
    "summary": "Per-block income in one epoch",
    "description": "Per-slot income for a single validator within one epoch.\n\nFull reference: the `GET|POST /blocks/income` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "identity",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
     },
     {
      "name": "voteKey",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "`vote_key` too: these two endpoints took only that spelling once."
     },
     {
      "name": "epoch",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Default: the current epoch."
     },
     {
      "name": "sort",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "`income`: biggest blocks first (total income), with `limit`."
     },
     {
      "name": "limit",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "At most this many rows (1..=1000), after `sort`."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "type": "object"
         },
         "description": "Shape: see the `GET|POST /blocks/income` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postBlocksIncome",
    "tags": [
     "Validators (history)"
    ],
    "summary": "Per-block income in one epoch",
    "description": "The POST form of `GET /blocks/income`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "identity": {
          "type": [
           "string",
           "null"
          ],
          "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
         },
         "voteKey": {
          "type": [
           "string",
           "null"
          ],
          "description": "`vote_key` too: these two endpoints took only that spelling once."
         },
         "epoch": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "Default: the current epoch."
         },
         "sort": {
          "type": [
           "string",
           "null"
          ],
          "description": "`income`: biggest blocks first (total income), with `limit`."
         },
         "limit": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "At most this many rows (1..=1000), after `sort`."
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "type": "object"
         },
         "description": "Shape: see the `GET|POST /blocks/income` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/blocks/insights": {
   "get": {
    "operationId": "getBlocksInsights",
    "tags": [
     "Validators (history)"
    ],
    "summary": "Per-slot leader, skip, vote latency (Tower)",
    "description": "Per-slot leader and skip flag for arbitrary slots, plus the vote-latency distribution of Tower-era slots (mainnet before the cutover in epoch 1064). Alpenglow votes are not transactions, so later slots have no latency to time; use /slot or /slots for them.\n\nFull reference: the `GET|POST /blocks/insights` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "slots",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string",
       "pattern": "^\\d+(\\s*,\\s*\\d+)*$",
       "description": "Comma-separated slots: the GET form of the JSON array."
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/BlocksInsights"
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postBlocksInsights",
    "tags": [
     "Validators (history)"
    ],
    "summary": "Per-slot leader, skip, vote latency (Tower)",
    "description": "The POST form of `GET /blocks/insights`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": true,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "slots": {
          "type": "array",
          "items": {
           "type": "integer",
           "minimum": 0
          },
          "maxItems": 1000
         }
        },
        "required": [
         "slots"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/BlocksInsights"
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/epochs/income": {
   "get": {
    "operationId": "getEpochsIncome",
    "tags": [
     "Validators (history)"
    ],
    "summary": "Per-epoch block income",
    "description": "Per-epoch income summary for one validator over the last N epochs.\n\nFull reference: the `GET|POST /epochs/income` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "identity",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
     },
     {
      "name": "voteKey",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "`vote_key` too: these two endpoints took only that spelling once."
     },
     {
      "name": "limit",
      "in": "query",
      "required": true,
      "schema": {
       "type": "integer",
       "minimum": 0
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "type": "object"
         },
         "description": "Shape: see the `GET|POST /epochs/income` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postEpochsIncome",
    "tags": [
     "Validators (history)"
    ],
    "summary": "Per-epoch block income",
    "description": "The POST form of `GET /epochs/income`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": true,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "identity": {
          "type": [
           "string",
           "null"
          ],
          "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
         },
         "voteKey": {
          "type": [
           "string",
           "null"
          ],
          "description": "`vote_key` too: these two endpoints took only that spelling once."
         },
         "limit": {
          "type": "integer",
          "minimum": 0
         }
        },
        "required": [
         "limit"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "type": "object"
         },
         "description": "Shape: see the `GET|POST /epochs/income` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/epochs/vote-stats": {
   "get": {
    "operationId": "getEpochsVoteStats",
    "tags": [
     "Validators (history)"
    ],
    "summary": "Per-epoch voting performance (Tower)",
    "description": "Historical (Tower era, mainnet epochs before 1064): per-epoch voting performance for one vote account over the last N Tower epochs. The data is keyed by vote account; a node identity is mapped to its vote account (see \"Naming a validator\").\n\nFull reference: the `GET|POST /epochs/vote-stats` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "identity",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
     },
     {
      "name": "voteKey",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Vote account or node identity (base58); either kind is accepted."
     },
     {
      "name": "limit",
      "in": "query",
      "required": true,
      "schema": {
       "type": "integer",
       "minimum": 0
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "type": "object"
         },
         "description": "Shape: see the `GET|POST /epochs/vote-stats` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postEpochsVoteStats",
    "tags": [
     "Validators (history)"
    ],
    "summary": "Per-epoch voting performance (Tower)",
    "description": "The POST form of `GET /epochs/vote-stats`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": true,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "identity": {
          "type": [
           "string",
           "null"
          ],
          "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
         },
         "voteKey": {
          "type": [
           "string",
           "null"
          ],
          "description": "Vote account or node identity (base58); either kind is accepted."
         },
         "limit": {
          "type": "integer",
          "minimum": 0
         }
        },
        "required": [
         "limit"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "type": "object"
         },
         "description": "Shape: see the `GET|POST /epochs/vote-stats` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/epochs/earnings": {
   "get": {
    "operationId": "getEpochsEarnings",
    "tags": [
     "Validators (history)"
    ],
    "summary": "Per-epoch earnings and costs",
    "description": "Per-epoch on-chain earnings for one validator: the validator's take of each revenue stream, what voting cost, and the net. `income.mevCommission` is the tip router's validator cut (`sc.tip`) where published, else estimated the same way (`mevCommissionBasis`); `blockRevenueCommission` is on the collected fees, `baseFees + priorityFees` (`baseFees` is already net of the burn). Mainnet epochs from 912 include Jito's BAM Boost (`income.bamBoost`, lamports at the epoch's JitoSOL rate, counted when claimed or still claimable; `bamBoost` the allotment, rate and claim state). Mainnet also lists DoubleZero Edge's shred-publisher rewards (`doubleZero`: USDC, 2Z or wSOL by program and period, in token base units, not counted in `income` or `net`). Flows only — no balances (an account balance mixes operating results with the operator's own deposits and withdrawals; \"do I need to top up\" is on /validators/status). Takes `identity` and/or `voteKey` (see \"Naming a validator\"). Keyed by the vote account: each epoch's income is read under the node identity that epoch recorded for it (from ~1046; today's before), so a validator that rotated its identity keeps its history.\n\nFull reference: the `GET|POST /epochs/earnings` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "identity",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
     },
     {
      "name": "voteKey",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Vote account or node identity (base58); either kind is accepted."
     },
     {
      "name": "limit",
      "in": "query",
      "required": true,
      "schema": {
       "type": "integer",
       "minimum": 0
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "type": "object"
         },
         "description": "Shape: see the `GET|POST /epochs/earnings` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postEpochsEarnings",
    "tags": [
     "Validators (history)"
    ],
    "summary": "Per-epoch earnings and costs",
    "description": "The POST form of `GET /epochs/earnings`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": true,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "identity": {
          "type": [
           "string",
           "null"
          ],
          "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
         },
         "voteKey": {
          "type": [
           "string",
           "null"
          ],
          "description": "Vote account or node identity (base58); either kind is accepted."
         },
         "limit": {
          "type": "integer",
          "minimum": 0
         }
        },
        "required": [
         "limit"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "type": "object"
         },
         "description": "Shape: see the `GET|POST /epochs/earnings` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/epochs/votes": {
   "get": {
    "operationId": "getEpochsVotes",
    "tags": [
     "Validators (history)"
    ],
    "summary": "Per-slot vote history (Tower)",
    "description": "Historical (Tower era, mainnet epochs before 1064): base64-encoded per-slot vote history for a validator in one epoch. Takes `identity` and/or `voteKey`, either kind of key (`voteKey` wins; see \"Naming a validator\"); the history is the vote account's. Before 2026-10-25 a node identity here got 404. Responses are cached a minute per (account, epoch); the current epoch's history grows a 1,000-slot bucket at a time, so it is at most that much behind.\n\nFull reference: the `GET|POST /epochs/votes` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "identity",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
     },
     {
      "name": "voteKey",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Vote account or node identity (base58); either kind is accepted."
     },
     {
      "name": "epoch",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /epochs/votes` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postEpochsVotes",
    "tags": [
     "Validators (history)"
    ],
    "summary": "Per-slot vote history (Tower)",
    "description": "The POST form of `GET /epochs/votes`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "identity": {
          "type": [
           "string",
           "null"
          ],
          "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
         },
         "voteKey": {
          "type": [
           "string",
           "null"
          ],
          "description": "Vote account or node identity (base58); either kind is accepted."
         },
         "epoch": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /epochs/votes` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/epochs/leaderboard": {
   "get": {
    "operationId": "getEpochsLeaderboard",
    "tags": [
     "Leaderboards"
    ],
    "summary": "Alias of /epochs/leaderboard/voting: Tower voting (historical)",
    "description": "Historical (Tower era, mainnet epochs before 1064): the voting performance leaderboard for one epoch. The two routes are identical; /epochs/leaderboard is kept for backwards compat.\n\nFull reference: the `GET|POST /epochs/leaderboard         (alias) / GET|POST /epochs/leaderboard/voting` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "epoch",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /epochs/leaderboard         (alias) / GET|POST /epochs/leaderboard/voting` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postEpochsLeaderboard",
    "tags": [
     "Leaderboards"
    ],
    "summary": "Alias of /epochs/leaderboard/voting: Tower voting (historical)",
    "description": "The POST form of `GET /epochs/leaderboard`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "epoch": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /epochs/leaderboard         (alias) / GET|POST /epochs/leaderboard/voting` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/epochs/leaderboard/voting": {
   "get": {
    "operationId": "getEpochsLeaderboardVoting",
    "tags": [
     "Leaderboards"
    ],
    "summary": "Tower voting (historical)",
    "description": "Historical (Tower era, mainnet epochs before 1064): the voting performance leaderboard for one epoch. The two routes are identical; /epochs/leaderboard is kept for backwards compat.\n\nFull reference: the `GET|POST /epochs/leaderboard         (alias) / GET|POST /epochs/leaderboard/voting` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "epoch",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /epochs/leaderboard         (alias) / GET|POST /epochs/leaderboard/voting` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postEpochsLeaderboardVoting",
    "tags": [
     "Leaderboards"
    ],
    "summary": "Tower voting (historical)",
    "description": "The POST form of `GET /epochs/leaderboard/voting`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "epoch": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /epochs/leaderboard         (alias) / GET|POST /epochs/leaderboard/voting` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/epochs/leaderboard/income": {
   "get": {
    "operationId": "getEpochsLeaderboardIncome",
    "tags": [
     "Leaderboards"
    ],
    "summary": "Block income",
    "description": "Block-income leaderboard for one epoch.\n\nFull reference: the `GET|POST /epochs/leaderboard/income` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "epoch",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/IncomeLeaderboard"
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postEpochsLeaderboardIncome",
    "tags": [
     "Leaderboards"
    ],
    "summary": "Block income",
    "description": "The POST form of `GET /epochs/leaderboard/income`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "epoch": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/IncomeLeaderboard"
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/epochs/participation": {
   "get": {
    "operationId": "getEpochsParticipation",
    "tags": [
     "Alpenglow"
    ],
    "summary": "One validator's participation per epoch",
    "description": "Alpenglow successor to /epochs/vote-stats: per-epoch certificate participation for one VOTE account over the last N epochs, from the cutover epoch on. Votes are BLS messages in Alpenglow, never transactions, so there are no credits or latencies here; what the chain records per slot is who was in the notarize / skip *reward certificate* bitmaps of the footer eight slots later, and who was in the finalization aggregate the leader carried. Every count is over `eligibleSlots` (slots whose footer our warehouse read), never over the epoch's slot count.\n\nFull reference: the `GET|POST /epochs/participation` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "voteKey",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Vote account or node identity (base58); either kind is accepted."
     },
     {
      "name": "limit",
      "in": "query",
      "required": true,
      "schema": {
       "type": "integer",
       "minimum": 0
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/ParticipationItem"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postEpochsParticipation",
    "tags": [
     "Alpenglow"
    ],
    "summary": "One validator's participation per epoch",
    "description": "The POST form of `GET /epochs/participation`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": true,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "voteKey": {
          "type": "string",
          "description": "Vote account or node identity (base58); either kind is accepted."
         },
         "limit": {
          "type": "integer",
          "minimum": 0
         }
        },
        "required": [
         "voteKey",
         "limit"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/ParticipationItem"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/epochs/leaderboard/participation": {
   "get": {
    "operationId": "getEpochsLeaderboardParticipation",
    "tags": [
     "Leaderboards"
    ],
    "summary": "Alpenglow voting participation",
    "description": "Alpenglow successor to /epochs/leaderboard/voting: every validator's participation for one epoch, with the same cohort fields (datacenter, provider, software) as the voting leaderboard. Tower epochs (< cutoverEpoch) return `\"consensus\": \"tower\"` and empty records without a storage read.\n\nFull reference: the `GET|POST /epochs/leaderboard/participation` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "epoch",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ParticipationLeaderboard"
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postEpochsLeaderboardParticipation",
    "tags": [
     "Leaderboards"
    ],
    "summary": "Alpenglow voting participation",
    "description": "The POST form of `GET /epochs/leaderboard/participation`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "epoch": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ParticipationLeaderboard"
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/epochs/participation/history": {
   "get": {
    "operationId": "getEpochsParticipationHistory",
    "tags": [
     "Alpenglow"
    ],
    "summary": "Its per-slot timeline",
    "description": "Alpenglow successor to /epochs/votes: what one VOTE account did on every reward slot of an epoch, from the per-validator timeline the Alpenglow ingestor writes.\n\nFull reference: the `GET|POST /epochs/participation/history` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "voteKey",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Vote account or node identity (base58); either kind is accepted."
     },
     {
      "name": "epoch",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /epochs/participation/history` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postEpochsParticipationHistory",
    "tags": [
     "Alpenglow"
    ],
    "summary": "Its per-slot timeline",
    "description": "The POST form of `GET /epochs/participation/history`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": true,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "voteKey": {
          "type": "string",
          "description": "Vote account or node identity (base58); either kind is accepted."
         },
         "epoch": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0
         }
        },
        "required": [
         "voteKey"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /epochs/participation/history` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/alpenglow/rank-map": {
   "get": {
    "operationId": "getAlpenglowRankMap",
    "tags": [
     "Alpenglow"
    ],
    "summary": "An epoch's BLS rank map",
    "description": "The per-epoch validator ordering that Alpenglow certificate bitmaps index: rank → vote account, node identity, stake, BLS key. Built from the frozen stake set the runtime fixes at the first slot of the previous epoch (our validators serve it over the fork RPC method getEpochStakes); verified against real certificates before the ingestor attributes anything with it. Also the authoritative \"admitted\" list and why the others are not.\n\nFull reference: the `GET|POST /alpenglow/rank-map` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "epoch",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /alpenglow/rank-map` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postAlpenglowRankMap",
    "tags": [
     "Alpenglow"
    ],
    "summary": "An epoch's BLS rank map",
    "description": "The POST form of `GET /alpenglow/rank-map`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "epoch": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /alpenglow/rank-map` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/slots/footer": {
   "get": {
    "operationId": "getSlotsFooter",
    "tags": [
     "Alpenglow"
    ],
    "summary": "One block footer with its certificates",
    "description": "One block's footer, decoded, with the raw material to re-verify every claim. The footer in block S carries the reward certificates for slot S − 8 (who notarized, who skipped) and the highest finalization certificate the leader knew. \"Did my vote land in slot N?\" is this endpoint for slot N + 8.\n\nFull reference: the `GET|POST /slots/footer` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "slot",
      "in": "query",
      "required": true,
      "schema": {
       "type": "integer",
       "minimum": 0
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /slots/footer` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postSlotsFooter",
    "tags": [
     "Alpenglow"
    ],
    "summary": "One block footer with its certificates",
    "description": "The POST form of `GET /slots/footer`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": true,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "slot": {
          "type": "integer",
          "minimum": 0
         }
        },
        "required": [
         "slot"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /slots/footer` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/slots": {
   "get": {
    "operationId": "getSlots",
    "tags": [
     "Alpenglow"
    ],
    "summary": "What happened on each slot of a range",
    "description": "What happened on each slot of a range (or of a list of slots, `slots`), keyed by the slot it describes (no +8 arithmetic): the outcome, the leader, the votes on it, its own footer, and when it was finalized. One item per slot that has a stored row, skipped slots included; a slot not ingested yet has no item. ~400 bytes per slot; /slots/footer has the full certificate proof for one.\n\nFull reference: the `GET|POST /slots` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "startSlot",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "The range form, with endSlot: inclusive, at most 1000 slots."
     },
     {
      "name": "endSlot",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      }
     },
     {
      "name": "slots",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "The list form, instead of startSlot/endSlot: comma-separated slots (a JSON array in a POST body), at most 500 distinct, in any order. Same items, ascending; startSlot/endSlot in the response are the lowest and highest asked for."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /slots` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postSlots",
    "tags": [
     "Alpenglow"
    ],
    "summary": "What happened on each slot of a range",
    "description": "The POST form of `GET /slots`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": true,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "startSlot": {
          "type": "integer",
          "minimum": 0
         },
         "endSlot": {
          "type": "integer",
          "minimum": 0
         }
        },
        "required": [
         "startSlot",
         "endSlot"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /slots` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/slot": {
   "get": {
    "operationId": "getSlot",
    "tags": [
     "Alpenglow"
    ],
    "summary": "Everything about one slot",
    "description": "Everything about one slot in one call, Tower or Alpenglow: the explorer's slot page.\n\nFull reference: the `GET|POST /slot` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "slot",
      "in": "query",
      "required": true,
      "schema": {
       "type": "integer",
       "minimum": 0
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Slot"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postSlot",
    "tags": [
     "Alpenglow"
    ],
    "summary": "Everything about one slot",
    "description": "The POST form of `GET /slot`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": true,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "slot": {
          "type": "integer",
          "minimum": 0
         }
        },
        "required": [
         "slot"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Slot"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/epochs/producers": {
   "get": {
    "operationId": "getEpochsProducers",
    "tags": [
     "Alpenglow"
    ],
    "summary": "Every producer's window record",
    "description": "Every block producer's record in an Alpenglow epoch so far (each node the leader schedule names): how its 4-slot windows went, its blocks' finalization lag, when it leads next. Worst first (most windows with skips). E.g. a producer that is offline shows skippedWindows == windows. \"Leader\" in this API is the protocol's schedule (`leader` fields name the scheduled node); \"producer\" is how that node did at producing blocks. Ranked, with rewards and vote inclusion: /epochs/leaderboard/producers.\n\nFull reference: the `GET|POST /epochs/producers` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "epoch",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      }
     },
     {
      "name": "producer",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "One producer (node identity)."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /epochs/producers` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postEpochsProducers",
    "tags": [
     "Alpenglow"
    ],
    "summary": "Every producer's window record",
    "description": "The POST form of `GET /epochs/producers`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "epoch": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0
         },
         "producer": {
          "type": [
           "string",
           "null"
          ],
          "description": "One producer (node identity)."
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /epochs/producers` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/epochs/leaderboard/producers": {
   "get": {
    "operationId": "getEpochsLeaderboardProducers",
    "tags": [
     "Leaderboards"
    ],
    "summary": "Alpenglow block production",
    "description": "Block-producer leaderboard for one Alpenglow epoch: every node the leader schedule names, with its /epochs/producers window record, what its blocks did for consensus and rewards, and the cohort fields of the participation leaderboard. (Tower epochs have no such data: 404 without a stored leader schedule; the Tower view of block production is /epochs/leaderboard/income.) Responses are cached 15 s per (epoch, sortBy, order, minLeaderSlots), and 10 min once the epoch is ingested through its last slot.\n\nFull reference: the `GET|POST /epochs/leaderboard/producers` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "epoch",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      }
     },
     {
      "name": "sortBy",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "enum": [
        "effectiveInclusion",
        "skipRate",
        "inclusion",
        "bonus",
        "finalizationLag",
        "stake",
        "availableInclusion",
        "scoredInclusion"
       ]
      }
     },
     {
      "name": "order",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "enum": [
        "asc",
        "desc"
       ]
      }
     },
     {
      "name": "minLeaderSlots",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Rank only producers with at least this many payable leader slots (default 0: everyone)."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ProducerLeaderboard"
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postEpochsLeaderboardProducers",
    "tags": [
     "Leaderboards"
    ],
    "summary": "Alpenglow block production",
    "description": "The POST form of `GET /epochs/leaderboard/producers`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "epoch": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0
         },
         "sortBy": {
          "type": [
           "string",
           "null"
          ],
          "enum": [
           "effectiveInclusion",
           "skipRate",
           "inclusion",
           "bonus",
           "finalizationLag",
           "stake",
           "availableInclusion",
           "scoredInclusion",
           null
          ]
         },
         "order": {
          "type": [
           "string",
           "null"
          ],
          "enum": [
           "asc",
           "desc",
           null
          ]
         },
         "minLeaderSlots": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "Rank only producers with at least this many payable leader slots (default 0: everyone)."
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ProducerLeaderboard"
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/epochs/participation/misses": {
   "get": {
    "operationId": "getEpochsParticipationMisses",
    "tags": [
     "Alpenglow"
    ],
    "summary": "Its misses by cause and producer",
    "description": "One validator's missed slots in one epoch, by the producer whose block carried (or should have carried) its votes: which producers' thin blocks cost it, and where its own votes did not get in.\n\nFull reference: the `GET|POST /epochs/participation/misses` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "voteKey",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Vote account or node identity (base58); either kind is accepted."
     },
     {
      "name": "epoch",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /epochs/participation/misses` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postEpochsParticipationMisses",
    "tags": [
     "Alpenglow"
    ],
    "summary": "Its misses by cause and producer",
    "description": "The POST form of `GET /epochs/participation/misses`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": true,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "voteKey": {
          "type": "string",
          "description": "Vote account or node identity (base58); either kind is accepted."
         },
         "epoch": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0
         }
        },
        "required": [
         "voteKey"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /epochs/participation/misses` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/epochs/production/omissions": {
   "get": {
    "operationId": "getEpochsProductionOmissions",
    "tags": [
     "Alpenglow"
    ],
    "summary": "Voters its blocks left out",
    "description": "One producer's reward certificates seen from the voters' side: every voter its blocks left out in an epoch (offline stretches aside), with missed and eligible slots, the thin-block / late split and stake, most missed first (ties by stake), paged, with the classification's thresholds and completeness. The producer-side counterpart of /epochs/participation/misses, below the blackhole threshold too.\n\nFull reference: the `GET|POST /epochs/production/omissions` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "voteKey",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Vote account or node identity (base58); either kind is accepted."
     },
     {
      "name": "epoch",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      }
     },
     {
      "name": "minMissed",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Only voters left out at least this many slots (default 1)."
     },
     {
      "name": "limit",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Page size of the listed voters (default all)."
     },
     {
      "name": "offset",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Listed voters to skip (default 0)."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /epochs/production/omissions` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postEpochsProductionOmissions",
    "tags": [
     "Alpenglow"
    ],
    "summary": "Voters its blocks left out",
    "description": "The POST form of `GET /epochs/production/omissions`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": true,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "voteKey": {
          "type": "string",
          "description": "Vote account or node identity (base58); either kind is accepted."
         },
         "epoch": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0
         },
         "minMissed": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "Only voters left out at least this many slots (default 1)."
         },
         "limit": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "Page size of the listed voters (default all)."
         },
         "offset": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "Listed voters to skip (default 0)."
         }
        },
        "required": [
         "voteKey"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /epochs/production/omissions` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/epochs/production": {
   "get": {
    "operationId": "getEpochsProduction",
    "tags": [
     "Alpenglow"
    ],
    "summary": "One producer's record per epoch",
    "description": "One validator's producer record per Alpenglow epoch, newest first: its row of /epochs/leaderboard/producers at the default sort (effectiveInclusion), so rank is the board's rank. For a production table next to /epochs/participation.\n\nFull reference: the `GET|POST /epochs/production` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "voteKey",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Vote account or node identity."
     },
     {
      "name": "limit",
      "in": "query",
      "required": true,
      "schema": {
       "type": "integer",
       "minimum": 0
      }
     },
     {
      "name": "minLeaderSlots",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "As on the leaderboard: rank only producers with at least this many payable leader slots (default 0)."
     },
     {
      "name": "sortBy",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "enum": [
        "effectiveInclusion",
        "skipRate",
        "inclusion",
        "bonus",
        "finalizationLag",
        "stake",
        "availableInclusion",
        "scoredInclusion"
       ]
      },
      "description": "What `rank` ranks by, as on the leaderboard (default `effectiveInclusion`, in its default order)."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ProductionItems"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postEpochsProduction",
    "tags": [
     "Alpenglow"
    ],
    "summary": "One producer's record per epoch",
    "description": "The POST form of `GET /epochs/production`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": true,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "voteKey": {
          "type": "string",
          "description": "Vote account or node identity."
         },
         "limit": {
          "type": "integer",
          "minimum": 0
         },
         "minLeaderSlots": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "As on the leaderboard: rank only producers with at least this many payable leader slots (default 0)."
         },
         "sortBy": {
          "type": [
           "string",
           "null"
          ],
          "enum": [
           "effectiveInclusion",
           "skipRate",
           "inclusion",
           "bonus",
           "finalizationLag",
           "stake",
           "availableInclusion",
           "scoredInclusion",
           null
          ],
          "description": "What `rank` ranks by, as on the leaderboard (default `effectiveInclusion`, in its default order)."
         }
        },
        "required": [
         "voteKey",
         "limit"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ProductionItems"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/epochs/production/windows": {
   "get": {
    "operationId": "getEpochsProductionWindows",
    "tags": [
     "Alpenglow"
    ],
    "summary": "Its leader windows, slot by slot",
    "description": "One validator's leader windows in one epoch, slot by slot: whether it produced, and the stake its block carried in reward certificates.\n\nFull reference: the `GET|POST /epochs/production/windows` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "voteKey",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Vote account or node identity."
     },
     {
      "name": "epoch",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      }
     },
     {
      "name": "limit",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Paging: played windows only, newest first, at most this many (1..=200; default 20 when `beforeSlot` or `issues` is given)."
     },
     {
      "name": "beforeSlot",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Paging: windows whose first slot is before this one."
     },
     {
      "name": "issues",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "enum": [
        "true",
        "false",
        "skipped",
        "poor"
       ]
      },
      "description": "Paging: `true` = windows with a skipped slot or a thin block, `skipped` / `poor` = only those with a skipped slot / a thin block, `false` = every played window."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ProductionWindows"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postEpochsProductionWindows",
    "tags": [
     "Alpenglow"
    ],
    "summary": "Its leader windows, slot by slot",
    "description": "The POST form of `GET /epochs/production/windows`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": true,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "voteKey": {
          "type": "string",
          "description": "Vote account or node identity."
         },
         "epoch": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0
         },
         "limit": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "Paging: played windows only, newest first, at most this many (1..=200; default 20 when `beforeSlot` or `issues` is given)."
         },
         "beforeSlot": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "Paging: windows whose first slot is before this one."
         },
         "issues": {
          "oneOf": [
           {
            "oneOf": [
             {
              "type": "boolean"
             },
             {
              "type": "string",
              "enum": [
               "skipped",
               "poor"
              ]
             }
            ]
           },
           {
            "type": "null"
           }
          ],
          "description": "Paging: `true` = windows with a skipped slot or a thin block, `skipped` / `poor` = only those with a skipped slot / a thin block, `false` = every played window."
         }
        },
        "required": [
         "voteKey"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ProductionWindows"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/consensus/live": {
   "get": {
    "operationId": "getConsensusLive",
    "tags": [
     "Alpenglow"
    ],
    "summary": "Slots in flight on our nodes",
    "description": "What consensus is doing right now, from our validators' vote pools (every node that may hold the staked identity, polled every second and merged by the consensus observer), including slots that never finalize. Use it to watch a slowdown or stall as it happens: who has not voted on an in-flight slot, votes split between block versions, certificates forming late. Everything else in this API is built from finalized blocks.\n\nFull reference: the `GET|POST /consensus/live` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "limit",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Most recent slots to return (default 32, max 256)."
     },
     {
      "name": "slot",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "One slot in detail: every validator that has not voted, bitmaps."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /consensus/live` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postConsensusLive",
    "tags": [
     "Alpenglow"
    ],
    "summary": "Slots in flight on our nodes",
    "description": "The POST form of `GET /consensus/live`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "limit": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "Most recent slots to return (default 32, max 256)."
         },
         "slot": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "One slot in detail: every validator that has not voted, bitmaps."
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /consensus/live` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/consensus/validator/live": {
   "get": {
    "operationId": "getConsensusValidatorLive",
    "tags": [
     "Alpenglow"
    ],
    "summary": "One validator's live votes",
    "description": "One validator's vote on each recent slot, for a live strip on its page: in flight from our nodes' vote pools, then final from the slot's reward certificates (the footer of block slot + 8, what vote rewards and the producer bonus pay on). States only, no timing. Built once per second for every validator together, so polling every second per viewer is cheap.\n\nCache-Control: public, max-age=1.\n\nFull reference: the `GET|POST /consensus/validator/live` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "voteKey",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Vote account or node identity."
     },
     {
      "name": "sinceSlot",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Rows for slots after this one. Pass the previous response's `finalThroughSlot`: rows after it can still change."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /consensus/validator/live` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postConsensusValidatorLive",
    "tags": [
     "Alpenglow"
    ],
    "summary": "One validator's live votes",
    "description": "The POST form of `GET /consensus/validator/live`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": true,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "voteKey": {
          "type": "string",
          "description": "Vote account or node identity."
         },
         "sinceSlot": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "Rows for slots after this one. Pass the previous response's `finalThroughSlot`: rows after it can still change."
         }
        },
        "required": [
         "voteKey"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /consensus/validator/live` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/epochs/cluster/history": {
   "get": {
    "operationId": "getEpochsClusterHistory",
    "tags": [
     "Alpenglow"
    ],
    "summary": "The chain's per-slot outcome timeline",
    "description": "What the chain did on every slot of an Alpenglow epoch, aligned slot for slot with /epochs/participation/history (same firstSlot, same packing), so one call per epoch serves every validator page. Responses are cached 10 s per epoch, 10 min once the epoch is ingested through its last slot (`lastIngestedSlot` says how far the answer runs).\n\nFull reference: the `GET|POST /epochs/cluster/history` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "epoch",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /epochs/cluster/history` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postEpochsClusterHistory",
    "tags": [
     "Alpenglow"
    ],
    "summary": "The chain's per-slot outcome timeline",
    "description": "The POST form of `GET /epochs/cluster/history`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "epoch": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /epochs/cluster/history` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/validators/delegators": {
   "get": {
    "operationId": "getValidatorsDelegators",
    "tags": [
     "Validators (history)"
    ],
    "summary": "Whole delegator set at an epoch's end",
    "description": "Everyone staking to one validator at the end of an epoch: how many delegators, the largest, and how stake is spread by delegator size and kind. Same source and delegator definition as /validators/stake-changes. A pool's `directedStake` and `directedSources` are capped to its stake here, as on /pool (`directedCapped`).\n\nFull reference: the `GET|POST /validators/delegators` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "identity",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
     },
     {
      "name": "voteKey",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Vote account or node identity (base58); either kind is accepted."
     },
     {
      "name": "epoch",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Default: the latest epoch with a set."
     },
     {
      "name": "limit",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Top delegators listed, 1..=100; default 25."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /validators/delegators` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postValidatorsDelegators",
    "tags": [
     "Validators (history)"
    ],
    "summary": "Whole delegator set at an epoch's end",
    "description": "The POST form of `GET /validators/delegators`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "identity": {
          "type": [
           "string",
           "null"
          ],
          "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
         },
         "voteKey": {
          "type": [
           "string",
           "null"
          ],
          "description": "Vote account or node identity (base58); either kind is accepted."
         },
         "epoch": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "Default: the latest epoch with a set."
         },
         "limit": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "Top delegators listed, 1..=100; default 25."
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /validators/delegators` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/validators/stake-changes": {
   "get": {
    "operationId": "getValidatorsStakeChanges",
    "tags": [
     "Validators (history)"
    ],
    "summary": "Who started or stopped staking, per epoch",
    "description": "Who started or stopped staking to one validator, epoch by epoch, oldest first. Epoch E compares the vote account's effective stake at the end of E-1 with the end of E, by delegator (a stake account's withdraw authority), with reward compounding removed.\n\nFull reference: the `GET|POST /validators/stake-changes` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "identity",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
     },
     {
      "name": "voteKey",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Vote account or node identity (base58); either kind is accepted."
     },
     {
      "name": "limit",
      "in": "query",
      "required": true,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Epochs back from the current one, 1..=50."
     },
     {
      "name": "maxChanges",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Delegator changes per epoch, largest first; default 50."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "type": "object"
         },
         "description": "Shape: see the `GET|POST /validators/stake-changes` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postValidatorsStakeChanges",
    "tags": [
     "Validators (history)"
    ],
    "summary": "Who started or stopped staking, per epoch",
    "description": "The POST form of `GET /validators/stake-changes`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": true,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "identity": {
          "type": [
           "string",
           "null"
          ],
          "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
         },
         "voteKey": {
          "type": [
           "string",
           "null"
          ],
          "description": "Vote account or node identity (base58); either kind is accepted."
         },
         "limit": {
          "type": "integer",
          "minimum": 0,
          "description": "Epochs back from the current one, 1..=50."
         },
         "maxChanges": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "Delegator changes per epoch, largest first; default 50."
         }
        },
        "required": [
         "limit"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "type": "object"
         },
         "description": "Shape: see the `GET|POST /validators/stake-changes` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/validators/pace": {
   "get": {
    "operationId": "getValidatorsPace",
    "tags": [
     "Validators (history)"
    ],
    "summary": "Slot pace per epoch, against the cluster and the physical floor",
    "description": "One validator's slot pace per Alpenglow epoch, newest first, beside the cluster's: its in-window block times, its handoffs (received: the previous leader's last block to its first) and outgoing handoffs (the next leader's first block after its last), each overall and by continent group against the great-circle fibre floor, as /epochs/leaderboard/producers serves them, without one board request per epoch. Chain-derived producer timestamps only.\n\nFull reference: the `GET|POST /validators/pace` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "identity",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
     },
     {
      "name": "voteKey",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Vote account or node identity (base58); either kind is accepted."
     },
     {
      "name": "limit",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Epochs back, the current one included: 1..=50; default 30. Epochs not classified are left out."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ValidatorPace"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postValidatorsPace",
    "tags": [
     "Validators (history)"
    ],
    "summary": "Slot pace per epoch, against the cluster and the physical floor",
    "description": "The POST form of `GET /validators/pace`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": true,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "identity": {
          "type": [
           "string",
           "null"
          ],
          "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
         },
         "voteKey": {
          "type": [
           "string",
           "null"
          ],
          "description": "Vote account or node identity (base58); either kind is accepted."
         },
         "limit": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "Epochs back, the current one included: 1..=50; default 30."
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ValidatorPace"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/validators/tips": {
   "get": {
    "operationId": "getValidatorsTips",
    "tags": [
     "Validators (history)"
    ],
    "summary": "Tip income by tip path, per epoch",
    "description": "One validator's tip income per epoch, newest first, by tip path (Jito tips, Jito priority-fee sharing, Jito's BAM Boost in JitoSOL with its claim state, and the builder paths that cannot be measured: Harmonic, Paladin P3, Rakurai, Raiku), with how each was split between the block builder, Jito's tip router, the validator and its stakers.\n\nFull reference: the `GET|POST /validators/tips` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "identity",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
     },
     {
      "name": "voteKey",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Vote account or node identity (base58); either kind is accepted."
     },
     {
      "name": "limit",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Epochs back, the current one included: 1..=50; default 10."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ValidatorTips"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postValidatorsTips",
    "tags": [
     "Validators (history)"
    ],
    "summary": "Tip income by tip path, per epoch",
    "description": "The POST form of `GET /validators/tips`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": true,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "identity": {
          "type": [
           "string",
           "null"
          ],
          "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
         },
         "voteKey": {
          "type": [
           "string",
           "null"
          ],
          "description": "Vote account or node identity (base58); either kind is accepted."
         },
         "limit": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "Epochs back, the current one included: 1..=50; default 10."
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ValidatorTips"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/validators/tips/blocks": {
   "get": {
    "operationId": "getValidatorsTipsBlocks",
    "tags": [
     "Validators (history)"
    ],
    "summary": "One epoch's blocks with their tips",
    "description": "One validator's produced blocks in one epoch with their Jito tips, priority fees and base fees, and the epoch's block builder: the drill-down of a /validators/tips row.\n\nFull reference: the `GET|POST /validators/tips/blocks` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "identity",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
     },
     {
      "name": "voteKey",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Vote account or node identity (base58); either kind is accepted."
     },
     {
      "name": "epoch",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Default: the current epoch."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ValidatorTipBlocks"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postValidatorsTipsBlocks",
    "tags": [
     "Validators (history)"
    ],
    "summary": "One epoch's blocks with their tips",
    "description": "The POST form of `GET /validators/tips/blocks`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": true,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "identity": {
          "type": [
           "string",
           "null"
          ],
          "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
         },
         "voteKey": {
          "type": [
           "string",
           "null"
          ],
          "description": "Vote account or node identity (base58); either kind is accepted."
         },
         "epoch": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "Default: the current epoch."
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ValidatorTipBlocks"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/pools": {
   "get": {
    "operationId": "getPools",
    "tags": [
     "Stake pools"
    ],
    "summary": "Every known stake pool's stake and validator count at an epoch's end",
    "description": "Every known stake pool (and Marinade, and the Solana Foundation Delegation Program) at the end of an epoch: how much stake it holds and on how many validators, with the epoch before for comparison. Same source as /validators/stake-changes `pools`, read pool by pool. A pool's `directed` sums count each validator's allocations capped to the pool's holding there (`cappedValidators`), so they never exceed its stake.\n\nFull reference: the `GET|POST /pools` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "epoch",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Default: the latest epoch with a pool row."
     },
     {
      "name": "all",
      "in": "query",
      "required": false,
      "schema": {
       "type": "boolean"
      },
      "description": "Also list pools delegating to no validator (every holding at or below the cutoff): dust and test pools, by default left out."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /pools` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postPools",
    "tags": [
     "Stake pools"
    ],
    "summary": "Every known stake pool's stake and validator count at an epoch's end",
    "description": "The POST form of `GET /pools`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "epoch": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "Default: the latest epoch with a pool row."
         },
         "all": {
          "type": [
           "boolean",
           "null"
          ],
          "description": "Also list pools delegating to no validator (every holding at or below the cutoff): dust and test pools, by default left out."
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /pools` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/pool": {
   "get": {
    "operationId": "getPool",
    "tags": [
     "Stake pools"
    ],
    "summary": "One pool's validators, and who it added, dropped or moved stake on",
    "description": "One stake pool at the end of an epoch: every validator it stakes to, and over the epochs before, which validators it added, dropped, or moved stake on. A renamed pool is found by its former names too (`formerNames`), and answered under its current `name`. Directed allocations are capped to the pool's holding on each validator: `directedSources[].lamports` is the capped share, `sourceLamports` the source's figure, `directedCapped` whether it was capped.\n\nFull reference: the `GET|POST /pool` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "name",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "A pool name (`JitoSOL`, `mSOL`, `SFDP`; case-insensitive when unambiguous), a former name it is still found by (`formerNames`, e.g. `Marinade (mSOL)`), or an authority address."
     },
     {
      "name": "epoch",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Default: the latest epoch with a pool row."
     },
     {
      "name": "limit",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Epochs of history, 1..=50; default 10."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /pool` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postPool",
    "tags": [
     "Stake pools"
    ],
    "summary": "One pool's validators, and who it added, dropped or moved stake on",
    "description": "The POST form of `GET /pool`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": [
           "string",
           "null"
          ],
          "description": "A pool name (`JitoSOL`, `mSOL`, `SFDP`; case-insensitive when unambiguous), a former name it is still found by (`formerNames`, e.g. `Marinade (mSOL)`), or an authority address."
         },
         "epoch": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "Default: the latest epoch with a pool row."
         },
         "limit": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "Epochs of history, 1..=50; default 10."
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /pool` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/cluster/geo-history": {
   "get": {
    "operationId": "getClusterGeoHistory",
    "tags": [
     "Cluster"
    ],
    "summary": "Stake concentration per epoch",
    "description": "How concentrated stake was, epoch by epoch: by country, continent, provider (ASN) and data center, with concentration measures for each. Built from each epoch's effective stake and the gossip address recorded for the epoch (as /validators/geo?epoch=E), so a past epoch reads the same whenever it is asked for. Kept warm server-side; past epochs are rebuilt daily, the current one every 10 min (all 600 epochs).\n\nFull reference: the `GET|POST /cluster/geo-history` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "epochs",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Epochs back from the current one, current included; 1..=600, default 50. Ignored when `fromEpoch` is set."
     },
     {
      "name": "fromEpoch",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "First epoch, inclusive; with `toEpoch` (default current) at most 600 epochs."
     },
     {
      "name": "toEpoch",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      }
     },
     {
      "name": "top",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Entries listed per breakdown, largest first; default 10."
     },
     {
      "name": "breakdowns",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Comma-separated subset of `BREAKDOWNS`; default all."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /cluster/geo-history` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postClusterGeoHistory",
    "tags": [
     "Cluster"
    ],
    "summary": "Stake concentration per epoch",
    "description": "The POST form of `GET /cluster/geo-history`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "epochs": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "Epochs back from the current one, current included; 1..=600, default 50. Ignored when `fromEpoch` is set."
         },
         "fromEpoch": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "First epoch, inclusive; with `toEpoch` (default current) at most 600 epochs."
         },
         "toEpoch": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0
         },
         "top": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "Entries listed per breakdown, largest first; default 10."
         },
         "breakdowns": {
          "type": [
           "string",
           "null"
          ],
          "description": "Comma-separated subset of `BREAKDOWNS`; default all."
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /cluster/geo-history` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/cluster/clients": {
   "get": {
    "operationId": "getClusterClients",
    "tags": [
     "Cluster"
    ],
    "summary": "An epoch's metrics by client and version, optionally by location",
    "description": "One epoch's voting, production and income metrics summed by the client (and optionally version) each validator ran in it, optionally cut by where it ran: the client comparison, including the same-datacenter one (`by=datacenter&mixedOnly=true`).\n\nFull reference: the `GET|POST /cluster/clients` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "epoch",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      }
     },
     {
      "name": "by",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "enum": [
        "none",
        "continent",
        "country",
        "provider",
        "datacenter"
       ]
      }
     },
     {
      "name": "versions",
      "in": "query",
      "required": false,
      "schema": {
       "type": "boolean"
      },
      "description": "Split each client by version (default false)."
     },
     {
      "name": "mixedOnly",
      "in": "query",
      "required": false,
      "schema": {
       "type": "boolean"
      },
      "description": "With `by`: only locations where validators ran more than one client."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /cluster/clients` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postClusterClients",
    "tags": [
     "Cluster"
    ],
    "summary": "An epoch's metrics by client and version, optionally by location",
    "description": "The POST form of `GET /cluster/clients`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "epoch": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0
         },
         "by": {
          "type": [
           "string",
           "null"
          ],
          "enum": [
           "none",
           "continent",
           "country",
           "provider",
           "datacenter",
           null
          ]
         },
         "versions": {
          "type": [
           "boolean",
           "null"
          ],
          "description": "Split each client by version (default false)."
         },
         "mixedOnly": {
          "type": [
           "boolean",
           "null"
          ],
          "description": "With `by`: only locations where validators ran more than one client."
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /cluster/clients` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/cluster/block-builders": {
   "get": {
    "operationId": "getClusterBlockBuilders",
    "tags": [
     "Cluster"
    ],
    "summary": "An epoch's stake, leader slots and block income by block builder",
    "description": "One epoch's validators, leader slots and block income summed by the block builder each validator used: Jito BAM, the Jito Block Engine, Harmonic, Rakurai, Paladin, Raiku, or none.\n\nFull reference: the `GET|POST /cluster/block-builders` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "epoch",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /cluster/block-builders` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postClusterBlockBuilders",
    "tags": [
     "Cluster"
    ],
    "summary": "An epoch's stake, leader slots and block income by block builder",
    "description": "The POST form of `GET /cluster/block-builders`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "epoch": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /cluster/block-builders` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/cluster/doublezero": {
   "get": {
    "operationId": "getClusterDoublezero",
    "tags": [
     "Cluster"
    ],
    "summary": "Validators connected to DoubleZero, by device and metro (mainnet)",
    "description": "The cluster's validators on DoubleZero (DZ): how many and how much stake are connected, tied by declared key or gossip address, and each device and metro with its validators. From DZ's own ledger, read every 5 minutes; only activated users count. Mainnet only: 404 on testnet, 503 until the snapshot is first read. Cache-Control: public, max-age=60, stale-while-revalidate=120.\n\nFull reference: the `GET|POST /cluster/doublezero` section of https://api.vx.tools/llms.txt.",
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /cluster/doublezero` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postClusterDoublezero",
    "tags": [
     "Cluster"
    ],
    "summary": "Validators connected to DoubleZero, by device and metro (mainnet)",
    "description": "The POST form of `GET /cluster/doublezero`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "No fields; an empty body or `{}`.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {}
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /cluster/doublezero` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/cluster/versions": {
   "get": {
    "operationId": "getClusterVersions",
    "tags": [
     "Cluster"
    ],
    "summary": "Client versions per epoch, who changed",
    "description": "Which client and version staked validators ran, epoch by epoch, and who changed. A completed epoch uses each validator's effective stake and the client and version recorded for it: gossip's at the epoch's end (em.gver / gcid, from mainnet epoch 1066) where recorded, else ValidatorHistory's (em.cid / cver); every version says which (versionSource). Its changes are the validators whose record differs from the epoch before's. The epoch in progress uses gossip now, and its changes come from the software events the chain-state writer saw this epoch (as /validators/host-changes events), with the time each was seen. Kept warm server-side for the default 10 epochs: older epochs are rebuilt daily, the last completed one hourly (its records are still being rewritten), the current one every 2 min.\n\nFull reference: the `GET|POST /cluster/versions` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "epochs",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Epochs back from the current one, current included; 1..=50, default 10."
     },
     {
      "name": "top",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Changes listed per epoch, largest stake first; default 20, at most 1000. `transitions` always counts them all."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /cluster/versions` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postClusterVersions",
    "tags": [
     "Cluster"
    ],
    "summary": "Client versions per epoch, who changed",
    "description": "The POST form of `GET /cluster/versions`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "epochs": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "Epochs back from the current one, current included; 1..=50, default 10."
         },
         "top": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "Changes listed per epoch, largest stake first; default 20, at most 1000. `transitions` always counts them all."
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /cluster/versions` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/cluster/versions/timeline": {
   "get": {
    "operationId": "getClusterVersionsTimeline",
    "tags": [
     "Cluster"
    ],
    "summary": "Stake by family and version inside epochs",
    "description": "Stake by client family and version over time, at points inside the epoch, for following a rollout as it happens. Each point is rebuilt backwards from what each staked validator runs in gossip now, undoing the software events the chain-state writer recorded after it (as /validators/host-changes events); a validator out of gossip now with no later event takes gossip's record of its epoch's end (em.gver), which is what it ran from its last event on. Versions are always gossip's. The epoch in progress refreshes every 2 min; kept warm server-side.\n\nFull reference: the `GET|POST /cluster/versions/timeline` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "epochs",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Epochs back from the current one, current included; 1..=3, default 1."
     },
     {
      "name": "bucketMins",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Minutes between points; 10..=1440, default 60."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /cluster/versions/timeline` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postClusterVersionsTimeline",
    "tags": [
     "Cluster"
    ],
    "summary": "Stake by family and version inside epochs",
    "description": "The POST form of `GET /cluster/versions/timeline`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "epochs": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "Epochs back from the current one, current included; 1..=3, default 1."
         },
         "bucketMins": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "Minutes between points; 10..=1440, default 60."
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /cluster/versions/timeline` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/validators/host-changes": {
   "get": {
    "operationId": "getValidatorsHostChanges",
    "tags": [
     "Validators (history)"
    ],
    "summary": "Migrations and failovers",
    "description": "Where one validator ran, two ways: epoch-level migrations from the gossip address recorded per epoch (mainnet: ValidatorHistory, ~500 epochs back), and minute-level events (failovers, migrations, software changes) from our chain-state writer, from when it started recording.\n\nFull reference: the `GET|POST /validators/host-changes` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "identity",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
     },
     {
      "name": "voteKey",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Vote account or node identity (base58); either kind is accepted."
     },
     {
      "name": "limit",
      "in": "query",
      "required": true,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Epochs back from the current one, 1..=512."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /validators/host-changes` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postValidatorsHostChanges",
    "tags": [
     "Validators (history)"
    ],
    "summary": "Migrations and failovers",
    "description": "The POST form of `GET /validators/host-changes`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": true,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "identity": {
          "type": [
           "string",
           "null"
          ],
          "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
         },
         "voteKey": {
          "type": [
           "string",
           "null"
          ],
          "description": "Vote account or node identity (base58); either kind is accepted."
         },
         "limit": {
          "type": "integer",
          "minimum": 0,
          "description": "Epochs back from the current one, 1..=512."
         }
        },
        "required": [
         "limit"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /validators/host-changes` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/validators/doublezero": {
   "get": {
    "operationId": "getValidatorsDoublezero",
    "tags": [
     "Validators (history)"
    ],
    "summary": "Its DoubleZero connections now and every change to them (mainnet)",
    "description": "One validator's DoubleZero (DZ) connections: the DZ users tied to its identity now (as /validators/status doubleZero), and every change to them (connected, disconnected, moved device, changed type or status) seen between two reads of DZ's ledger, every 5 minutes, from when recording started. Client addresses are not served. Mainnet only: 404 on testnet, 503 until the snapshot is first read.\n\nFull reference: the `GET|POST /validators/doublezero` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "identity",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
     },
     {
      "name": "voteKey",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Vote account or node identity (base58); either kind is accepted."
     },
     {
      "name": "limit",
      "in": "query",
      "required": true,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Epochs back from the current one, 1..=512."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /validators/doublezero` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postValidatorsDoublezero",
    "tags": [
     "Validators (history)"
    ],
    "summary": "Its DoubleZero connections now and every change to them (mainnet)",
    "description": "The POST form of `GET /validators/doublezero`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": true,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "identity": {
          "type": [
           "string",
           "null"
          ],
          "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
         },
         "voteKey": {
          "type": [
           "string",
           "null"
          ],
          "description": "Vote account or node identity (base58); either kind is accepted."
         },
         "limit": {
          "type": "integer",
          "minimum": 0,
          "description": "Epochs back from the current one, 1..=512."
         }
        },
        "required": [
         "limit"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /validators/doublezero` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/validators/vote-account-changes": {
   "get": {
    "operationId": "getValidatorsVoteAccountChanges",
    "tags": [
     "Validators (history)"
    ],
    "summary": "Who changed its vote account (withdrawer, voter, identity, commission, collectors) or withdrew",
    "description": "Administrative changes to one validator's vote account, oldest first: who changed its withdrawer, authorized voter (and BLS key), node identity, commission or collectors, who withdrew from it, and its creation. From the vote-program instructions of successful transactions, top level or run by another program (a multisig); since mainnet's Alpenglow cutover (epoch 1064) only.\n\nFull reference: the `GET|POST /validators/vote-account-changes` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "identity",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
     },
     {
      "name": "voteKey",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Vote account or node identity (base58); either kind is accepted."
     },
     {
      "name": "limit",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Epochs back from the current one, 1..=128."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /validators/vote-account-changes` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postValidatorsVoteAccountChanges",
    "tags": [
     "Validators (history)"
    ],
    "summary": "Who changed its vote account (withdrawer, voter, identity, commission, collectors) or withdrew",
    "description": "The POST form of `GET /validators/vote-account-changes`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "identity": {
          "type": [
           "string",
           "null"
          ],
          "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
         },
         "voteKey": {
          "type": [
           "string",
           "null"
          ],
          "description": "Vote account or node identity (base58); either kind is accepted."
         },
         "limit": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "Epochs back from the current one, 1..=128."
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /validators/vote-account-changes` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/cluster/vote-account-changes": {
   "get": {
    "operationId": "getClusterVoteAccountChanges",
    "tags": [
     "Cluster"
    ],
    "summary": "Every vote account's changes, by kind or validator",
    "description": "Every vote account's administrative changes in one epoch or the last few, newest first, optionally only some kinds or one validator: the events of /validators/vote-account-changes across the cluster, with who the vote account belongs to now.\n\nFull reference: the `GET|POST /cluster/vote-account-changes` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "epoch",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "One epoch; otherwise the last `epochs`."
     },
     {
      "name": "epochs",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Epochs up to the current one, 1..=10, default 3."
     },
     {
      "name": "kind",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Comma-separated kinds to keep."
     },
     {
      "name": "voteKey",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "One vote account (or its identity) only."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /cluster/vote-account-changes` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postClusterVoteAccountChanges",
    "tags": [
     "Cluster"
    ],
    "summary": "Every vote account's changes, by kind or validator",
    "description": "The POST form of `GET /cluster/vote-account-changes`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "epoch": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "One epoch; otherwise the last `epochs`."
         },
         "epochs": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "Epochs up to the current one, 1..=10, default 3."
         },
         "kind": {
          "type": [
           "string",
           "null"
          ],
          "description": "Comma-separated kinds to keep."
         },
         "voteKey": {
          "type": [
           "string",
           "null"
          ],
          "description": "One vote account (or its identity) only."
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /cluster/vote-account-changes` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/cluster/activity": {
   "get": {
    "operationId": "getClusterActivity",
    "tags": [
     "Cluster"
    ],
    "summary": "Every validator's vote-account changes, identity withdrawals and host changes in one feed, by kind or validator",
    "description": "Every validator's activity in one epoch or the last few, newest first: vote-account changes (as /cluster/vote-account-changes), withdrawals from node identities (SOL or SPL tokens leaving the identity: kind `identityWithdraw`, source `identity`) and host changes (failovers, migrations and software changes, as /validators/host-changes events) in one feed, optionally only some kinds or one validator. An `identityWithdraw` event's `newRecipient` says whether the identity had never sent SOL or tokens to that recipient before in its recorded history (`null` when the history cannot tell).\n\nFull reference: the `GET|POST /cluster/activity` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "epoch",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "One epoch; otherwise the last `epochs`."
     },
     {
      "name": "epochs",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Epochs up to the current one, 1..=10, default 3."
     },
     {
      "name": "kind",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Comma-separated kinds to keep: create, voter, withdrawer, identity, inflationCommission, blockRevenueCommission, inflationCollector, blockRevenueCollector, withdraw, identityWithdraw, failover, migration, software."
     },
     {
      "name": "voteKey",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "One validator only, by either key (one of the two)."
     },
     {
      "name": "identity",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /cluster/activity` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postClusterActivity",
    "tags": [
     "Cluster"
    ],
    "summary": "Every validator's vote-account changes, identity withdrawals and host changes in one feed, by kind or validator",
    "description": "The POST form of `GET /cluster/activity`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "epoch": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "One epoch; otherwise the last `epochs`."
         },
         "epochs": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "Epochs up to the current one, 1..=10, default 3."
         },
         "kind": {
          "type": [
           "string",
           "null"
          ],
          "description": "Comma-separated kinds to keep: create, voter, withdrawer, identity, inflationCommission, blockRevenueCommission, inflationCollector, blockRevenueCollector, withdraw, identityWithdraw, failover, migration, software."
         },
         "voteKey": {
          "type": [
           "string",
           "null"
          ],
          "description": "One validator only, by either key (one of the two)."
         },
         "identity": {
          "type": [
           "string",
           "null"
          ],
          "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /cluster/activity` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/validators/activity": {
   "get": {
    "operationId": "getValidatorsActivity",
    "tags": [
     "Validators (history)"
    ],
    "summary": "Its vote-account changes, identity withdrawals and host changes in one list",
    "description": "One validator's activity, oldest first: the events of /validators/vote-account-changes, the SOL and tokens that left its node identity (kind `identityWithdraw`, with `newRecipient`: whether it went somewhere the identity had never sent to before, `null` when the history cannot tell) and the events of /validators/host-changes in one list, each marked with its source. The per-validator counterpart of /cluster/activity, with the same event shape.\n\nFull reference: the `GET|POST /validators/activity` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "identity",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
     },
     {
      "name": "voteKey",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Vote account or node identity (base58); either kind is accepted."
     },
     {
      "name": "limit",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "Epochs back from the current one, 1..=128, default 10."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /validators/activity` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postValidatorsActivity",
    "tags": [
     "Validators (history)"
    ],
    "summary": "Its vote-account changes, identity withdrawals and host changes in one list",
    "description": "The POST form of `GET /validators/activity`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "identity": {
          "type": [
           "string",
           "null"
          ],
          "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
         },
         "voteKey": {
          "type": [
           "string",
           "null"
          ],
          "description": "Vote account or node identity (base58); either kind is accepted."
         },
         "limit": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "Epochs back from the current one, 1..=128, default 10."
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /validators/activity` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/governance/proposals": {
   "get": {
    "operationId": "getGovernanceProposals",
    "tags": [
     "Governance (mainnet)"
    ],
    "summary": "Every proposal: tallies, turnout, verdict",
    "description": "Solana governance proposals (SGPs) voted on chain through the svmgov program (govYkyQ3ePtGULAtY6V75qjWE8UH4vCUVQ1W4HdCAZU), mainnet only, in creation order: tallies, turnout and the verdict.\n\nFull reference: the `GET|POST /governance/proposals` section of https://api.vx.tools/llms.txt.",
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /governance/proposals` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postGovernanceProposals",
    "tags": [
     "Governance (mainnet)"
    ],
    "summary": "Every proposal: tallies, turnout, verdict",
    "description": "The POST form of `GET /governance/proposals`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "No fields; an empty body or `{}`.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {}
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /governance/proposals` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/governance/proposal": {
   "get": {
    "operationId": "getGovernanceProposal",
    "tags": [
     "Governance (mainnet)"
    ],
    "summary": "One proposal: votes, overrides, breakdowns, timeline",
    "description": "One proposal in full: every validator vote, the validators that did not vote, stakers' overrides per validator and the large ones by staker, the outcome by client, country and provider, and turnout over time.\n\nFull reference: the `GET|POST /governance/proposal` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "address",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "The proposal account, or its SGP number (`SGP-0003`, `3`)."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /governance/proposal` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postGovernanceProposal",
    "tags": [
     "Governance (mainnet)"
    ],
    "summary": "One proposal: votes, overrides, breakdowns, timeline",
    "description": "The POST form of `GET /governance/proposal`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": true,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "address": {
          "type": "string",
          "description": "The proposal account, or its SGP number (`SGP-0003`, `3`)."
         }
        },
        "required": [
         "address"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /governance/proposal` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/validators/governance": {
   "get": {
    "operationId": "getValidatorsGovernance",
    "tags": [
     "Validators (history)"
    ],
    "summary": "Its governance votes and stakers' overrides",
    "description": "One validator's record across every proposal: its vote and its stakers' overrides.\n\nFull reference: the `GET|POST /validators/governance` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "identity",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
     },
     {
      "name": "voteKey",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Vote account or node identity (base58); either kind is accepted."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /validators/governance` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postValidatorsGovernance",
    "tags": [
     "Validators (history)"
    ],
    "summary": "Its governance votes and stakers' overrides",
    "description": "The POST form of `GET /validators/governance`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "identity": {
          "type": [
           "string",
           "null"
          ],
          "description": "Node identity or vote account (base58); either kind is accepted. `voteKey` wins when both are sent."
         },
         "voteKey": {
          "type": [
           "string",
           "null"
          ],
          "description": "Vote account or node identity (base58); either kind is accepted."
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /validators/governance` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/features": {
   "get": {
    "operationId": "getFeatures",
    "tags": [
     "Feature gates"
    ],
    "summary": "Every feature gate on all three clusters",
    "description": "Every Solana feature gate, with its state on mainnet-beta, testnet and devnet. Status comes from each feature account on chain (read every minute); the queue order, titles, SIMDs and min versions per client come from the Agave wiki's Feature Gate Tracker Schedule (`wikiUrl`; read every 5 minutes); names from agave's FEATURE_NAMES. The same data on every cluster's API. The wiki has no planned mainnet epoch: what is next is the queue order. Min versions are the wiki's only (empty = not listed).\n\nFull reference: the `GET|POST /features` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "cluster",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Which cluster `status` filters on (default: the one served)."
     },
     {
      "name": "status",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "`active`, `queued`, `inactive` or `scheduled` (in the wiki's queue)."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /features` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postFeatures",
    "tags": [
     "Feature gates"
    ],
    "summary": "Every feature gate on all three clusters",
    "description": "The POST form of `GET /features`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "cluster": {
          "type": [
           "string",
           "null"
          ],
          "description": "Which cluster `status` filters on (default: the one served)."
         },
         "status": {
          "type": [
           "string",
           "null"
          ],
          "description": "`active`, `queued`, `inactive` or `scheduled` (in the wiki's queue)."
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /features` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/features/upcoming": {
   "get": {
    "operationId": "getFeaturesUpcoming",
    "tags": [
     "Feature gates"
    ],
    "summary": "Queued and scheduled, with stake readiness",
    "description": "What activates next on one cluster: queued features first (they activate at the next epoch boundary), then the wiki's queue in order. Each feature is shaped as in /features, plus `readiness` when `cluster` is the one this API serves (api.vx.tools: mainnet-beta): the activated stake whose node's gossip version meets the feature's min version for its client.\n\nFull reference: the `GET|POST /features/upcoming` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "cluster",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /features/upcoming` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postFeaturesUpcoming",
    "tags": [
     "Feature gates"
    ],
    "summary": "Queued and scheduled, with stake readiness",
    "description": "The POST form of `GET /features/upcoming`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "cluster": {
          "type": [
           "string",
           "null"
          ]
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /features/upcoming` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/feature": {
   "get": {
    "operationId": "getFeature",
    "tags": [
     "Feature gates"
    ],
    "summary": "One feature gate and its history",
    "description": "One feature gate on every cluster, with its history.\n\nFull reference: the `GET|POST /feature` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "id",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /feature` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postFeature",
    "tags": [
     "Feature gates"
    ],
    "summary": "One feature gate and its history",
    "description": "The POST form of `GET /feature`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": true,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "id": {
          "type": "string"
         }
        },
        "required": [
         "id"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /feature` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/simds": {
   "get": {
    "operationId": "getSimds",
    "tags": [
     "Feature gates"
    ],
    "summary": "Every SIMD with its gates' activation per cluster",
    "description": "The feature gates organized by SIMD. Activation happens per gate, so this is a view over the same data as /features: each SIMD with the gates that implement it (a SIMD can have several, as SIMD-0437's rent tiers do, and a gate several SIMDs, as SBPFv3 does) and how far they have activated on each cluster, plus the gates it is only related to. Every proposal in the SIMD repo is listed, with or without a gate, by SIMD number, and every SIMD an open PR proposes; one whose PR closed unmerged is listed when a gate or a superseding SIMD points at it (the rest only through /simd).\n\nFull reference: the `GET|POST /simds` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "cluster",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "Which cluster `stage` filters on (default: the one served)."
     },
     {
      "name": "stage",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "`noGate`, `pending`, `partial` or `active`."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /simds` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postSimds",
    "tags": [
     "Feature gates"
    ],
    "summary": "Every SIMD with its gates' activation per cluster",
    "description": "The POST form of `GET /simds`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "cluster": {
          "type": [
           "string",
           "null"
          ],
          "description": "Which cluster `stage` filters on (default: the one served)."
         },
         "stage": {
          "type": [
           "string",
           "null"
          ],
          "description": "`noGate`, `pending`, `partial` or `active`."
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /simds` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/simd": {
   "get": {
    "operationId": "getSimd",
    "tags": [
     "Feature gates"
    ],
    "summary": "One SIMD with its gates in full",
    "description": "One SIMD: its summary as in /simds, and its gates in full, shaped as in /features (with `readiness` for the served cluster while not active).\n\nFull reference: the `GET|POST /simd` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "simd",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "`512`, `0512` or `SIMD-0512`."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /simd` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postSimd",
    "tags": [
     "Feature gates"
    ],
    "summary": "One SIMD with its gates in full",
    "description": "The POST form of `GET /simd`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": true,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "simd": {
          "type": "string",
          "description": "`512`, `0512` or `SIMD-0512`."
         }
        },
        "required": [
         "simd"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /simd` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/announcements": {
   "get": {
    "operationId": "getAnnouncements",
    "tags": [
     "Feature gates"
    ],
    "summary": "Restarts, upgrades, feature activations as announced",
    "description": "Restarts, upgrades and feature activations as the Solana Tech server announces them in `#mb-announcements` (mainnet-beta) and `#testnet-announcements` (testnet), followed into the Vortex Discord and read every minute. Only what a post says is kept, never its text or author; a deleted post is dropped. Posts since 2026-10-26.\n\nFull reference: the `GET|POST /announcements` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "cluster",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "`mainnet-beta` or `testnet`; both when omitted."
     },
     {
      "name": "kind",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string"
      },
      "description": "`restart`, `upgrade`, `downgrade`, `feature`, `security` (a vulnerability to patch or mitigate) or `other`."
     },
     {
      "name": "limit",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      },
      "description": "1..=200, default 50."
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /announcements` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postAnnouncements",
    "tags": [
     "Feature gates"
    ],
    "summary": "Restarts, upgrades, feature activations as announced",
    "description": "The POST form of `GET /announcements`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "cluster": {
          "type": [
           "string",
           "null"
          ],
          "description": "`mainnet-beta` or `testnet`; both when omitted."
         },
         "kind": {
          "type": [
           "string",
           "null"
          ],
          "description": "`restart`, `upgrade`, `downgrade`, `feature`, `security` (a vulnerability to patch or mitigate) or `other`."
         },
         "limit": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "description": "1..=200, default 50."
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /announcements` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  },
  "/epochs/leader-schedule": {
   "get": {
    "operationId": "getEpochsLeaderSchedule",
    "tags": [
     "Cluster"
    ],
    "summary": "An epoch's leader schedule",
    "description": "The epoch's leader per slot, compactly: one index into `leaders` per 4-slot leader window.\n\nFull reference: the `GET|POST /epochs/leader-schedule` section of https://api.vx.tools/llms.txt.",
    "parameters": [
     {
      "name": "epoch",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "minimum": 0
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /epochs/leader-schedule` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   },
   "post": {
    "operationId": "postEpochsLeaderSchedule",
    "tags": [
     "Cluster"
    ],
    "summary": "An epoch's leader schedule",
    "description": "The POST form of `GET /epochs/leader-schedule`: the same parameters as a JSON body, the same answer.",
    "requestBody": {
     "required": false,
     "description": "The same fields as the GET query string, as JSON.",
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "epoch": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "headers": {
       "Cache-Control": {
        "$ref": "#/components/headers/CacheControl"
       },
       "X-Robots-Tag": {
        "$ref": "#/components/headers/XRobotsTag"
       },
       "x-vortex-build": {
        "$ref": "#/components/headers/VortexBuild"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Shape: see the `GET|POST /epochs/leader-schedule` section of https://api.vx.tools/llms.txt."
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "4XX": {
      "$ref": "#/components/responses/Error"
     },
     "5XX": {
      "$ref": "#/components/responses/Error"
     }
    }
   }
  }
 },
 "components": {
  "schemas": {
   "BlockIncome": {
    "type": "object",
    "properties": {
     "baseFees": {
      "type": "integer",
      "minimum": 0,
      "description": "Lamports, the leader's share of base (signature) fees: the half left after the burn, not the gross fee."
     },
     "priorityFees": {
      "type": "integer",
      "minimum": 0,
      "description": "Lamports from priority (compute-unit) fees."
     },
     "mevTips": {
      "type": "integer",
      "minimum": 0,
      "description": "Lamports captured as MEV via tip programs."
     }
    },
    "required": [
     "baseFees",
     "priorityFees",
     "mevTips"
    ],
    "description": "Income in lamports. totalFees = baseFees + priorityFees; total income adds mevTips."
   },
   "LatencyDistributionEntry": {
    "type": "object",
    "properties": {
     "latency": {
      "type": "integer",
      "minimum": 0,
      "maximum": 31,
      "description": "0 = did not vote, 1..=30 = latency in slots, 31 = 31 or more."
     },
     "stakePct": {
      "type": "number",
      "description": "Share of voting stake in this bucket, 0..100."
     },
     "validatorCount": {
      "type": "integer",
      "minimum": 0
     }
    },
    "required": [
     "latency",
     "stakePct",
     "validatorCount"
    ],
    "description": "Tower era: one bucket of a slot's stake-weighted vote-latency histogram."
   },
   "Geography": {
    "type": "object",
    "properties": {
     "source": {
      "type": "string",
      "enum": [
       "epoch",
       "current"
      ],
      "description": "`epoch`: the epoch's recorded gossip addresses; `current`: today's (none recorded for the epoch)."
     },
     "edition": {
      "type": [
       "string",
       "null"
      ],
      "description": "DB-IP edition (`2026-10`) the epoch's addresses resolved with."
     }
    },
    "required": [
     "source",
     "edition"
    ],
    "description": "Where a response's location fields come from."
   },
   "FooterAgent": {
    "type": "object",
    "properties": {
     "agent": {
      "type": "string"
     },
     "blocks": {
      "type": "integer",
      "minimum": 0
     }
    },
    "required": [
     "agent",
     "blocks"
    ]
   },
   "Consensus": {
    "type": "string",
    "enum": [
     "tower",
     "alpenglow"
    ]
   },
   "Version": {
    "type": "object",
    "properties": {
     "sha": {
      "type": "string",
      "description": "Git commit the server was built from; `unknown` outside a checkout."
     },
     "cluster": {
      "type": "string",
      "enum": [
       "mainnet-beta",
       "testnet",
       "devnet"
      ],
      "description": "The cluster this instance serves."
     }
    },
    "required": [
     "sha",
     "cluster"
    ]
   },
   "Ready": {
    "type": "object",
    "properties": {
     "ready": {
      "type": "boolean",
      "description": "Every required component has finished its first pass and the singleton lock file opens."
     },
     "pending": {
      "type": "array",
      "items": {
       "type": "string"
      },
      "description": "What is not done yet: `clock`, `directory`, `tenure`, `epochTotals`, `leaderboard`, `pools` (mainnet), `versions`, `geoHistory`, `governance` (mainnet), `features`, `simds`, `announcements`, `movingStake`, `commissionTerms`, `admission`, `ingestion`; `startup` before any is registered; `singletonLock` while the lock file cannot be opened."
     },
     "uptimeSeconds": {
      "type": "integer",
      "minimum": 0
     },
     "readyAfterSeconds": {
      "type": [
       "number",
       "null"
      ],
      "description": "Seconds from start to ready, once ready."
     },
     "singleton": {
      "type": "object",
      "description": "Which of the deployment's processes runs the once-per-deployment work (usage file, paging, Slack alerts).",
      "properties": {
       "gated": {
        "type": "boolean",
        "description": "False when the lock is disabled: every process runs it."
       },
       "held": {
        "type": "boolean",
        "description": "This process runs it."
       },
       "lock": {
        "type": [
         "string",
         "null"
        ],
        "description": "The lock file."
       },
       "error": {
        "type": [
         "string",
         "null"
        ],
        "description": "Why the lock file cannot be opened."
       }
      },
      "required": [
       "gated",
       "held",
       "lock",
       "error"
      ]
     }
    },
    "required": [
     "ready",
     "pending",
     "uptimeSeconds",
     "readyAfterSeconds",
     "singleton"
    ]
   },
   "AlpenglowStatus": {
    "type": "object",
    "properties": {
     "phase": {
      "type": "string",
      "enum": [
       "scheduled",
       "migrating",
       "active"
      ]
     },
     "activationSlot": {
      "type": "integer",
      "minimum": 0,
      "description": "First slot of the activation epoch (expected slot while `scheduled`)."
     },
     "genesisSlot": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0,
      "description": "G, the last TowerBFT block; null until `active`."
     },
     "cutoverEpoch": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0,
      "description": "Epoch containing G (mainnet: 1064); null until `active`. Epochs from it on are Alpenglow."
     }
    },
    "required": [
     "phase",
     "activationSlot",
     "genesisSlot",
     "cutoverEpoch"
    ]
   },
   "EpochProgress": {
    "type": "object",
    "properties": {
     "slotIndex": {
      "type": "integer",
      "minimum": 0
     },
     "slotsInEpoch": {
      "type": "integer",
      "minimum": 0
     },
     "absoluteSlot": {
      "type": "integer",
      "minimum": 0
     },
     "slotSeconds": {
      "type": [
       "number",
       "null"
      ],
      "description": "Observed seconds per slot over the last ~30 minutes (not the nominal 0.4)."
     },
     "estimatedEndTime": {
      "type": [
       "integer",
       "null"
      ],
      "description": "Unix seconds the epoch's last slot is expected."
     },
     "readAt": {
      "type": "integer",
      "description": "Unix seconds the slot figures were read."
     }
    },
    "required": [
     "slotIndex",
     "slotsInEpoch",
     "absoluteSlot",
     "slotSeconds",
     "estimatedEndTime",
     "readAt"
    ]
   },
   "EpochTotals": {
    "type": "object",
    "properties": {
     "epoch": {
      "type": "integer",
      "minimum": 0
     },
     "processedSlots": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0
     },
     "blocksProduced": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0
     },
     "skippedSlots": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0
     },
     "blockRevenue": {
      "oneOf": [
       {
        "$ref": "#/components/schemas/BlockIncome"
       },
       {
        "type": "null"
       }
      ]
     },
     "activeValidators": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0
     },
     "stakedValidators": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0
     },
     "readAt": {
      "type": "integer"
     }
    },
    "required": [
     "epoch",
     "processedSlots",
     "blocksProduced",
     "skippedSlots",
     "blockRevenue",
     "activeValidators",
     "stakedValidators",
     "readAt"
    ],
    "description": "Cluster totals for the epoch so far; block figures are null where no block ingestion runs (testnet)."
   },
   "EpochsCurrent": {
    "type": "object",
    "properties": {
     "cluster": {
      "type": "string",
      "enum": [
       "mainnet-beta",
       "testnet",
       "devnet"
      ],
      "description": "The cluster this instance serves."
     },
     "epoch": {
      "type": "integer",
      "minimum": 0
     },
     "alpenglow": {
      "oneOf": [
       {
        "$ref": "#/components/schemas/AlpenglowStatus"
       },
       {
        "type": "null"
       }
      ],
      "description": "TowerBFT -> Alpenglow transition state; null while nothing is scheduled."
     },
     "progress": {
      "oneOf": [
       {
        "$ref": "#/components/schemas/EpochProgress"
       },
       {
        "type": "null"
       }
      ]
     },
     "totals": {
      "oneOf": [
       {
        "$ref": "#/components/schemas/EpochTotals"
       },
       {
        "type": "null"
       }
      ]
     },
     "ingestion": {
      "type": [
       "object",
       "null"
      ],
      "description": "Data freshness: `{ finalizedSlot, blocks, footers, rankMaps, footerEpochs, checkedAt }`; see llms.txt."
     },
     "chain": {
      "type": [
       "object",
       "null"
      ],
      "description": "Whether the cluster is moving: `{ state: running | halted | stale, ... }`; see llms.txt."
     }
    },
    "required": [
     "cluster",
     "epoch",
     "alpenglow",
     "progress",
     "totals",
     "ingestion",
     "chain"
    ]
   },
   "ValidatorEntry": {
    "type": "object",
    "properties": {
     "nodeAddress": {
      "type": "string",
      "description": "Node identity."
     },
     "voteAddress": {
      "type": [
       "string",
       "null"
      ],
      "description": "Vote account; null if not registered."
     },
     "name": {
      "type": [
       "string",
       "null"
      ],
      "description": "Curated name, else the on-chain validator-info name."
     },
     "firstEpoch": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0,
      "description": "First epoch the vote account voted or had stake in."
     },
     "activatedStake": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0,
      "description": "The vote account's activated stake this epoch, lamports, from the live directory; null without a vote account. totalActivatedStake on the response is the cluster's."
     },
     "withdrawerKind": {
      "type": [
       "string",
       "null"
      ],
      "enum": [
       "identity",
       "program",
       "key",
       null
      ],
      "description": "What holds the vote account's withdraw authority, from the address alone: `identity` = the node identity key; `program` = an address off the ed25519 curve, which only a program can sign for (a multisig such as Squads, governance); `key` = any other key. Null without a vote state. As `voteState.withdrawerKind` on /validators/status."
     },
     "website": {
      "type": "string",
      "description": "`info=true` only; absent when not published."
     },
     "details": {
      "type": "string",
      "description": "`info=true` only; absent when not published."
     },
     "iconUrl": {
      "type": "string",
      "description": "`info=true` only; absent when not published. Untrusted, any host."
     }
    },
    "required": [
     "nodeAddress",
     "voteAddress",
     "name",
     "firstEpoch",
     "activatedStake",
     "withdrawerKind"
    ]
   },
   "ValidatorDirectory": {
    "type": "object",
    "properties": {
     "validators": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/ValidatorEntry"
      }
     },
     "totalActivatedStake": {
      "type": "integer",
      "minimum": 0,
      "description": "Every staked vote account's activated stake this epoch, lamports (the live directory's total)."
     }
    },
    "required": [
     "validators",
     "totalActivatedStake"
    ]
   },
   "ParticipationRewards": {
    "type": "object",
    "properties": {
     "perSlotLamports": {
      "type": "integer",
      "minimum": 0,
      "description": "What one paid slot is worth to this validator (its half)."
     },
     "votingLamports": {
      "type": "integer",
      "minimum": 0,
      "description": "Earned by its notarize and skip votes."
     },
     "missedLamports": {
      "type": "integer",
      "minimum": 0,
      "description": "Lost to its missed slots."
     },
     "unpayableLamports": {
      "type": "integer",
      "minimum": 0,
      "description": "Slots that paid nobody: not its fault."
     },
     "producerBonusLamports": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0,
      "description": "Its half of the votes in the reward certificates of the footers it produced."
     },
     "totalLamports": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0,
      "description": "votingLamports + producerBonusLamports."
     },
     "maxVotingLamports": {
      "type": "integer",
      "minimum": 0,
      "description": "Voting in every slot of the epoch."
     },
     "onChainLamports": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0,
      "description": "The vote account's on-chain epoch_credits gain (lamports under Alpenglow), while RPC reports it (5 epochs)."
     }
    },
    "required": [
     "perSlotLamports",
     "votingLamports",
     "missedLamports",
     "unpayableLamports",
     "producerBonusLamports",
     "totalLamports",
     "maxVotingLamports",
     "onChainLamports"
    ],
    "description": "What its votes earned in an Alpenglow epoch, lamports, over the slots ingested so far."
   },
   "MissCauses": {
    "type": "object",
    "properties": {
     "throughSlot": {
      "type": "integer",
      "minimum": 0
     },
     "offlineSlots": {
      "type": "integer",
      "minimum": 0
     },
     "thinBlockSlots": {
      "type": "integer",
      "minimum": 0
     },
     "lateSlots": {
      "type": "integer",
      "minimum": 0
     },
     "offlineLamports": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0
     },
     "thinBlockLamports": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0
     },
     "lateLamports": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0
     },
     "unreachableProducers": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0
     },
     "unreachableSlots": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0
     },
     "offlineCutoffSlots": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0
     }
    },
    "required": [
     "throughSlot",
     "offlineSlots",
     "thinBlockSlots",
     "lateSlots",
     "offlineLamports",
     "thinBlockLamports",
     "lateLamports",
     "unreachableProducers",
     "unreachableSlots",
     "offlineCutoffSlots"
    ],
    "description": "Its missed slots by cause; see /epochs/participation in llms.txt."
   },
   "RewardTotals": {
    "type": "object",
    "properties": {
     "budgetLamports": {
      "type": "integer",
      "minimum": 0
     },
     "votingLamports": {
      "type": "integer",
      "minimum": 0
     },
     "missedLamports": {
      "type": "integer",
      "minimum": 0
     },
     "unpayableLamports": {
      "type": "integer",
      "minimum": 0
     },
     "producerBonusLamports": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0
     },
     "maxVotingLamports": {
      "type": "integer",
      "minimum": 0
     }
    },
    "required": [
     "budgetLamports",
     "votingLamports",
     "missedLamports",
     "unpayableLamports",
     "producerBonusLamports",
     "maxVotingLamports"
    ],
    "description": "Sums over the epoch's admitted validators."
   },
   "ParticipationItem": {
    "type": "object",
    "properties": {
     "epoch": {
      "type": "integer",
      "minimum": 0
     },
     "admitted": {
      "type": "boolean",
      "description": "In the epoch's rank map, i.e. able to vote at all."
     },
     "stakeRank": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0,
      "description": "Rank in the rank map (0 = highest stake); not a performance rank."
     },
     "stake": {
      "type": "integer",
      "minimum": 0,
      "description": "Stake the rank map used, lamports."
     },
     "eligibleSlots": {
      "type": "integer",
      "minimum": 0,
      "description": "Reward slots whose footer was read (the denominator for every rate)."
     },
     "notarizedSlots": {
      "type": "integer",
      "minimum": 0,
      "description": "Eligible slots it voted notarize on."
     },
     "skippedSlots": {
      "type": "integer",
      "minimum": 0,
      "description": "Eligible slots it voted skip on (a real, paid vote)."
     },
     "skippedNotarizedSlots": {
      "type": "integer",
      "minimum": 0,
      "description": "Of skippedSlots, slots the cluster notarized anyway."
     },
     "missedSlots": {
      "type": "integer",
      "minimum": 0,
      "description": "Eligible slots with neither vote."
     },
     "finalizedCerts": {
      "type": "integer",
      "minimum": 0,
      "description": "Finalization certificates decoded for the epoch."
     },
     "finalizedSlots": {
      "type": "integer",
      "minimum": 0,
      "description": "Finalization certificates its vote appears in."
     },
     "fastFinalizedSlots": {
      "type": "integer",
      "minimum": 0,
      "description": "Of those, fast-path (80%) aggregates."
     },
     "lastIngestedSlot": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0,
      "description": "Last reward slot ingested; null until the first write."
     },
     "complete": {
      "type": "boolean",
      "description": "Every count is final."
     },
     "missingFooters": {
      "type": "integer",
      "minimum": 0,
      "description": "Footer slots missing from the warehouse."
     },
     "rank": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0,
      "description": "Its rank on that epoch's participation leaderboard (0-based)."
     },
     "rewards": {
      "oneOf": [
       {
        "$ref": "#/components/schemas/ParticipationRewards"
       },
       {
        "type": "null"
       }
      ]
     },
     "missCauses": {
      "oneOf": [
       {
        "$ref": "#/components/schemas/MissCauses"
       },
       {
        "type": "null"
       }
      ]
     }
    },
    "required": [
     "epoch",
     "admitted",
     "stakeRank",
     "stake",
     "eligibleSlots",
     "notarizedSlots",
     "skippedSlots",
     "skippedNotarizedSlots",
     "missedSlots",
     "finalizedCerts",
     "finalizedSlots",
     "fastFinalizedSlots",
     "lastIngestedSlot",
     "complete",
     "missingFooters",
     "rank",
     "rewards",
     "missCauses"
    ],
    "description": "One Alpenglow epoch of one vote account's certificate participation."
   },
   "ParticipationLeaderboardRecord": {
    "type": "object",
    "properties": {
     "nodeName": {
      "type": "string"
     },
     "nodeAddress": {
      "type": "string"
     },
     "voteAddress": {
      "type": "string"
     },
     "admitted": {
      "type": "boolean",
      "description": "In the epoch's rank map, i.e. able to vote at all."
     },
     "stakeRank": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0,
      "description": "Rank in the rank map (0 = highest stake); not a performance rank."
     },
     "stake": {
      "type": "integer",
      "minimum": 0,
      "description": "Stake the rank map used, lamports."
     },
     "eligibleSlots": {
      "type": "integer",
      "minimum": 0,
      "description": "Reward slots whose footer was read (the denominator for every rate)."
     },
     "notarizedSlots": {
      "type": "integer",
      "minimum": 0,
      "description": "Eligible slots it voted notarize on."
     },
     "skippedSlots": {
      "type": "integer",
      "minimum": 0,
      "description": "Eligible slots it voted skip on (a real, paid vote)."
     },
     "skippedNotarizedSlots": {
      "type": "integer",
      "minimum": 0,
      "description": "Of skippedSlots, slots the cluster notarized anyway."
     },
     "missedSlots": {
      "type": "integer",
      "minimum": 0,
      "description": "Eligible slots with neither vote."
     },
     "finalizedCerts": {
      "type": "integer",
      "minimum": 0,
      "description": "Finalization certificates decoded for the epoch."
     },
     "finalizedSlots": {
      "type": "integer",
      "minimum": 0,
      "description": "Finalization certificates its vote appears in."
     },
     "fastFinalizedSlots": {
      "type": "integer",
      "minimum": 0,
      "description": "Of those, fast-path (80%) aggregates."
     },
     "lastIngestedSlot": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0,
      "description": "Last reward slot ingested; null until the first write."
     },
     "complete": {
      "type": "boolean",
      "description": "Every count is final."
     },
     "missingFooters": {
      "type": "integer",
      "minimum": 0,
      "description": "Footer slots missing from the warehouse."
     },
     "rank": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0,
      "description": "Competition rank, 0-based, ties shared; null when not admitted."
     },
     "rewards": {
      "oneOf": [
       {
        "$ref": "#/components/schemas/ParticipationRewards"
       },
       {
        "type": "null"
       }
      ]
     },
     "missCauses": {
      "oneOf": [
       {
        "$ref": "#/components/schemas/MissCauses"
       },
       {
        "type": "null"
       }
      ]
     },
     "datacenter": {
      "type": [
       "string",
       "null"
      ],
      "description": "`<ASN>-<countryCode>-<city>` from the gossip address in DB-IP Lite, e.g. `20473-US-Atlanta`; `0--Unknown` when nothing resolved; null when not in gossip."
     },
     "continent": {
      "type": [
       "string",
       "null"
      ],
      "description": "DB-IP's English name, e.g. `Europe`."
     },
     "country": {
      "type": [
       "string",
       "null"
      ],
      "description": "DB-IP's English name, e.g. `United States`."
     },
     "provider": {
      "type": [
       "string",
       "null"
      ],
      "description": "Managed-hosting brand from the curated list (`Vultr`, `OVH`, ...), else `Self-hosted`."
     },
     "softwareBase": {
      "type": [
       "string",
       "null"
      ],
      "description": "`Agave`, `Frankendancer` or `Firedancer`."
     },
     "softwareFlavor": {
      "type": [
       "string",
       "null"
      ],
      "description": "Fork on top of the base (`BAM`, `Jito`, `Harmonic`, ...); null for stock builds."
     },
     "softwareVersion": {
      "type": [
       "string",
       "null"
      ],
      "description": "e.g. `4.3.0`."
     },
     "softwareSource": {
      "type": [
       "string",
       "null"
      ],
      "enum": [
       "recorded",
       "gossip",
       "footer",
       null
      ],
      "description": "Where the software label came from."
     },
     "softwareVersionSource": {
      "type": "string",
      "enum": [
       "footer",
       "gossip",
       "validatorHistory"
      ],
      "description": "Where softwareVersion came from; absent without a version."
     },
     "footerAgents": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/FooterAgent"
      },
      "maxItems": 5,
      "description": "Present only when its blocks were not all one build."
     }
    },
    "required": [
     "nodeName",
     "nodeAddress",
     "voteAddress",
     "admitted",
     "stakeRank",
     "stake",
     "eligibleSlots",
     "notarizedSlots",
     "skippedSlots",
     "skippedNotarizedSlots",
     "missedSlots",
     "finalizedCerts",
     "finalizedSlots",
     "fastFinalizedSlots",
     "lastIngestedSlot",
     "complete",
     "missingFooters",
     "rank",
     "rewards",
     "missCauses",
     "datacenter",
     "continent",
     "country",
     "provider",
     "softwareBase",
     "softwareFlavor",
     "softwareVersion",
     "softwareSource"
    ]
   },
   "ParticipationLeaderboard": {
    "type": "object",
    "properties": {
     "epoch": {
      "type": "integer",
      "minimum": 0
     },
     "consensus": {
      "$ref": "#/components/schemas/Consensus"
     },
     "eligibleSlots": {
      "type": "integer",
      "minimum": 0
     },
     "finalizedCerts": {
      "type": "integer",
      "minimum": 0
     },
     "lastIngestedSlot": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0
     },
     "complete": {
      "type": "boolean"
     },
     "missingFooters": {
      "type": "integer",
      "minimum": 0
     },
     "admitted": {
      "type": "integer",
      "minimum": 0,
      "description": "Records with admitted == true."
     },
     "rewardTotals": {
      "oneOf": [
       {
        "$ref": "#/components/schemas/RewardTotals"
       },
       {
        "type": "null"
       }
      ]
     },
     "geography": {
      "$ref": "#/components/schemas/Geography"
     },
     "records": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/ParticipationLeaderboardRecord"
      }
     }
    },
    "required": [
     "epoch",
     "consensus",
     "eligibleSlots",
     "finalizedCerts",
     "lastIngestedSlot",
     "complete",
     "missingFooters",
     "admitted",
     "rewardTotals",
     "geography",
     "records"
    ],
    "description": "Every validator's Alpenglow participation for one epoch, best first. Tower epochs answer with empty records."
   },
   "IncomeLeaderboardRecord": {
    "type": "object",
    "properties": {
     "nodeName": {
      "type": "string"
     },
     "nodeAddress": {
      "type": "string"
     },
     "stake": {
      "type": "integer",
      "minimum": 0
     },
     "totalSlots": {
      "type": "integer",
      "minimum": 0
     },
     "confirmedSlots": {
      "type": "integer",
      "minimum": 0
     },
     "skippedSlots": {
      "type": "integer",
      "minimum": 0
     },
     "totalIncome": {
      "$ref": "#/components/schemas/BlockIncome"
     },
     "medianIncome": {
      "$ref": "#/components/schemas/BlockIncome"
     },
     "minIncome": {
      "$ref": "#/components/schemas/BlockIncome"
     },
     "maxIncome": {
      "$ref": "#/components/schemas/BlockIncome"
     },
     "datacenter": {
      "type": [
       "string",
       "null"
      ],
      "description": "`<ASN>-<countryCode>-<city>` from the gossip address in DB-IP Lite, e.g. `20473-US-Atlanta`; `0--Unknown` when nothing resolved; null when not in gossip."
     },
     "continent": {
      "type": [
       "string",
       "null"
      ],
      "description": "DB-IP's English name, e.g. `Europe`."
     },
     "country": {
      "type": [
       "string",
       "null"
      ],
      "description": "DB-IP's English name, e.g. `United States`."
     },
     "provider": {
      "type": [
       "string",
       "null"
      ],
      "description": "Managed-hosting brand from the curated list (`Vultr`, `OVH`, ...), else `Self-hosted`."
     },
     "softwareBase": {
      "type": [
       "string",
       "null"
      ],
      "description": "`Agave`, `Frankendancer` or `Firedancer`."
     },
     "softwareFlavor": {
      "type": [
       "string",
       "null"
      ],
      "description": "Fork on top of the base (`BAM`, `Jito`, `Harmonic`, ...); null for stock builds."
     },
     "softwareVersion": {
      "type": [
       "string",
       "null"
      ],
      "description": "e.g. `4.3.0`."
     },
     "softwareSource": {
      "type": "string",
      "enum": [
       "recorded",
       "gossip"
      ],
      "description": "Absent when unknown."
     },
     "softwareVersionSource": {
      "type": "string",
      "enum": [
       "gossip",
       "validatorHistory"
      ],
      "description": "Absent when unknown."
     },
     "captureTotal": {
      "type": [
       "number",
       "null"
      ],
      "description": "Median over its blocks of income / the neighbouring leaders' median: 1.0 earns like its neighbours."
     },
     "captureFees": {
      "type": [
       "number",
       "null"
      ]
     },
     "captureTips": {
      "type": [
       "number",
       "null"
      ]
     },
     "captureBlocks": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0
     },
     "missedToSkipsLamports": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0,
      "description": "Its skipped slots' baselines summed."
     },
     "meanIncome": {
      "oneOf": [
       {
        "$ref": "#/components/schemas/BlockIncome"
       },
       {
        "type": "null"
       }
      ]
     }
    },
    "required": [
     "nodeName",
     "nodeAddress",
     "stake",
     "totalSlots",
     "confirmedSlots",
     "skippedSlots",
     "totalIncome",
     "medianIncome",
     "minIncome",
     "maxIncome",
     "datacenter",
     "continent",
     "country",
     "provider",
     "softwareBase",
     "softwareFlavor",
     "softwareVersion",
     "captureTotal",
     "captureFees",
     "captureTips",
     "captureBlocks",
     "missedToSkipsLamports",
     "meanIncome"
    ]
   },
   "IncomeLeaderboard": {
    "type": "object",
    "properties": {
     "epoch": {
      "type": "integer",
      "minimum": 0
     },
     "records": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/IncomeLeaderboardRecord"
      },
      "description": "The first record is the synthetic \"(cluster stats)\" row (all-ones address); the rest by median total fees, highest first."
     }
    },
    "required": [
     "epoch",
     "records"
    ]
   },
   "BlockInsight": {
    "type": "object",
    "properties": {
     "slot": {
      "type": "integer",
      "minimum": 0
     },
     "isSkipped": {
      "type": [
       "boolean",
       "null"
      ],
      "description": "null = unknown / not ingested."
     },
     "noVotes": {
      "type": [
       "boolean",
       "null"
      ],
      "description": "Tower: the block had no vote transactions."
     },
     "leaderNodeAddress": {
      "type": [
       "string",
       "null"
      ]
     },
     "distribution": {
      "type": [
       "array",
       "null"
      ],
      "items": {
       "$ref": "#/components/schemas/LatencyDistributionEntry"
      },
      "description": "Tower slots only."
     },
     "consensus": {
      "$ref": "#/components/schemas/Consensus"
     }
    },
    "required": [
     "slot",
     "isSkipped",
     "noVotes",
     "leaderNodeAddress",
     "distribution",
     "consensus"
    ]
   },
   "BlocksInsights": {
    "type": "object",
    "properties": {
     "results": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/BlockInsight"
      }
     }
    },
    "required": [
     "results"
    ]
   },
   "SkipCause": {
    "type": "string",
    "enum": [
     "offline",
     "unknown",
     "duplicate",
     "staleParent",
     "lateBlock",
     "noBlock"
    ],
    "description": "Why a skipped Alpenglow leader slot was skipped (the skip-causes job), the first that applies in this order: offline (the leader was not voting either), unknown (no complete pool record), duplicate (more than one block version notarized), staleParent (the block named a stale parent), lateBlock (a block was seen and voted on, skip won), noBlock (no block reached the cluster). See skipCauses in the /epochs/leaderboard/producers section of llms.txt."
   },
   "SkipCauseCounts": {
    "type": "object",
    "properties": {
     "offline": {
      "type": "integer",
      "minimum": 0
     },
     "unknown": {
      "type": "integer",
      "minimum": 0
     },
     "duplicate": {
      "type": "integer",
      "minimum": 0
     },
     "staleParent": {
      "type": "integer",
      "minimum": 0
     },
     "lateBlock": {
      "type": "integer",
      "minimum": 0
     },
     "noBlock": {
      "type": "integer",
      "minimum": 0
     }
    },
    "required": [
     "offline",
     "unknown",
     "duplicate",
     "staleParent",
     "lateBlock",
     "noBlock"
    ],
    "description": "Skipped leader slots by SkipCause; they sum to the skipped slots classified so far."
   },
   "SlotDurationStats": {
    "type": "object",
    "properties": {
     "count": {
      "type": "integer",
      "minimum": 0,
      "description": "Blocks timed."
     },
     "p50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "Median block duration, ms; null without samples."
     },
     "p90Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "90th percentile, ms; null without samples."
     }
    },
    "required": [
     "count",
     "p50Ms",
     "p90Ms"
    ],
    "description": "Block durations from producer timestamps (a block's minus its parent's), ms."
   },
   "SlotDuration": {
    "type": "object",
    "properties": {
     "inWindow": {
      "$ref": "#/components/schemas/SlotDurationStats",
      "description": "Blocks at window positions 2-4, against the producer's own previous block (its pace)."
     },
     "handoff": {
      "$ref": "#/components/schemas/SlotDurationStats",
      "description": "Window-first blocks, against the previous leader's last block (two clocks)."
     },
     "handoffByRegion": {
      "oneOf": [
       {
        "$ref": "#/components/schemas/HandoffByRegion"
       },
       {
        "type": "null"
       }
      ],
      "description": "The handoffs by the previous leader's continent group at the handoff; null for epochs classified before the job recorded it."
     },
     "handoffExpectedP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "Median physical floor over every handoff with both locations known, ms (see skipClassification.latencyModel); null without one."
     },
     "handoffExcessP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "Median of each handoff's duration minus its own floor, ms (not the difference of the medians); null without a handoff with a floor."
     },
     "region": {
      "oneOf": [
       {
        "$ref": "#/components/schemas/ContinentGroup"
       },
       {
        "type": "null"
       }
      ],
      "description": "The producer's own continent group (where most of its leader windows started); null on the cluster row and for epochs classified before."
     },
     "handoffOut": {
      "oneOf": [
       {
        "$ref": "#/components/schemas/SlotDurationStats"
       },
       {
        "type": "null"
       }
      ],
      "description": "The other direction: the next leader's window-first block against this producer's last block of a window (the next leader's handoffs, attributed to the one handed off from). Slow here but not in handoff: slow to be built on rather than to receive. Null on the cluster row (every handoff is both) and for epochs classified before the job recorded it, as are the three below."
     },
     "handoffOutByRegion": {
      "oneOf": [
       {
        "$ref": "#/components/schemas/HandoffByRegion"
       },
       {
        "type": "null"
       }
      ],
      "description": "The outgoing handoffs by the NEXT leader's continent group at the handoff."
     },
     "handoffOutExpectedP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "Median physical floor over every outgoing handoff with both locations known, ms."
     },
     "handoffOutExcessP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "Median of each outgoing handoff's duration minus its own floor, ms."
     },
     "handoffExtraP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "handoffExcessP50Ms less handoffBuildMs, the new leader building its first block: a handoff spans the gap between the leaders and that block, so the excess over the floor still holds it. This is the delay beyond both. Null with the excess."
     },
     "handoffOutExtraP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "handoffOutExcessP50Ms less handoffBuildMs, as handoffExtraP50Ms."
     },
     "handoffBuildMs": {
      "type": [
       "number",
       "null"
      ],
      "description": "What every *ExtraP50Ms subtracts, ms: the time agave gives a window's first block, the epoch's cluster inWindow p50 less 56 ms. Agave starts a window's clock at ParentReady and ends its first block one slot later less BLOCK_PRODUCTION_BUFFER (50 ms) and TIME_TO_COMPLETE_BLOCK_BROADCAST (6 ms), while each later block ends a full slot after the one before; producer time is stamped when a block's footer is built, at its end. Null without the cluster's inWindow p50."
     },
     "handoffByRoute": {
      "oneOf": [
       {
        "type": "array",
        "items": {
         "$ref": "#/components/schemas/RouteHandoff"
        }
       },
       {
        "type": "null"
       }
      ],
      "description": "Cluster row only: every handoff by route, the previous leader's continent group to the next's. handoffByRegion groups by the previous leader's alone, so a group mixes destinations (most handoffs from North America go to Europe, so that group's median floor is transatlantic); a route does not. Null on producer rows (their groups are routes already) and for epochs classified before routes were recorded."
     },
     "handoffTurbineExpectedP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "Median Turbine floor over every handoff, ms: the median shred's path through the epoch's stake-weighted Turbine trees (previous leader -> root -> next leader, or through a layer-1 node), each leg priced by its corridor's measured route factor; at least the direct floor. The fallback path: since agave v4.2 the leader also sends every shred straight to the next window's leader, so neither this nor the direct floor is today's critical path (see handoffNotarizationExpectedP50Ms); under Fast Leader Handover the direct leg is. Null before it was recorded (a producer's: before its epoch was reclassified with producer floors)."
     },
     "handoffTurbineExcessP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "Median of each handoff's duration minus its own Turbine floor, ms."
     },
     "handoffTurbineExtraP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "handoffTurbineExcessP50Ms less handoffBuildMs."
     },
     "handoffNotarizationExpectedP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "Median notarization floor, ms: the handoff's critical path while Fast Leader Handover is off (a leader starts once the previous block is notarized): the block reaching the voters through Turbine and their notarize votes reaching the next leader, until votes of 60% of stake are in. The network path only: no replay, vote or certificate processing, and not the new leader's block (see handoffBuildMs). An estimate, modelled from the epoch's stake, the nodes' locations and measured route factors. Null before it was recorded (a producer's: before its epoch was reclassified with producer floors)."
     },
     "handoffNotarizationExcessP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "Median of each handoff's duration minus its own notarization floor, ms."
     },
     "handoffNotarizationExtraP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "handoffNotarizationExcessP50Ms less handoffBuildMs: on mainnet the time beyond the modelled network path and the first block, i.e. voter replay, vote and certificate processing, and the model's error."
     },
     "handoffOutTurbineExpectedP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "Producer rows: the outgoing handoffs' median Turbine floor, ms, as handoffTurbineExpectedP50Ms. Null on the cluster row and before producer floors were recorded."
     },
     "handoffOutTurbineExcessP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "Median of each outgoing handoff's duration minus its Turbine floor, ms."
     },
     "handoffOutTurbineExtraP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "handoffOutTurbineExcessP50Ms less handoffBuildMs."
     },
     "handoffOutNotarizationExpectedP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "Producer rows: the outgoing handoffs' median notarization floor, ms, as handoffNotarizationExpectedP50Ms. Null on the cluster row and before producer floors were recorded."
     },
     "handoffOutNotarizationExcessP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "Median of each outgoing handoff's duration minus its notarization floor, ms."
     },
     "handoffOutNotarizationExtraP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "handoffOutNotarizationExcessP50Ms less handoffBuildMs."
     }
    },
    "required": [
     "inWindow",
     "handoff",
     "handoffByRegion",
     "handoffExpectedP50Ms",
     "handoffExcessP50Ms",
     "region",
     "handoffOut",
     "handoffOutByRegion",
     "handoffOutExpectedP50Ms",
     "handoffOutExcessP50Ms",
     "handoffExtraP50Ms",
     "handoffOutExtraP50Ms",
     "handoffBuildMs",
     "handoffByRoute",
     "handoffTurbineExpectedP50Ms",
     "handoffTurbineExcessP50Ms",
     "handoffTurbineExtraP50Ms",
     "handoffNotarizationExpectedP50Ms",
     "handoffNotarizationExcessP50Ms",
     "handoffNotarizationExtraP50Ms",
     "handoffOutTurbineExpectedP50Ms",
     "handoffOutTurbineExcessP50Ms",
     "handoffOutTurbineExtraP50Ms",
     "handoffOutNotarizationExpectedP50Ms",
     "handoffOutNotarizationExcessP50Ms",
     "handoffOutNotarizationExtraP50Ms"
    ],
    "description": "Slot durations; blocks next to a clamped timestamp are left out."
   },
   "ContinentGroup": {
    "type": "string",
    "enum": [
     "northAmerica",
     "europe",
     "asia",
     "other",
     "unknown"
    ],
    "description": "Where a leader was, by the DB-IP continent of its gossip address for the epoch (moved by failovers seen in gossip): Oceania, South America and Africa are other; unknown when no location is known."
   },
   "RouteHandoff": {
    "type": "object",
    "description": "One route's handoffs: from the previous leader's continent group to the next leader's, both at the handoff.",
    "properties": {
     "from": {
      "$ref": "#/components/schemas/ContinentGroup"
     },
     "to": {
      "$ref": "#/components/schemas/ContinentGroup"
     },
     "count": {
      "type": "integer",
      "minimum": 0,
      "description": "Handoffs timed."
     },
     "p50Ms": {
      "type": [
       "number",
       "null"
      ]
     },
     "p90Ms": {
      "type": [
       "number",
       "null"
      ]
     },
     "expectedP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "Median floor, ms; null without a handoff with a floor (always for unknown)."
     },
     "excessP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "Median of each handoff's duration minus its own floor, ms."
     },
     "extraP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "excessP50Ms less the new leader's first block (the slot duration's handoffBuildMs)."
     },
     "turbineExpectedP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "Median Turbine floor, ms (cluster row only; see SlotDuration.handoffTurbineExpectedP50Ms)."
     },
     "turbineExcessP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "Median of each handoff's duration minus its own Turbine floor, ms."
     },
     "turbineExtraP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "turbineExcessP50Ms less the new leader's first block (handoffBuildMs)."
     },
     "notarizationExpectedP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "Median notarization floor, ms (cluster row only; see SlotDuration.handoffNotarizationExpectedP50Ms)."
     },
     "notarizationExcessP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "Median of each handoff's duration minus its own notarization floor, ms."
     },
     "notarizationExtraP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "notarizationExcessP50Ms less the new leader's first block (handoffBuildMs)."
     }
    },
    "required": [
     "from",
     "to",
     "count",
     "p50Ms",
     "p90Ms",
     "expectedP50Ms",
     "excessP50Ms",
     "extraP50Ms",
     "turbineExpectedP50Ms",
     "turbineExcessP50Ms",
     "turbineExtraP50Ms",
     "notarizationExpectedP50Ms",
     "notarizationExcessP50Ms",
     "notarizationExtraP50Ms"
    ]
   },
   "RegionHandoff": {
    "type": "object",
    "properties": {
     "count": {
      "type": "integer",
      "minimum": 0,
      "description": "Handoffs timed."
     },
     "p50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "Median handoff duration, ms; null without samples."
     },
     "p90Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "90th percentile, ms; null without samples."
     },
     "expectedP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "Median floor: great-circle distance between the two leaders' DB-IP city coordinates over skipClassification.fibreKmPerMs, ms. Null without a handoff with a floor, and always for unknown."
     },
     "excessP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "Median of each handoff's duration minus its own floor, ms (may be negative: two clocks); null as expectedP50Ms."
     },
     "extraP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "excessP50Ms less the new leader's first block (the slot duration's handoffBuildMs): the delay beyond the floor and the new leader building its block. Null with excessP50Ms."
     },
     "turbineExpectedP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "Median Turbine floor, ms (cluster row, and producer rows once their epoch is reclassified at summary version 7; see SlotDuration.handoffTurbineExpectedP50Ms)."
     },
     "turbineExcessP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "Median of each handoff's duration minus its own Turbine floor, ms."
     },
     "turbineExtraP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "turbineExcessP50Ms less the new leader's first block (handoffBuildMs)."
     },
     "notarizationExpectedP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "Median notarization floor, ms (cluster row, and producer rows once their epoch is reclassified at summary version 7; see SlotDuration.handoffNotarizationExpectedP50Ms)."
     },
     "notarizationExcessP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "Median of each handoff's duration minus its own notarization floor, ms."
     },
     "notarizationExtraP50Ms": {
      "type": [
       "number",
       "null"
      ],
      "description": "notarizationExcessP50Ms less the new leader's first block (handoffBuildMs)."
     }
    },
    "required": [
     "count",
     "p50Ms",
     "p90Ms",
     "expectedP50Ms",
     "excessP50Ms",
     "extraP50Ms",
     "turbineExpectedP50Ms",
     "turbineExcessP50Ms",
     "turbineExtraP50Ms",
     "notarizationExpectedP50Ms",
     "notarizationExcessP50Ms",
     "notarizationExtraP50Ms"
    ],
    "description": "One continent group's handoffs against their physical floor."
   },
   "HandoffByRegion": {
    "type": "object",
    "properties": {
     "northAmerica": {
      "$ref": "#/components/schemas/RegionHandoff"
     },
     "europe": {
      "$ref": "#/components/schemas/RegionHandoff"
     },
     "asia": {
      "$ref": "#/components/schemas/RegionHandoff"
     },
     "other": {
      "$ref": "#/components/schemas/RegionHandoff",
      "description": "Oceania, South America, Africa."
     },
     "unknown": {
      "$ref": "#/components/schemas/RegionHandoff",
      "description": "Either leader's location unknown: counted, no floor."
     }
    },
    "required": [
     "northAmerica",
     "europe",
     "asia",
     "other",
     "unknown"
    ],
    "description": "Handoffs by the previous leader's continent group at the handoff; every group present (count 0 without handoffs)."
   },
   "SkipClassification": {
    "type": "object",
    "properties": {
     "version": {
      "type": "integer",
      "minimum": 0
     },
     "firstSlot": {
      "type": "integer",
      "minimum": 0,
      "description": "Slots classified and timed: firstSlot..=throughSlot."
     },
     "throughSlot": {
      "type": "integer",
      "minimum": 0
     },
     "offlineSlots": {
      "type": "integer",
      "minimum": 0,
      "description": "A leader is offline inside a run of at least this many missed eligible slots of its own."
     },
     "lateBlockMinShare": {
      "type": "number",
      "description": "A block counts as seen only with this share of notarize stake besides the leader's own."
     },
     "laggingRatio": {
      "type": "number",
      "description": "lagging: in-window p50 above this times the cluster's."
     },
     "laggingMinSamples": {
      "type": "integer",
      "minimum": 0,
      "description": "lagging needs at least this many in-window blocks."
     },
     "faintBlockSlots": {
      "type": "integer",
      "minimum": 0,
      "description": "noBlock slots with a notarize set below lateBlockMinShare."
     },
     "clampedBlocks": {
      "type": "integer",
      "minimum": 0,
      "description": "Blocks left out of the durations for a clamped timestamp."
     },
     "laggingProducers": {
      "type": "integer",
      "minimum": 0
     },
     "latencyModel": {
      "type": [
       "string",
       "null"
      ],
      "description": "How slotDuration's handoff floors are modelled: greatCircleFibre, the great-circle distance between the two leaders' DB-IP city coordinates over fibreKmPerMs (a physical floor, no route factor). Null for epochs classified before."
     },
     "fibreKmPerMs": {
      "type": [
       "number",
       "null"
      ],
      "description": "Light's speed in fibre the floor assumes, km/ms (200); null as latencyModel."
     }
    },
    "required": [
     "version",
     "firstSlot",
     "throughSlot",
     "offlineSlots",
     "lateBlockMinShare",
     "laggingRatio",
     "laggingMinSamples",
     "faintBlockSlots",
     "clampedBlocks",
     "laggingProducers",
     "latencyModel",
     "fibreKmPerMs"
    ],
    "description": "How an epoch's skips were classified and its blocks timed (the skip-causes job's summary)."
   },
   "ProducerSkipFields": {
    "type": "object",
    "properties": {
     "skipCauses": {
      "oneOf": [
       {
        "$ref": "#/components/schemas/SkipCauseCounts"
       },
       {
        "type": "null"
       }
      ],
      "description": "Its skipped leader slots by cause (on the cluster row, the epoch's); null until the epoch is classified."
     },
     "slotDuration": {
      "oneOf": [
       {
        "$ref": "#/components/schemas/SlotDuration"
       },
       {
        "type": "null"
       }
      ],
      "description": "Its blocks' slot durations (on the cluster row, the cluster's); null until classified."
     },
     "lagging": {
      "type": [
       "boolean",
       "null"
      ],
      "description": "Its in-window p50 is above laggingRatio times the cluster's over at least laggingMinSamples blocks (see SkipClassification); null until classified, and on the cluster row."
     }
    },
    "required": [
     "skipCauses",
     "slotDuration",
     "lagging"
    ],
    "description": "The skip-cause fields of a producer record (/epochs/leaderboard/producers records and cluster, /epochs/production items). The record's other fields: see llms.txt."
   },
   "ProducerLeaderboard": {
    "type": "object",
    "properties": {
     "skipClassification": {
      "oneOf": [
       {
        "$ref": "#/components/schemas/SkipClassification"
       },
       {
        "type": "null"
       }
      ],
      "description": "How its skips were classified and blocks timed; null until the skip-causes job has run for the epoch."
     },
     "cluster": {
      "$ref": "#/components/schemas/ProducerSkipFields"
     },
     "records": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/ProducerSkipFields"
      }
     }
    },
    "required": [
     "skipClassification",
     "cluster",
     "records"
    ],
    "description": "Every producer's record for one epoch, with the cluster as one producer. The skip-cause fields are listed here; the rest of the shape: see the `GET|POST /epochs/leaderboard/producers` section of https://api.vx.tools/llms.txt."
   },
   "ProductionItems": {
    "type": "array",
    "items": {
     "type": "object",
     "allOf": [
      {
       "$ref": "#/components/schemas/ProducerSkipFields"
      }
     ],
     "properties": {
      "skipClassification": {
       "oneOf": [
        {
         "$ref": "#/components/schemas/SkipClassification"
        },
        {
         "type": "null"
        }
       ],
       "description": "How its skips were classified and blocks timed; null until the skip-causes job has run for the epoch."
      }
     },
     "required": [
      "skipClassification"
     ]
    },
    "description": "One validator's producer record per epoch. The skip-cause fields are listed here; the rest of the shape: see the `GET|POST /epochs/production` section of https://api.vx.tools/llms.txt."
   },
   "ProductionWindows": {
    "type": "object",
    "properties": {
     "windows": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "slots": {
         "type": "array",
         "items": {
          "type": "object",
          "properties": {
           "skipCause": {
            "oneOf": [
             {
              "$ref": "#/components/schemas/SkipCause"
             },
             {
              "type": "null"
             }
            ],
            "description": "A skipped slot's cause; null for other slots and until the slot is classified."
           },
           "slotMs": {
            "type": [
             "number",
             "null"
            ],
            "description": "A block's duration, ms: its producer timestamp minus its parent's, where the parent is the slot before and neither timestamp is clamped (on a window's first slot, the handoff from the previous leader). null otherwise and until the epoch is timed."
           }
          },
          "required": [
           "skipCause",
           "slotMs"
          ]
         }
        }
       }
      }
     },
     "skipClassification": {
      "oneOf": [
       {
        "$ref": "#/components/schemas/SkipClassification"
       },
       {
        "type": "null"
       }
      ],
      "description": "How skipCause / slotMs were computed; null until the skip-causes job has run for the epoch."
     }
    },
    "required": [
     "windows",
     "skipClassification"
    ],
    "description": "One producer's leader windows in one epoch, slot by slot. The skip-cause fields are listed here; the rest of the shape: see the `GET|POST /epochs/production/windows` section of https://api.vx.tools/llms.txt."
   },
   "Slot": {
    "type": "object",
    "properties": {
     "skipCause": {
      "oneOf": [
       {
        "$ref": "#/components/schemas/SkipCause"
       },
       {
        "type": "null"
       }
      ],
      "description": "A skipped Alpenglow slot's cause; null for other slots and until the slot is classified."
     }
    },
    "required": [
     "skipCause"
    ],
    "description": "One slot: its block, votes, certificates and producer. The skip-cause fields are listed here; the rest of the shape: see the `GET|POST /slot` section of https://api.vx.tools/llms.txt."
   },
   "ValidatorPace": {
    "type": "object",
    "description": "One validator's slot pace per epoch, newest first.",
    "properties": {
     "voteKey": {
      "type": "string"
     },
     "identity": {
      "type": "string",
      "description": "Today's."
     },
     "epochs": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/EpochPace"
      }
     }
    },
    "required": [
     "voteKey",
     "identity",
     "epochs"
    ]
   },
   "EpochPace": {
    "type": "object",
    "properties": {
     "epoch": {
      "type": "integer",
      "minimum": 0
     },
     "identity": {
      "type": "string",
      "description": "The identity the epoch is filed under."
     },
     "complete": {
      "type": "boolean",
      "description": "Classified through the epoch's last slot with the next epoch seen: these figures will not change."
     },
     "slotDuration": {
      "$ref": "#/components/schemas/SlotDuration",
      "description": "As /epochs/leaderboard/producers slotDuration for this producer (zero counts when it led no timed block)."
     },
     "skipCauses": {
      "$ref": "#/components/schemas/SkipCauseCounts"
     },
     "lagging": {
      "type": [
       "boolean",
       "null"
      ],
      "description": "In-window pace slower than the cluster's by the job's margin."
     },
     "cluster": {
      "$ref": "#/components/schemas/SlotDuration",
      "description": "The cluster's, as the board's cluster row (outgoing null: every handoff is both)."
     }
    },
    "required": [
     "epoch",
     "identity",
     "complete",
     "slotDuration",
     "skipCauses",
     "lagging",
     "cluster"
    ]
   },
   "ValidatorTips": {
    "type": "object",
    "properties": {
     "voteKey": {
      "type": "string"
     },
     "identity": {
      "type": "string",
      "description": "Today's node identity."
     },
     "epochs": {
      "type": "array",
      "description": "Newest first.",
      "items": {
       "$ref": "#/components/schemas/EpochTips"
      }
     }
    },
    "required": [
     "voteKey",
     "identity",
     "epochs"
    ]
   },
   "EpochTips": {
    "type": "object",
    "properties": {
     "epoch": {
      "type": "integer",
      "minimum": 0
     },
     "complete": {
      "type": "boolean",
      "description": "The epoch is over and every block ingested."
     },
     "identity": {
      "type": "string",
      "description": "The node identity the epoch is filed under."
     },
     "leaderSlots": {
      "type": "integer",
      "minimum": 0
     },
     "blocks": {
      "type": "integer",
      "minimum": 0
     },
     "skippedSlots": {
      "type": "integer",
      "minimum": 0
     },
     "blocksComplete": {
      "type": "boolean",
      "description": "blocks + skippedSlots covers leaderSlots."
     },
     "blockIncome": {
      "type": [
       "object",
       "null"
      ],
      "description": "The blocks' totals; null without a row.",
      "properties": {
       "baseFees": {
        "type": "integer",
        "minimum": 0
       },
       "priorityFees": {
        "type": "integer",
        "minimum": 0
       },
       "mevTips": {
        "type": "integer",
        "minimum": 0
       }
      }
     },
     "client": {
      "type": [
       "string",
       "null"
      ],
      "description": "Gossip's client name (AgaveBam, HarmonicFiredancer, ...)."
     },
     "clientSource": {
      "type": [
       "string",
       "null"
      ],
      "enum": [
       "recorded",
       "validatorHistory",
       "gossip",
       null
      ]
     },
     "bam": {
      "type": [
       "boolean",
       "null"
      ],
      "description": "Connected to Jito BAM in the epoch, per Jito."
     },
     "builder": {
      "type": "string",
      "description": "As /cluster/block-builders: jito-bam, jito-block-engine, harmonic, rakurai, paladin, raiku or none."
     },
     "builderName": {
      "type": "string"
     },
     "paths": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/TipPath"
      }
     },
     "total": {
      "$ref": "#/components/schemas/TipTotal"
     }
    },
    "required": [
     "epoch",
     "complete",
     "identity",
     "leaderSlots",
     "blocks",
     "skippedSlots",
     "blocksComplete",
     "blockIncome",
     "client",
     "clientSource",
     "bam",
     "builder",
     "builderName",
     "paths",
     "total"
    ]
   },
   "TipPath": {
    "type": "object",
    "description": "One tip path of one epoch. Lamports; null where a field does not apply or is not known yet.",
    "properties": {
     "path": {
      "type": "string",
      "enum": [
       "jitoTips",
       "jitoPriorityFees",
       "harmonic",
       "paladinP3",
       "rakuraiTips",
       "raikuTips",
       "bamBoost"
      ]
     },
     "basis": {
      "type": "string",
      "enum": [
       "exact",
       "unavailable"
      ],
      "description": "`unavailable`: not measurable (tips paid as priority fees) or not ingested yet; every figure null."
     },
     "gross": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0,
      "description": "What the path paid in the validator's blocks."
     },
     "builderFee": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0,
      "description": "The block builder's cut before the distribution account: gross - distributed (a complete epoch)."
     },
     "distributed": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0,
      "description": "What the distribution account held for the tip router to split."
     },
     "protocolFee": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0,
      "description": "Jito's tip router fee."
     },
     "protocolFeeBps": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0
     },
     "validatorCut": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0,
      "description": "The validator's commission, paid to its vote account."
     },
     "stakers": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0,
      "description": "Paid to the vote account's stake accounts."
     },
     "commissionBps": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0,
      "description": "The validator's commission rate on the path."
     },
     "builder": {
      "type": [
       "string",
       "null"
      ],
      "description": "The builder the path's tips came through."
     },
     "unit": {
      "type": "string",
      "enum": [
       "lamports",
       "jitoSol"
      ],
      "description": "lamports, or jitoSol (JitoSOL base units, 9 decimals: bamBoost)."
     },
     "claim": {
      "oneOf": [
       {
        "$ref": "#/components/schemas/BamBoostClaim"
       },
       {
        "type": "null"
       }
      ],
      "description": "bamBoost only: whether the identity claimed it; null elsewhere and when it was not allotted any."
     },
     "source": {
      "type": "string",
      "description": "Where the figures come from, or why there are none."
     }
    },
    "required": [
     "path",
     "basis",
     "gross",
     "builderFee",
     "distributed",
     "protocolFee",
     "protocolFeeBps",
     "validatorCut",
     "stakers",
     "commissionBps",
     "builder",
     "unit",
     "claim",
     "source"
    ]
   },
   "BamBoostClaim": {
    "type": "object",
    "description": "A BAM Boost allotment's claim state.",
    "properties": {
     "state": {
      "type": "string",
      "enum": [
       "claimed",
       "claimable",
       "expired"
      ],
      "description": "claimed, claimable (open through claimEndEpoch) or expired (not claimed in time: forfeited)."
     },
     "claimed": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0,
      "description": "What it claimed, JitoSOL base units; null until it claims."
     },
     "claimEndEpoch": {
      "type": "integer",
      "minimum": 0,
      "description": "The last epoch Jito's distributor accepts the claim."
     }
    },
    "required": [
     "state",
     "claimed",
     "claimEndEpoch"
    ]
   },
   "TipTotal": {
    "type": "object",
    "description": "The exact paths summed, field by field (null where none has the field).",
    "properties": {
     "gross": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0
     },
     "builderFee": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0
     },
     "protocolFee": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0
     },
     "validatorCut": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0
     },
     "stakers": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0
     }
    },
    "required": [
     "gross",
     "builderFee",
     "protocolFee",
     "validatorCut",
     "stakers"
    ]
   },
   "ValidatorTipBlocks": {
    "type": "object",
    "properties": {
     "voteKey": {
      "type": "string"
     },
     "epoch": {
      "type": "integer",
      "minimum": 0
     },
     "identity": {
      "type": "string",
      "description": "The identity that led the epoch's slots."
     },
     "complete": {
      "type": "boolean"
     },
     "client": {
      "type": [
       "string",
       "null"
      ]
     },
     "builder": {
      "type": "string"
     },
     "builderName": {
      "type": "string"
     },
     "builderTips": {
      "type": [
       "string",
       "null"
      ],
      "enum": [
       "tipAccounts",
       "priorityFees",
       "ownTipAccounts",
       null
      ],
      "description": "Where the builder's own tips are in each block, as /cluster/block-builders' tips."
     },
     "leaderSlots": {
      "type": "integer",
      "minimum": 0
     },
     "skippedSlots": {
      "type": "integer",
      "minimum": 0
     },
     "pendingSlots": {
      "type": "integer",
      "minimum": 0,
      "description": "Leader slots not ingested (or still to come)."
     },
     "blocks": {
      "type": "array",
      "description": "Produced blocks, slot ascending.",
      "items": {
       "$ref": "#/components/schemas/BlockTips"
      }
     }
    },
    "required": [
     "voteKey",
     "epoch",
     "identity",
     "complete",
     "client",
     "builder",
     "builderName",
     "builderTips",
     "leaderSlots",
     "skippedSlots",
     "pendingSlots",
     "blocks"
    ]
   },
   "BlockTips": {
    "type": "object",
    "properties": {
     "slot": {
      "type": "integer",
      "minimum": 0
     },
     "time": {
      "type": [
       "integer",
       "null"
      ],
      "description": "Unix seconds."
     },
     "baseFees": {
      "type": "integer",
      "minimum": 0
     },
     "priorityFees": {
      "type": "integer",
      "minimum": 0
     },
     "mevTips": {
      "type": "integer",
      "minimum": 0,
      "description": "Transfers to Jito's tip-payment accounts in the block (jitoTips gross)."
     }
    },
    "required": [
     "slot",
     "time",
     "baseFees",
     "priorityFees",
     "mevTips"
    ]
   }
  },
  "headers": {
   "CacheControl": {
    "description": "How long the answer may be reused: e.g. `public, max-age=600` for a completed epoch's leaderboards, 15 s while an epoch is in progress, a day for a stored leader schedule, `no-store` on errors and 404s. Per-endpoint values are in the descriptions and in llms.txt.",
    "schema": {
     "type": "string"
    }
   },
   "CacheControlStatic": {
    "description": "The static documents: `public, max-age=300`.",
    "schema": {
     "type": "string",
     "const": "public, max-age=300"
    }
   },
   "XRobotsTag": {
    "description": "Keeps raw JSON out of search indexes; agents are welcome (robots.txt allows all).",
    "schema": {
     "type": "string",
     "const": "noindex"
    }
   },
   "VortexBuild": {
    "description": "The git commit of the server that answered.",
    "schema": {
     "type": "string"
    }
   }
  },
  "responses": {
   "Error": {
    "description": "400 for a missing required parameter or an unusable non-identifier one (a limit out of range, an unknown kind, conflicting parameters), 404 when an identifier names nothing (see NotFound) or nothing is stored for the request (it may arrive later), 403 for operator-only routes, 500 when storage could not be read. The body is JSON `null` (or a short text message for a rejected parameter); `Cache-Control: no-store`.",
    "content": {
     "application/json": {
      "schema": {
       "type": "null"
      }
     },
     "text/plain": {
      "schema": {
       "type": "string"
      }
     }
    }
   },
   "NotFound": {
    "description": "The identifier names nothing: malformed (not base58, the wrong length, not a number), out of range (SIMD 999999) or unknown; or nothing is stored for it yet. The body is the endpoint's error body (JSON `null`, an empty array, or a short text message); `Cache-Control: no-store`.",
    "content": {
     "application/json": {
      "schema": {}
     },
     "text/plain": {
      "schema": {
       "type": "string"
      }
     }
    }
   }
  },
  "securitySchemes": {
   "adminToken": {
    "type": "http",
    "scheme": "bearer",
    "description": "The instance's admin token (VORTEX_ADMIN_TOKEN). Operators only; not issued to anyone else."
   }
  }
 }
}
