{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/base167-com/json-schema/base167-com-season-config-schema.json",
  "title": "SeasonConfig",
  "description": "The season's settings and addresses. Everything that decides WHO may enter and WHEN. Until 2026-08-29 this was published as a bare {\"type\":\"object\"}, so the single richest object in the API was undocumented. Timestamps are unix seconds; amounts are raw integer strings in the token's own decimals, never floats.",
  "x-generated": "2026-11-02",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/base167-com-openapi.json#/components/schemas/SeasonConfig",
  "type": "object",
  "properties": {
    "season": {
      "type": "integer",
      "description": "Season number. Seasons are sequential and only one is current."
    },
    "chainId": {
      "type": "integer",
      "const": 8453,
      "description": "Base mainnet."
    },
    "base167": {
      "$ref": "#/$defs/Address",
      "description": "The BASE167 token."
    },
    "factory": {
      "$ref": "#/$defs/Address",
      "description": "SeasonFactory: claimEntry, enroll and claimWinner all target this."
    },
    "entryNFT": {
      "$ref": "#/$defs/Address",
      "description": "This season's Entry pass (ERC-721)."
    },
    "winnersNFT": {
      "$ref": "#/$defs/Address",
      "description": "This season's Winner badge (ERC-721). Minting one moves no value."
    },
    "usdc": {
      "$ref": "#/$defs/Address",
      "description": "The USDC contract scoring is measured in."
    },
    "entryMarketplaceUrl": {
      "type": "string",
      "description": "Where Entry passes can be bought or sold during seatMarket."
    },
    "exclusions": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/Address"
      },
      "description": "Addresses removed from the holder snapshot by design: the treasury, the burn address, the token itself and the liquidity pool."
    },
    "snapshotAt": {
      "type": "integer",
      "description": "Unix seconds. The holder snapshot is taken; the Entry pass becomes claimable."
    },
    "enrollOpenAt": {
      "type": "integer",
      "description": "Unix seconds. Enrolment opens."
    },
    "enrollCloseAt": {
      "type": "integer",
      "description": "Unix seconds. Enrolment closes."
    },
    "openingBellAt": {
      "type": "integer",
      "description": "Unix seconds. Trading starts and the competition wallet is judged on its balances."
    },
    "closingBellAt": {
      "type": "integer",
      "description": "Unix seconds. Trading ends; scoring and publication follow."
    },
    "snapshotBlock": {
      "type": [
        "integer",
        "null"
      ],
      "description": "Block the snapshot was pinned to. Null until the job runs; written once and never changed."
    },
    "startBlock": {
      "type": [
        "integer",
        "null"
      ],
      "description": "Block the opening bell was pinned to. Null until the bell; one-shot."
    },
    "closingBlock": {
      "type": [
        "integer",
        "null"
      ],
      "description": "Block the closing bell was pinned to. Null until the bell; one-shot."
    },
    "topHolders": {
      "type": "integer",
      "description": "ELIGIBILITY: how many wallets may claim an Entry pass. Read this rather than assuming a number -- it has changed between seasons."
    },
    "displayHolders": {
      "type": "integer",
      "description": "DISPLAY ONLY: how many rows the site renders. Not an eligibility bound. Do not confuse it with topHolders."
    },
    "displayRoster": {
      "type": "integer",
      "description": "DISPLAY ONLY: how many enrolled rows the site resolves and renders."
    },
    "winnersCount": {
      "type": "integer",
      "description": "How many places count as winners: each mints a rank-stamped Winner badge and takes a Finals seat. NOT how many are PAID -- only the podium is paid."
    },
    "minStakeUSDC": {
      "type": "string",
      "description": "Raw USDC (6dp) a competition wallet must hold at the opening bell. \"5000000\" is $5. There is no ceiling: ranking is by percentage return, so a larger stake buys no advantage."
    },
    "stakeToleranceUSDC": {
      "type": "string",
      "description": "Raw USDC (6dp) of slack allowed under minStakeUSDC. \"500000\" is $0.50."
    },
    "gasAllowanceWei": {
      "type": "string",
      "description": "Maximum native ETH, in wei, the competition wallet may hold at the opening bell. \"200000000000000\" is 0.0002 ETH. More than this is a disqualification."
    },
    "finalsCollectorSeats": {
      "type": "integer",
      "description": "How many Finals seats are drawn from the collector board."
    },
    "base167DeployBlock": {
      "type": "integer",
      "description": "Block the BASE167 token was deployed at. The floor for any log scan -- start here rather than at block 0, or an eth_getLogs range will be rejected."
    },
    "entryNFTDeployBlock": {
      "type": [
        "integer",
        "null"
      ],
      "description": "Block this season's EntryNFT was deployed at, and the floor for any scan of ITS logs. Optional: a season synced before 2026-09-02 has no pin and falls back to base167DeployBlock, which is correct but scans a far wider range."
    },
    "prizePotBase167": {
      "type": "integer",
      "description": "The season prize pot in WHOLE BASE167 (not wei). Paid to the podium only. Always stated in BASE167 and never as a cash value."
    },
    "prizeBreakdown": {
      "type": "array",
      "description": "The podium split. Sums to prizePotBase167 and descends strictly. Places outside it mint a Winner badge and take a Finals seat but are paid nothing.",
      "items": {
        "type": "object",
        "required": [
          "place",
          "amount"
        ],
        "properties": {
          "place": {
            "type": "integer"
          },
          "amount": {
            "type": "integer",
            "description": "Whole BASE167."
          }
        }
      }
    }
  },
  "required": [
    "season",
    "chainId",
    "factory",
    "entryNFT",
    "winnersNFT",
    "snapshotAt",
    "enrollOpenAt",
    "enrollCloseAt",
    "openingBellAt",
    "closingBellAt",
    "topHolders",
    "winnersCount",
    "minStakeUSDC",
    "gasAllowanceWei",
    "prizePotBase167",
    "prizeBreakdown"
  ],
  "$defs": {
    "Address": {
      "type": "string",
      "pattern": "^0x[a-fA-F0-9]{40}$",
      "description": "A mixed-case address MUST carry a valid EIP-55 checksum; an all-lowercase address is always accepted. A correctly-shaped address with a bad checksum returns 400 BAD_CHECKSUM."
    }
  }
}