{
  "generated_on": "2026-10-24",
  "latest_change": "2026-10-12",
  "policy": {
    "sunset_window_days": 30,
    "tombstone_keep_days": 365,
    "headers": [
      "Deprecation",
      "Sunset",
      "Link"
    ],
    "versions": "The bare path is v1 and /v1/x/ the same route with its version; /v2/ carries the routes whose shape changed; a shape never changes in place.",
    "discord": "https://discord.gg/kusanagi-ventures"
  },
  "deprecated": [
    {
      "path": "/v1/portfolio-baskets/",
      "field": null,
      "both_mounts": false,
      "announced": "2026-10-12",
      "sunset": "2026-11-11",
      "days_left": 18,
      "replacement": null,
      "note": "What each beta basket owes one coldkey, copied from the chain once a night. The live figure is the chain's own: `BetaBasketRuntimeApi.get_root_basket_positions` answers the owed shares and payout of every fund for a coldkey."
    },
    {
      "path": "/validators/{hotkey}/",
      "field": null,
      "both_mounts": true,
      "announced": "2026-10-12",
      "sunset": "2026-11-11",
      "days_left": 18,
      "replacement": "/v2/validators/{hotkey}/",
      "note": "One validator with its subnets, history and delegators. `/v2/validators/{hotkey}/` serves the same body, except that `delegators` is one page (100 rows by default, 500 at most) with a `delegators_pagination` envelope; walk `page` or the `after` cursor where you need every delegator."
    },
    {
      "path": "/idle-stakes/",
      "field": null,
      "both_mounts": true,
      "announced": "2026-08-30",
      "sunset": "2026-11-28",
      "days_left": 35,
      "replacement": null,
      "note": "The global per-subnet idle-stake aggregate. `/idle-stakes/lookup/` is NOT a replacement and is not going anywhere: it answers one coldkey's delegations, not the network aggregate."
    },
    {
      "path": "/portfolio-apy-history/",
      "field": null,
      "both_mounts": true,
      "announced": "2026-09-08",
      "sunset": "2026-12-07",
      "days_left": 44,
      "replacement": "/portfolio-pnl-apy/",
      "note": "The daily APY series of one coldkey. `/portfolio-pnl-apy/` serves the current windows and says when they close (`apy_as_of`); the day-by-day series has no public successor."
    },
    {
      "path": "/portfolio-income/",
      "field": null,
      "both_mounts": true,
      "announced": "2026-09-08",
      "sunset": "2026-12-07",
      "days_left": 44,
      "replacement": "/portfolio-pnl-apy/",
      "note": "Income by source over 7d/30d. `/portfolio-pnl-apy/` serves the organic half (`apy.value_change_*`) over the same windows; the windowed `trading` bucket (realized PnL diffed over 7d/30d) has no successor."
    },
    {
      "path": "/v1/root-weights/",
      "field": null,
      "both_mounts": false,
      "announced": "2026-09-18",
      "sunset": "2026-12-17",
      "days_left": 54,
      "replacement": "/v1/beta-baskets/composition/",
      "note": "Every root validator's published basket vector. The chain retired the mechanism at runtime 464: no vector exists or can be published, and `/v1/beta-baskets/composition/` serves what each fund actually holds."
    },
    {
      "path": "/portfolio-pnl-apy/subnet/",
      "field": null,
      "both_mounts": true,
      "announced": "2026-10-08",
      "sunset": "2027-01-06",
      "days_left": 74,
      "replacement": "/portfolio-pnl-apy/?include_subnets=true",
      "note": "One coldkey's APY and PnL on one subnet. `/portfolio-pnl-apy/?include_subnets=true` serves the same entry for every subnet the coldkey holds, under `subnets[]`; read the one whose `netuid` you need."
    },
    {
      "path": "/subnets/{netuid}/",
      "field": "neurons[].weights",
      "both_mounts": true,
      "announced": "2026-10-08",
      "sunset": "2027-01-06",
      "days_left": 74,
      "replacement": "/metagraph/{netuid}/weights/",
      "note": "Each neuron's own weight vector. `/metagraph/{netuid}/weights/` serves the subnet's weights, named and paginated."
    },
    {
      "path": "/v1/limit-orders/",
      "field": "results[].executed_tx_hash",
      "both_mounts": false,
      "announced": "2026-10-08",
      "sunset": "2027-01-06",
      "days_left": 74,
      "replacement": null,
      "note": "Always `\"\"`. `executed_block` and `executed_extrinsic_index` locate the fill; the field leaves every order row, `/v1/limit-orders/{order_id}/` and the cancel's answer included."
    },
    {
      "path": "/v2/subnets/{netuid}/",
      "field": "neurons[].weights",
      "both_mounts": false,
      "announced": "2026-10-08",
      "sunset": "2027-01-06",
      "days_left": 74,
      "replacement": "/metagraph/{netuid}/weights/",
      "note": "Each neuron's own weight vector. `/metagraph/{netuid}/weights/` serves the subnet's weights, named and paginated."
    }
  ],
  "changes": [
    {
      "on": "2026-10-12",
      "kind": "deprecated",
      "paths": [
        "/v1/portfolio-baskets/"
      ],
      "field": null,
      "summary": "A nightly copy of the beta-basket positions the chain answers live; nothing in the API replaces it.",
      "action": "Read `BetaBasketRuntimeApi.get_root_basket_positions` on chain for a coldkey's owed shares and payout.",
      "anchor": "2026-10-12-deprecated-v1-portfolio-baskets",
      "removal": "2026-11-11"
    },
    {
      "on": "2026-10-12",
      "kind": "deprecated",
      "paths": [
        "/validators/{hotkey}/",
        "/v1/validators/{hotkey}/"
      ],
      "field": null,
      "summary": "`/v2/validators/{hotkey}/` serves the same validator with its `delegators` one page at a time; the list and `/history/` stay.",
      "action": "Move to `/v2/validators/{hotkey}/`, and walk `page` or the `after` cursor where you need every delegator.",
      "anchor": "2026-10-12-deprecated-validators-id",
      "removal": "2026-11-11"
    },
    {
      "on": "2026-10-08",
      "kind": "deprecated",
      "paths": [
        "/subnets/{netuid}/",
        "/v1/subnets/{netuid}/",
        "/v2/subnets/{netuid}/"
      ],
      "field": "neurons[].weights",
      "summary": "The subnet detail keeps serving each neuron's weight vector until the sunset, then leaves it out; the route stays.",
      "action": "Read `/metagraph/{netuid}/weights/` for the subnet's weights.",
      "anchor": "2026-10-08-deprecated-subnets-id-neurons-weights",
      "removal": "2027-01-06"
    },
    {
      "on": "2026-10-08",
      "kind": "deprecated",
      "paths": [
        "/v1/limit-orders/"
      ],
      "field": "results[].executed_tx_hash",
      "summary": "Always `\"\"` on every order row; it leaves the rows at the sunset, the routes stay. These routes are not in the reference.",
      "action": "Locate a fill by `executed_block` and `executed_extrinsic_index`.",
      "anchor": "2026-10-08-deprecated-v1-limit-orders-results-executed-tx-hash",
      "removal": "2027-01-06"
    },
    {
      "on": "2026-10-08",
      "kind": "deprecated",
      "paths": [
        "/portfolio-pnl-apy/subnet/",
        "/v1/portfolio-pnl-apy/subnet/"
      ],
      "field": null,
      "summary": "`/portfolio-pnl-apy/?include_subnets=true` serves the same per-subnet entry under `subnets[]`, for every subnet at once.",
      "action": "Move to `/portfolio-pnl-apy/?include_subnets=true` and read the `subnets[]` entry of your `netuid`.",
      "anchor": "2026-10-08-deprecated-portfolio-pnl-apy-subnet",
      "removal": "2027-01-06"
    },
    {
      "on": "2026-09-18",
      "kind": "deprecated",
      "paths": [
        "/v1/root-weights/"
      ],
      "field": null,
      "summary": "Runtime 464 retired root-weight vectors on 2026-09-17: `results[].entries` is empty for every validator and stays so.",
      "action": "Read `/v1/beta-baskets/composition/` for what each fund holds, or `/v1/beta-baskets/subnets/` for the per-subnet view.",
      "anchor": "2026-09-18-deprecated-v1-root-weights",
      "removal": "2026-12-17"
    },
    {
      "on": "2026-09-08",
      "kind": "deprecated",
      "paths": [
        "/portfolio-income/",
        "/v1/portfolio-income/"
      ],
      "field": null,
      "summary": "`/portfolio-pnl-apy/` serves the organic half (`apy.value_change_*`); the windowed `trading` bucket has no successor.",
      "action": "Move to `/portfolio-pnl-apy/`, or say on Discord what the trading bucket was for.",
      "anchor": "2026-09-08-deprecated-portfolio-income",
      "removal": "2026-12-07"
    },
    {
      "on": "2026-09-08",
      "kind": "deprecated",
      "paths": [
        "/portfolio-apy-history/",
        "/v1/portfolio-apy-history/"
      ],
      "field": null,
      "summary": "`/portfolio-pnl-apy/` serves the current windows and `apy_as_of`; the day-by-day series has no successor.",
      "action": "Move to `/portfolio-pnl-apy/`, or say on Discord if you need the series.",
      "anchor": "2026-09-08-deprecated-portfolio-apy-history",
      "removal": "2026-12-07"
    },
    {
      "on": "2026-08-30",
      "kind": "deprecated",
      "paths": [
        "/idle-stakes/",
        "/v1/idle-stakes/"
      ],
      "field": null,
      "summary": "`/idle-stakes/lookup/` (one coldkey's delegations) is not affected and is not a replacement.",
      "action": "Stop calling it before the removal date; nothing serves the aggregate after.",
      "anchor": "2026-08-30-deprecated-idle-stakes",
      "removal": "2026-11-28"
    }
  ]
}