How do you quote fifty symbols without fifty requests?
A dashboard with forty tickers on it should not make forty API calls every refresh. Both delayed-quote endpoints take several symbols at once, and each does it with a slightly different contract.
Batching on /real-time/{ticker}
The path takes one symbol. The s query parameter takes a comma-separated list of additional ones:
/real-time/AAPL.US?s=SPY.US,EURUSD.FOREX,BTC-USD.CC
Four symbols, one request. The list mixes asset classes freely — US equities, an FX pair and a crypto pair in the same call, each with its own exchange suffix.
Now the detail that breaks client code. The response schema for this endpoint is a oneOf: a single object when you request one symbol, an array of objects when you use s. The shape of the response depends on the contents of your query string. Code that handles the one-symbol case and then acquires a second symbol will fail at the point it tries to read .code off a list.
The robust habit is to always send s, even with a single extra symbol, so you always parse an array — or to normalise immediately on receipt and never let the two shapes propagate.
The endpoint also accepts an ex parameter, an exchange-code filter. It is documented thinly; treat anything you discover through it as unsupported until it appears properly in the specification.
Batching on /us-quote-delayed
This one is built for batching from the start. There is no path symbol at all — s is required and takes the comma-separated list:
/us-quote-delayed?s=AAPL,MSFT,GOOGL
Now read the response before you write anything against it, because it is not the /real-time shape with more rows. It is a different object with different names:
{"meta": {"count": 2},
"data": {"AAPL.US": {"symbol": "AAPL.US", "exchange": "XNAS", "type": "STOCK",
"name": "Apple", "sector": "Information Technology",
"bidPrice": 310.75, "askPrice": 310.8,
"bidSize": 40, "askSize": 40,
"lastTradePrice": 310.8, "lastTradeTime": 1787143931085,
"volume": 1479485, "change": 0.77, "changePercent": 0.25,
"previousClosePrice": 310.03, ...}},
"links": {"next": null}}
Three things there will break a first draft. It is an envelope, not an array — {meta, data, links} — so iterating the response gives you three keys. data is an object keyed by symbol, not a list. And the field names are its own: symbol not code, lastTradePrice not close, previousClosePrice not previousClose, changePercent not change_p, lastTradeTime in milliseconds and no gmtoffset at all.
It adds one parameter the other lacks: fields, a comma-separated list of the fields you actually want — using these names. Ask for fields=close,change_p and you get neither, silently, because neither exists here. Ask for what is there:
/us-quote-delayed?s=AAPL,MSFT&fields=lastTradePrice,volume,changePercent
For a hundred symbols on a dashboard refreshing every minute, trimming thirty fields to three is a real reduction in bytes parsed. And note what this endpoint has that nothing else in the course does: a bid and an ask, with their own sizes and timestamps. The opening lesson of this course listed "no bid, no ask, so you cannot tell what it would have cost to transact" among the things a daily bar leaves out. This is where you get it back.
The scope is narrower, though, and stated in the endpoint's own description: US equities, fifteen-minute delayed. For a London or Tokyo symbol you are back on /real-time. Omitting s returns a 422, not a 400.
How many is too many
There is no hard maximum in the specification, and the vendor's own guidance for /real-time suggests keeping a batch to roughly fifteen to twenty symbols. Treat that as the working limit rather than a rule you can safely ignore, because the failure mode of an over-long query string is a truncated or rejected request, not a helpful error naming the symbol it gave up on.
For a watchlist of two hundred, that means chunking: split into batches of fifteen or twenty, issue them in sequence, and reassemble. Which turns a question about batching into a question about rate limits — one request per chunk, and the per-minute ceiling is the thing you will hit first. Course 1 covers that arithmetic.
The accounting nobody mentions
Batching reduces requests, not necessarily quota. Quota on quote endpoints is generally counted per symbol returned rather than per HTTP call, so a twenty-symbol batch is not one unit of consumption. What batching buys you is fewer round trips, less rate-limit pressure, and one consistent moment for the whole set — every row in a batch is fetched together, which matters when you are comparing them.
Try it now
- Here is
/real-time/AAPL.USalone, then the same path withs=MSFT.US,TSLA.US. Read the labels in the two tables: the first is one object's fields, the second is rows of a list. Diff the two response shapes. That difference is the bug waiting in most first drafts.
- Here are the payload sizes of
/us-quote-delayed?s=AAPL,MSFT,GOOGLthree ways, measured on 28 September 2026 during the US session. Work out the saving from trimming, then read the last row: a request for two fields that do not exist here succeeded, returned neither of them, and trimmed nothing. Note too what came back forchangePercentwhen it was asked for by name. Below the table is the trimmed call as the academy renders it, withfields=lastTradePrice,volume.
fields |
status | bytes | what each symbol's entry held |
|---|---|---|---|
| none | 200 | 3,731 | the full record, about fifty fields |
lastTradePrice,changePercent |
200 | 222 | those two keys, with changePercent null on all three |
close,change_p |
200 | 3,731 | the full record again, with no close and no change_p in it |
- Here is one seventeen-symbol batch,
/real-time/AAPL.US?s=…, called at 15:54:53 UTC on Monday 28 September 2026 with every market below open, trimmed tocodeandtimestampconverted to UTC. Check whether every row carries the sametimestamp. Where they differ, ask which instrument last traded and when, and which difference is the licence rather than the trading. That is the answer to a question you did not know you were asking.
code |
timestamp (UTC) |
|---|---|
| AAPL.US, MSFT.US, NVDA.US, AMZN.US, GOOGL.US, META.US, TSLA.US, JPM.US, F.US, NVR.US, SPY.US, TLT.US | 15:39:00 |
| KO.US | 15:38:00 |
| VOW3.XETRA | 15:37:00 |
| HSBA.LSE | 15:38:00 |
| EURUSD.FOREX | 15:54:00 |
| BTC-USD.CC | 15:54:00 |