Real photo by Compagnons / Unsplash, used under the Unsplash License.
Source-backed answer: Public quote screens can start with the public market and orderbook endpoints. Private account or trading endpoints use signed Kalshi headers, not a simple bearer token. The orderbook endpoint returns yes and no bid ladders, not a separate ask feed. Do not paste a private key into a shared spreadsheet.
Kalshi's production market-data base URL is https://external-api.kalshi.com/trade-api/v2. The current market-data guide says public series, events, markets and orderbook data can be requested without authentication. That is the right first boundary for a shared workbook.
Do not turn a quote sheet into a credential vault. Authenticated Kalshi calls require an access-key ID, millisecond timestamp and RSA-PSS signature. Google Sheets and Excel files are commonly shared, copied and inspected. Put signed private calls in a server-side service with explicit access control, then expose only the minimum read-only result if needed.
The current response uses orderbook_fp.yes_dollars and orderbook_fp.no_dollars. Each row is a price string and fixed-point contract quantity. Both arrays are bids, sorted from lower to higher price; the best bid is the last row. A separate ask array is not returned.
| Displayed value | Derivation | Required guard |
|---|---|---|
| Best YES bid | Last price in yes_dollars | Blank if the YES ladder is empty |
| Best NO bid | Last price in no_dollars | Blank if the NO ladder is empty |
| Best YES ask | 1.00 - best NO bid | Blank if there is no NO bid |
| Best NO ask | 1.00 - best YES bid | Blank if there is no YES bid |
| YES spread | YES ask - YES bid | Do not compute from a missing side |
A quote is still not a guaranteed fill. Show level quantity beside price, and label the observation timestamp. A cached cell with no timestamp should not be described as live.
Google documents UrlFetchApp.fetch() for HTTP/HTTPS and installable time-driven triggers for scheduled functions. The following example reads a ticker from cell B1, fetches the current public orderbook, and writes the raw bid ladders plus an observation time. It intentionally does not accept or store Kalshi credentials.
function refreshKalshiOrderbook() {
const sheet = SpreadsheetApp.getActive().getSheetByName('Quotes');
const ticker = String(sheet.getRange('B1').getValue()).trim();
if (!/^[A-Z0-9_.-]+$/.test(ticker)) throw new Error('Invalid ticker');
const base = 'https://external-api.kalshi.com/trade-api/v2';
const url = base + '/markets/' + encodeURIComponent(ticker) + '/orderbook';
const response = UrlFetchApp.fetch(url, {muteHttpExceptions: true});
const status = response.getResponseCode();
if (status !== 200) throw new Error('Kalshi HTTP ' + status);
const data = JSON.parse(response.getContentText()).orderbook_fp;
const rows = [['side', 'price_dollars', 'count_fp']];
(data.yes_dollars || []).forEach(level => rows.push(['yes_bid', ...level]));
(data.no_dollars || []).forEach(level => rows.push(['no_bid', ...level]));
sheet.getRange('D1').setValue(new Date());
sheet.getRange('D2:F').clearContent();
sheet.getRange(2, 4, rows.length, 3).setValues(rows);
}
For a scheduled refresh, create an installable trigger under the intended owner account. Google notes that installable triggers run as their creator and are subject to quota limits. Log failures and keep the previous timestamp visible rather than silently presenting old values as current.
Microsoft documents Data → From Web in Excel through the Power Query Web connector and JSON transformation through Json.Document. For a public orderbook URL, the workflow is:
orderbook_fp, then yes_dollars and no_dollars.Office Scripts can call external APIs, but Microsoft's guidance also says the environment has no infrastructure for storing API credentials or keys. That makes a workbook a poor place for a Kalshi private key. Keep this design public and read-only.
Do not use a universal “refresh every minute” rule. Kalshi's current rate-limit model charges token cost per request and separates read and write budgets. Spreadsheet platforms also have their own execution and trigger quotas.
For N tickers refreshed every S seconds at endpoint cost C, the steady request-token demand is N × C / S tokens per second, before retries. Compare that number with the current account budget and leave headroom. On HTTP 429, stop the affected refresh path and retry with bounded exponential backoff rather than creating a retry storm.
No. Kalshi's authenticated REST flow uses KALSHI-ACCESS-KEY, KALSHI-ACCESS-TIMESTAMP, and KALSHI-ACCESS-SIGNATURE headers with RSA-PSS signing. Public market and orderbook requests do not need those secrets. Keep private endpoints outside shared spreadsheets.
The current orderbook response contains yes_dollars and no_dollars bid ladders inside orderbook_fp. It does not return separate asks. The best YES ask is one dollar minus the best NO bid, and the best NO ask is one dollar minus the best YES bid.
There is no universal safe interval. Calculate request cost from the current Kalshi token budget, the number of tickers, and the spreadsheet platform's own quotas. Handle HTTP 429 with backoff, display the last successful observation time, and do not label stale cells live.
Google Apps Script documents UrlFetchApp for HTTP and HTTPS requests, and Kalshi documents unauthenticated public market-data endpoints. A bound script can fetch public JSON and write normalized values to cells. Installable triggers run under their creator's account and remain subject to Apps Script quotas.
Microsoft documents the Power Query Web connector and JSON import for Excel. Those are reasonable options for public JSON. Office Scripts can also call external APIs, but Microsoft's documentation says Office Scripts has no infrastructure for storing API credentials, so do not hard-code a Kalshi private key in a workbook.
Boundary: This is a read-only data-display guide, not a trading system. APIs, quotas and spreadsheet platforms change. Verify all linked documentation and protect credentials before implementation.