No key and no account. Any origin may call it from a browser; any agent may read it from a chat. Reads are cached at the edge, so a thousand readers cost the app what one does.
Everything this app shows about tokenized stocks on Base, and the calls to trade them, as a public API. No key, no account, open CORS — and every endpoint on this page has a Try it that runs against the live deployment.
No key and no account. Any origin may call it from a browser; any agent may read it from a chat. Reads are cached at the edge, so a thousand readers cost the app what one does.
One POST returns the approval and the swap for a buy or a sell, from the router the app trades with. The user's own wallet signs and sends them; nothing is held for anyone.
Two endpoints back a model call or a heavy upstream read. Those cost $0.10 in USDC per call over x402; everything else is free.
| Base URL | https://basestocks.finance/api/v1 · JSON · Base mainnet (8453) |
|---|---|
| Keys | none · no account and no sign-up · the paid endpoints take an x402 payment instead of a key |
| CORS | open to every origin, GET and POST · a browser on any site may call it |
| Envelope | { data, meta } · meta.cacheSeconds says how long the body stays valid, and the CDN honours the same number |
| Errors | { error: { code, message, hint? } } with a 4xx or 5xx status · 402 carries the x402 payment requirements · 451 means the eligibility answer is missing |
| Amounts | integer strings in the smallest unit: USDC has 6 decimals, ETH 18; a stock token carries a multiplier, so read shares from the API rather than dividing yourself |
| Identity | a stock is its contract address; tickers and symbols are accepted and resolved to it |
| Signing | never on the server · /api/v1/trade returns calls for the user's own wallet, which signs and sends them |
| Eligibility | from a restricted country, /api/v1/trade answers 451 until the visitor confirms they are not a US person; a site that asks in its own UI sends x-bstocks-eligibility: confirmed, never on the visitor's behalf |
curl -s 'https://basestocks.finance/api/v1/stocks/NVDA'// 1. Ask for the calls. amount is what is sold, in its smallest unit: 10 USDC = 10000000.
const res = await fetch("https://basestocks.finance/api/v1/trade", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ stock: "NVDA", side: "buy", amount: "10000000", account, builderCode: "bc_yourcode" }),
});
const { data, error } = await res.json();
if (error) throw new Error(error.message);
// 2. The user's wallet sends them in order: the approval first, when there is one.
// A quote lives for data.expiresAt; ask again if the approval took longer.
for (const call of data.calls) {
const hash = await walletClient.sendTransaction({ account, to: call.to, data: call.data, value: BigInt(call.value) });
await publicClient.waitForTransactionReceipt({ hash });
}Tokenized stocks are not ordinary ERC-20s, and these have caught people out. The API returns each of them explicitly rather than leaving you to infer it.
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.
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.
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.
A newer stock may have no Chainlink feed yet. Its reference is null, displaySource is "market" and displayUsd is the pool price with nothing to check it against. Read liquidityUsd and status before relying on it: a pool of a few thousand dollars moves with a single trade.
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.
Names and symbols are mutable onchain metadata. Symbols are accepted for convenience, but store the address.
https://basestocks.finance/llms.txtllms-full.txt This whole reference in one text file: conventions, every parameter and error, curl lines, the trade example.https://basestocks.finance/llms-full.txtOpenAPI 3.1 Typed parameters and the trade body, for Swagger, Postman, a code generator or an agent's tool definitions.https://basestocks.finance/api/v1/openapi.jsonEndpoint index The catalog itself as JSON, with the payment details and the caveats.https://basestocks.finance/api/v1Ask your assistant: “Read https://basestocks.finance/llms-full.txt and tell me which tokenized stock on Base has the deepest liquidity right now.” The reads are plain GETs an assistant inside a chat can fetch; the trade builder is a POST for an app or an agent with a wallet.
Prices, references, liquidity, headlines, yield venues and platform totals. Free, cached at the edge, open to every origin.
/api/v1/stocksFreecached 30sEvery tokenized stock that can be traded right now (supply, a pool and a quote in both directions): DEX price, Chainlink reference where one exists, liquidity, 24h volume, multiplier and trading status.
curl -s 'https://basestocks.finance/api/v1/stocks'/api/v1/stocks/{symbol}Freecached 30sOne stock by ticker, token symbol or contract address, with the pools that trade it. Answers for any verified stock, including one that is not in the list above because it has no market yet.
| Name | In | Type | Description |
|---|---|---|---|
| symbol * | path | string | Ticker ("NVDA"), token symbol ("NVDAc") or 0x address. |
404 UNKNOWN_STOCKcurl -s 'https://basestocks.finance/api/v1/stocks/NVDA'/api/v1/newsFreecached 300sHeadlines: one stock's wire, the market desks, or the Base and Coinbase tokenized-stock feed. Titles and links only.
| Name | In | Type | Description |
|---|---|---|---|
| scope | query | ecosystem | market · default ecosystem | Which feed. Ignored when symbol is given. |
| symbol | query | string | Ticker, for that stock's own headlines. |
| limit | query | integer · 1–30 · default 10 | Headlines to return. |
400 BAD_SCOPE404 UNKNOWN_STOCKcurl -s 'https://basestocks.finance/api/v1/news?scope=ecosystem&limit=5'/api/v1/earnFreecached 120sWhere idle USDC can earn on Base: venue, variable APY, TVL and risk notes, discovered live from the protocols.
curl -s 'https://basestocks.finance/api/v1/earn'/api/v1/statsFreecached 300sWhat has been done through the app, counted from records verified against a receipt on Base.
curl -s 'https://basestocks.finance/api/v1/stats'Any wallet's tokenized-stock position, read from the chain.
/api/v1/portfolio/{address}Freecached 15s60/minAny wallet's tokenized-stock position, read from the chain — raw balances and share-equivalents side by side.
| Name | In | Type | Description |
|---|---|---|---|
| address * | path | address | 0x-prefixed wallet address. |
400 BAD_ADDRESS429 RATE_LIMITEDcurl -s 'https://basestocks.finance/api/v1/portfolio/0xEAa823AB4C4eE00283d8ed7be713ddf8A5ba0Fac'The calls to buy or sell a stock, built by the same router the app trades with. Nothing is signed or sent: the user's own wallet does that.
/api/v1/tradeFree30/mineligibilityThe calls to buy or sell one stock, for the account that will send them: an approval of exactly the amount sold when the allowance is short, then the swap, from the router the app trades with. Nothing is signed or sent.
| Name | In | Type | Description |
|---|---|---|---|
| stock * | body | string | Ticker ("NVDA"), token symbol ("NVDAc") or 0x address. |
| side * | body | buy | sell | buy spends USDC (or ETH), sell spends the stock for USDC. |
| amount * | body | uint | What is sold, in its smallest unit: USDC has 6 decimals, ETH 18, a stock its own. |
| account * | body | address | The wallet that sends the calls and pays. |
| recipient | body | address | Who receives a buy. Defaults to account; a sale always pays the account. |
| payWith | body | USDC | ETH · default USDC | What a buy is paid with. |
| slippageBps | body | integer · 10–500 · default 100 | How far below the quote the output may land, in basis points. |
| provider | body | zeroX | kyber | okx | uniswap | velora | aerodrome | Try this route first; the others still cover a failure. |
| builderCode | body | string | Your ERC-8021 builder code. It goes on every call beside the app's, so the trade is attributed to both. |
400 BAD_BODY404 UNKNOWN_STOCK409 NO_ROUTE429 RATE_LIMITED451 REGION_RESTRICTED4xx from the pre-trade checks502 TRADE_FAILEDcurl -s -X POST 'https://basestocks.finance/api/v1/trade' \
-H 'content-type: application/json' \
-d '{"stock":"NVDA","side":"buy","amount":"10000000","account":"0xEAa823AB4C4eE00283d8ed7be713ddf8A5ba0Fac"}'Two endpoints with a cost a cache cannot remove, priced at $0.10 in USDC per call over x402.
Call the endpoint. It answers 402 Payment Required with the amount, the asset, the network and the recipient. Your client signs a USDC authorization, retries the same URL, and gets the body. Nothing to sign up for and no key to rotate.
Settlement happens after a successful response, so a request that fails or asks for an unknown stock never costs anything.
x402 is Coinbase's HTTP payment standard. Base's guide covers the buyer side, including how an agent pays autonomously.
/api/v1/pro/report0.10 USDCcached 900sThe 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.
402 PAYMENT_REQUIRED503 REPORT_UNAVAILABLEcurl -s 'https://basestocks.finance/api/v1/pro/report'/api/v1/pro/history/{symbol}0.10 USDCcached 300sFull candle history for one stock, labelled with its source. $0.10 in USDC per call.
| Name | In | Type | Description |
|---|---|---|---|
| symbol * | path | string | Ticker or 0x address. |
| timeframe | query | 1D | 1W | 1M | 3M | 1Y · default 1M | The span of the series. |
400 BAD_TIMEFRAME402 PAYMENT_REQUIRED404 UNKNOWN_STOCKcurl -s 'https://basestocks.finance/api/v1/pro/history/NVDA?timeframe=1M'Coinbase tokenized stocks are available only to eligible persons outside the United States. This API reports public chain data and builds calls for the user's own wallet; it never signs, sends or executes a trade. Prices and rates change; the app publishes what it reads and marks what it could not.