{
  "openapi": "3.1.0",
  "info": {
    "title": "BaseStocks API",
    "version": "1.0.0",
    "description": "Read-only data on Coinbase Tokenized Stocks (B20) on Base.\n\nFree endpoints need no key, no headers and no account. Two endpoints that cost real work to produce are priced per call in USDC over x402.\n\n**One token is not one share.** Every stock carries a multiplier that moves on splits and dividends. Share-equivalents are rawBalance × multiplier ÷ 1e18. The portfolio endpoint returns both so no conversion is guessed.\n**The Chainlink reference is a total-return value.** Coinbase's feeds report total return, not the raw equity price. It is returned as reference.totalReturnUsd, deliberately not named a price: comparing it with dexPriceUsd and calling the gap an arbitrage is a mistake.\n**Feeds run 24/5 and then hold.** Outside US trading hours, and during a corporate action, a feed stops updating and keeps its last value while staying callable. Read reference.updatedAt and reference.isStale before relying on it.\n**A pool is not automatically a price.** dexPriceUsd is read only from a pool quoted in USDC or ETH, and only counts as displayUsd when it is within 20% of a live reference. A pool prices a token against whatever is on its other side, so a pair quoted in a long-tail token reports that token's valuation: one such pair had a stock reading 49x its reference. When the check refuses the market price, displaySource is \"reference\" even though dexPriceUsd is present.\n**Identity is the address.** Names and symbols are mutable onchain metadata. Symbols are accepted for convenience, but store the address.",
    "contact": {
      "url": "https://basestocks.finance/developers"
    }
  },
  "servers": [
    {
      "url": "https://basestocks.finance"
    }
  ],
  "paths": {
    "/api/v1/stocks": {
      "get": {
        "summary": "Every listed tokenized stock: DEX price, Chainlink reference, liquidity, 24h volume, multiplier and trading status.",
        "operationId": "api_v1_stocks",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "404": {
            "description": "No such stock or wallet"
          }
        }
      }
    },
    "/api/v1/stocks/{symbol}": {
      "get": {
        "summary": "One stock by ticker, token symbol or contract address, with the pools that trade it.",
        "operationId": "api_v1_stocks_symbol",
        "parameters": [
          {
            "name": "symbol",
            "in": "path",
            "required": true,
            "description": "Ticker (\"NVDA\"), token symbol (\"NVDAc\") or 0x address.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "404": {
            "description": "No such stock or wallet"
          }
        }
      }
    },
    "/api/v1/news": {
      "get": {
        "summary": "Headlines: one stock's wire, the market desks, or the Base and Coinbase tokenized-stock feed. Titles and links only.",
        "operationId": "api_v1_news",
        "parameters": [
          {
            "name": "scope",
            "in": "query",
            "required": false,
            "description": "\"ecosystem\" (default) or \"market\". Ignored when symbol is given.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "symbol",
            "in": "query",
            "required": false,
            "description": "Ticker, for that stock's own headlines.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "1–30, default 10.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "404": {
            "description": "No such stock or wallet"
          }
        }
      }
    },
    "/api/v1/earn": {
      "get": {
        "summary": "Where idle USDC can earn on Base: venue, variable APY, TVL and risk notes, discovered live from the protocols.",
        "operationId": "api_v1_earn",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "404": {
            "description": "No such stock or wallet"
          }
        }
      }
    },
    "/api/v1/portfolio/{address}": {
      "get": {
        "summary": "Any wallet's tokenized-stock position, read from the chain — raw balances and share-equivalents side by side.",
        "operationId": "api_v1_portfolio_address",
        "parameters": [
          {
            "name": "address",
            "in": "path",
            "required": true,
            "description": "0x-prefixed wallet address.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "404": {
            "description": "No such stock or wallet"
          }
        }
      }
    },
    "/api/v1/stats": {
      "get": {
        "summary": "What has been done through the app, counted from records verified against a receipt on Base.",
        "operationId": "api_v1_stats",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "404": {
            "description": "No such stock or wallet"
          }
        }
      }
    },
    "/api/v1/pro/report": {
      "get": {
        "summary": "The written market brief with the prices behind it. $0.10 in USDC per call — it is backed by a model, so every call has a cost a cache cannot remove.",
        "operationId": "api_v1_pro_report",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "402": {
            "description": "Payment required: $0.10 in USDC over x402. The response carries the amount, asset, network and recipient; sign it and retry the same request."
          },
          "404": {
            "description": "No such stock or wallet"
          }
        },
        "security": [
          {
            "x402": []
          }
        ]
      }
    },
    "/api/v1/pro/history/{symbol}": {
      "get": {
        "summary": "Full candle history for one stock, labelled with its source. $0.10 in USDC per call.",
        "operationId": "api_v1_pro_history_symbol",
        "parameters": [
          {
            "name": "symbol",
            "in": "path",
            "required": true,
            "description": "Ticker or 0x address.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "timeframe",
            "in": "query",
            "required": false,
            "description": "1D, 1W, 1M (default), 3M or 1Y.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "402": {
            "description": "Payment required: $0.10 in USDC over x402. The response carries the amount, asset, network and recipient; sign it and retry the same request."
          },
          "404": {
            "description": "No such stock or wallet"
          }
        },
        "security": [
          {
            "x402": []
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "Envelope": {
        "type": "object",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "description": "The endpoint's payload."
          },
          "meta": {
            "type": "object",
            "properties": {
              "generatedAt": {
                "type": "integer",
                "description": "Unix ms when this body was built."
              },
              "cacheSeconds": {
                "type": "integer",
                "description": "How long this body may be reused; the CDN honours the same number."
              },
              "docs": {
                "type": "string"
              }
            }
          }
        }
      }
    },
    "securitySchemes": {
      "x402": {
        "type": "http",
        "scheme": "x402",
        "description": "Pay-per-call in USDC on base. An unpaid request answers 402 with the payment requirements; sign the authorization and retry. Settlement happens only after a successful response, so a failed call costs nothing."
      }
    }
  }
}