{
  "openapi": "3.1.0",
  "info": {
    "title": "Stocks On Chain API",
    "version": "1.0.0",
    "summary": "Tokenized stock data, free and keyless.",
    "description": "Static JSON describing every tokenized stock we track: the stock, each instrument (one per issuer, with the legal wrapper and corporate-action mechanic), each listing under it (chain, contract address), prices with timestamps, and corporate actions read from chain state. No authentication, no rate limit, CORS open. Nothing in this API ranks or rates anything; every ordered collection states its own sortKey.",
    "contact": {
      "name": "Gwei, Inc.",
      "email": "gweistocksonchain@gmail.com",
      "url": "https://stocksonchain.io"
    },
    "license": {
      "name": "CC BY 4.0",
      "url": "https://creativecommons.org/licenses/by/4.0/"
    }
  },
  "servers": [
    {
      "url": "https://stocksonchain.io"
    }
  ],
  "externalDocs": {
    "description": "Agent and API documentation",
    "url": "https://stocksonchain.io/developers/agents"
  },
  "components": {
    "schemas": {
      "Mechanics": {
        "description": "How one issuer handles corporate actions for a stock. A tagged union - read `kind` before reaching for any other field. Anything that is not erc8056 has no multiplier at all; the field is structurally absent, not null and not 1.0. `kind` is the shape reported here, NOT the standard a contract implements: only Robinhood tokens implement ERC-8056, Ondo publishes the same figure from a separate oracle, Backed reads it from its own token functions on EVM chains and from a Token-2022 extension on Solana, and Coinbase B20 tokens answer multiplier() and do not answer uiMultiplier().",
        "oneOf": [
          {
            "type": "object",
            "title": "erc8056",
            "required": [
              "kind",
              "multiplier",
              "supplyUI"
            ],
            "properties": {
              "kind": {
                "const": "erc8056"
              },
              "multiplier": {
                "type": "number"
              },
              "supplyUI": {
                "type": "number"
              },
              "supplyDerived": {
                "type": "boolean"
              },
              "pending": {
                "type": [
                  "object",
                  "null"
                ]
              },
              "events": {
                "type": "array",
                "items": {
                  "type": "object"
                }
              },
              "multiplierGrowthPct": {
                "type": [
                  "number",
                  "null"
                ]
              }
            }
          },
          {
            "type": "object",
            "title": "distribution",
            "required": [
              "kind"
            ],
            "properties": {
              "kind": {
                "const": "distribution"
              },
              "lastDistribution": {
                "type": [
                  "object",
                  "null"
                ]
              },
              "splitMultiplier": {
                "type": "number"
              }
            }
          }
        ]
      }
    }
  },
  "paths": {
    "/api/tokens.json": {
      "get": {
        "operationId": "listTokens",
        "summary": "Every tokenized stock, with every instrument and listing",
        "description": "The full snapshot. Each stock carries an instruments array (one per issuer) and a listings array (one per issuer and chain). An issuer can put the same product on several chains, so instruments answer what the options are and listings answer what the address is on a given chain. Stocks are alphabetical by ticker. On each listing, price, marketCap, volume24h, holders and transfers carry their read time in a matching *At field.",
        "responses": {
          "200": {
            "description": "Snapshot of all stocks and listings.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/api/tokens/{slug}.json": {
      "get": {
        "operationId": "getToken",
        "summary": "One stock",
        "description": "One stock, its listings, the events recorded against it, holder concentration and a daily history rollup.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Lowercase ticker, for example `nvda`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "One stock and everything known about it.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "404": {
            "description": "No stock with that slug is tracked."
          }
        }
      }
    },
    "/api/events.json": {
      "get": {
        "operationId": "listEvents",
        "summary": "Corporate actions",
        "description": "Splits, distributions and multiplier changes read from chain state, each with a transaction hash, plus scheduled changes whose effective time is after the snapshot read time. Events are ordered by when each took effect, newest first; scheduled changes soonest first. That is chronology, not a ranking.",
        "responses": {
          "200": {
            "description": "The corporate-action tape.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/api/tradfi.json": {
      "get": {
        "operationId": "listTradfiTickers",
        "summary": "Every ticker on the old market",
        "description": "Ticker and company name for the whole listed market, from the SEC's own company_tickers.json. This is what lets a consumer answer \"that is a real stock, and it is not tokenized yet\" instead of returning nothing.",
        "responses": {
          "200": {
            "description": "Ticker index.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/api/tickers.json": {
      "get": {
        "operationId": "listOnChainTickers",
        "summary": "Every stock on chain, one short row each",
        "description": "The lookup behind \"is my stock on chain?\". Each row is [ticker, slug, company, chains, issuerCount, tokenCount]; the field names are in `shape`, and `chains` maps each chain slug to its name. Alphabetical by ticker, chains in registry order. No prices, so nothing in it goes stale faster than the registry. Use /api/tokens/{slug}.json for figures.",
        "responses": {
          "200": {
            "description": "On-chain ticker index.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/api/history/totals.json": {
      "get": {
        "operationId": "listHistoryTotals",
        "summary": "Daily totals across the stocks that reported that day",
        "description": "One row per UTC day: market value, 24h volume and holder count summed across the stocks that reported that day (stocksReported), with per-issuer and per-chain totals where recorded. Money figures dated 2026-09-18 or earlier are null and carry a withdrawn reason: they were a market data provider’s, and this site publishes only what it reads itself. Holder counts are unaffected. Ordered by date ascending - that is chronology, not a ranking. Every figure is a level read that day, never a delta. stocksReported changes when coverage expands; compare only days of equal coverage.",
        "responses": {
          "200": {
            "description": "The daily aggregate series.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/api/history/{slug}.json": {
      "get": {
        "operationId": "getStockHistory",
        "summary": "Daily rows for one stock",
        "description": "The per-day series for one stock: price, multiplier, share-equivalent supply, holders, volume and market value, one row per UTC day. The same rows ship inside /api/tokens/{slug}.json as dailyHistory; this is the series alone.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Lowercase ticker, for example `nvda`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The daily rows for one stock.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "404": {
            "description": "No stock with that slug is tracked."
          }
        }
      }
    },
    "/api/agent/manifest.json": {
      "get": {
        "operationId": "getAgentManifest",
        "summary": "Agent tier terms",
        "description": "The free endpoints, the metered bulk resources, and their prices if the paid tier is live. Never metered itself: it is how a caller learns what the prices are.",
        "responses": {
          "200": {
            "description": "Machine-readable tier descriptor.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/api/agent/dataset.json": {
      "get": {
        "operationId": "getDataset",
        "summary": "Bulk dataset",
        "description": "The current state of everything this site reads for itself, in one request: supply, proven holder counts, corporate-action mechanics, the chains matrix, annualised multiplier growth, the corporate-action tape and the daily aggregate series. Every holder and transfer figure is a proven read; the payload's holderScope block names the chains covered and the method, and an absent field means not proven, never zero. No price, no volume, no market value. Currently free. The paid tier is not live, and no date is set. The same data is free either way at: Four free requests: /api/tokens.json, /api/events.json, /api/history/totals.json and /api/registry.json. Those carry the same figures AND the price and market value this feed leaves out. If it goes live, paying will accept the terms at https://stocksonchain.io/developers/terms for that request; the licence does not change and stays CC BY 4.0.",
        "responses": {
          "200": {
            "description": "The current state of everything this site reads for itself, in one request: supply, proven holder counts, corporate-action mechanics, the chains matrix, annualised multiplier growth, the corporate-action tape and the daily aggregate series. Every holder and transfer figure is a proven read; the payload's holderScope block names the chains covered and the method, and an absent field means not proven, never zero. No price, no volume, no market value.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/api/agent/history.json": {
      "get": {
        "operationId": "getBulkHistory",
        "summary": "Bulk daily history",
        "description": "The daily series of every stock that has one, in one request: one row per UTC day per stock, with the share-equivalent supply, the multiplier and the holder count where recorded. Levels read that day, never deltas; the payload's holderScope block states the holder-count provenance and its date boundary. No price, no volume, no market value. Currently free. The paid tier is not live, and no date is set. The same data is free either way at: One free request per stock at /api/history/{slug}.json, one for each stock with rows. The payload's coverage block states how many that is. Those carry the same rows AND the price and market value this feed leaves out. If it goes live, paying will accept the terms at https://stocksonchain.io/developers/terms for that request; the licence does not change and stays CC BY 4.0.",
        "responses": {
          "200": {
            "description": "The daily series of every stock that has one, in one request: one row per UTC day per stock, with the share-equivalent supply, the multiplier and the holder count where recorded. Levels read that day, never deltas; the payload's holderScope block states the holder-count provenance and its date boundary. No price, no volume, no market value.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  }
}