GET
/v1/last/movers/:venueMarket movers
Get the top gainers and top losers across stocks, crypto, FX, and commodities, ranked by percentage change since the last daily close, including symbol, current price, previous close, change, percent change, and day volume. One request returns both lists, or just one with direction.
- Auth
X-API-Keyheader- Format
- JSON
- Rate limits
- Per-key, see limits
Example
request · shell
curl -H "X-API-Key: $KEY" \
"https://api.sifting.io/v1/last/movers/stocks?limit=2"200OKapplication/json
{ "data": { "gainers": [ { "symbol": "NVDA", "price": "148.32", "prev_close": "139.1", "change": "9.22", "change_pct": 6.6283, "day_volume": 18452310, "prev_day_volume": 21980400 }, { "symbol": "TSLA", "price": "271.4", "prev_close": "256.85", "change": "14.55", "change_pct": 5.6648, "day_volume": 9120455, "prev_day_volume": 10234100 } ], "losers": [ { "symbol": "INTC", "price": "21.15", "prev_close": "22.74", "change": "-1.59", "change_pct": -6.9921, "day_volume": 22100870, "prev_day_volume": 15870200 }, { "symbol": "PYPL", "price": "63.4", "prev_close": "67.1", "change": "-3.7", "change_pct": -5.5142, "day_volume": 5210330, "prev_day_volume": 6120900 } ] }, "meta": { "as_of": "2026-10-06T15:42:10Z", "venue": "stocks", "limit": 2 }}Loading runner…
First load onlyParameters
ParameterDescription
Parameter
venuerequiredenum · path- stocks | crypto | forex | commodities.
limitinteger · query- Rows per list, applied to gainers and losers each. 1–100, default 20. Any other value returns 400.
directionenum · query- gainers | losers | all. Default all, which returns both lists. Case-insensitive. Any other value returns 400.
Response fields
FieldDescription
Field
data.gainers[]array- Biggest rise first. Omitted when direction=losers.
data.gainers[].symbolstring- Symbol.
data.gainers[].pricestring- Current price.
data.gainers[].prev_closestring- Previous close the move is measured against, the same value /v1/last/close returns.
data.gainers[].changestring- price minus prev_close. Negative for losers.
data.gainers[].change_pctfloat- Percentage change against prev_close, rounded to 4 decimals. Negative for losers.
data.gainers[].day_volumefloat- Volume so far in the current trading day: the UTC day for crypto, forex, and commodities, the regular session for US stocks. Omitted when no volume is available.
data.gainers[].prev_day_volumefloat- Full volume of the trading day before day_volume's day. Omitted when unavailable.
data.losers[]array- Biggest fall first. Same row shape as data.gainers[]. Omitted when direction=gainers.
meta.as_ofstring- When the response was produced. RFC 3339, UTC.
meta.venuestring- The venue you queried.
meta.limitinteger- Rows per list applied to this response.
Reference
Choosing listsDescription
Choosing lists
- Both lists
- No direction, or direction=all, returns gainers and losers.
- One list
- direction=gainers returns only the gainers key; direction=losers returns only the losers key. The other key is left out of data entirely.
- With limit
- limit applies to whichever lists you get. ?direction=gainers&limit=10 returns the top 10 gainers.
- Empty vs omitted
- A list you asked for that has no rows comes back as []. A list you filtered out is not in the response.
How change is measuredDescription
How change is measured
- Crypto, forex, commodities
- Measured against the close taken at 00:00 UTC each day, so change reads as the move since midnight UTC.
- US stocks
- Measured against the close taken at the US market close (4:00 PM ET), Monday to Friday. During the session you see the move since the previous close; after the close and overnight, you see after-hours moves against that close.
- Weekends
- No new close is taken, so the lists show the last session's final state.
- Same baseline
- prev_close is the same value /v1/last/close/:venue/:symbol serves, so the two always agree.
VolumeDescription
Volume
- Source
- Our own aggregated volume, the same that feeds our OHLCV bars.
- Trading day
- The UTC day for crypto, forex, and commodities; the regular session for US stocks. Not a rolling 24 hours.
- Between days
- Until the next day's first bar (US stock pre-market, weekends, holidays), day_volume still carries the previous day's full total.
- Missing vs zero
- An omitted field means no volume is available for that symbol; a 0 is a real zero. Check for the key before using it.
- Not a ranking input
- Rows are ranked by change_pct only. Volume is there for context, for example to compare day_volume with prev_day_volume or skip thinly traded names.
Freshness & behaviorDescription
Freshness & behavior
- Refresh
- Rankings refresh about once a minute: near real-time, not tick by tick. For tick-level prices use /v1/last/trade or the WebSocket.
- What's listed
- Symbols with both a current price and a previous close. Unchanged symbols appear in neither list, so a list can be shorter than limit, and a quiet market returns 200 with empty arrays, not an error.
- Ties
- Equal moves are ordered by symbol, so rows never reshuffle between calls.
- Prices
- From the same fair-price feed as the rest of our live data. Very small or thinly traded stocks can post large percentage moves; filter on price or day_volume client-side if you only want liquid names.
- Scope
- Ranked by percentage change on the current state. A most-active (volume-ranked) list, history, and price or sector filters are not part of this endpoint.
- Access
- Follows the live-data access for the market: a plan that includes live stocks includes stock movers, and so on.
Prices are strings, cast before mathDescription
Prices are strings, cast before math
- Why
- price, prev_close, and change come back as JSON strings to preserve exact precision. change_pct, day_volume, and prev_day_volume are plain numbers.
- The trap
- Math on the raw string fields breaks: Python raises TypeError, JavaScript + silently joins the strings instead of adding.
- Python
- top = data["data"]["gainers"][0]; price = float(top["price"])
- JavaScript
- const top = data.data.gainers[0]; const price = Number(top.price);
- cURL / jq
- Cast in jq too: jq '.data.gainers[] | { symbol, price: (.price|tonumber), change_pct }'
Error responses
StatusCodeMeaning
- 400
invalid_limitlimit is not an integer between 1 and 100.
{ "error": "limit must be an integer between 1 and 100" } - 400
invalid_directiondirection is not gainers, losers, or all (for example up, both, or gainers,losers).
{ "error": "direction must be gainers, losers or all" } - 403
not_entitledYour subscription doesn't include live data for this market, the same gate as /v1/last/trade.
{ "error": "no active subscription for this market", "market_id": "us_stocks", "feature": "live_stocks"} - 404
unknown_venueVenue path segment isn't one of stocks | crypto | forex | commodities.
{ "error": "unknown venue" } - 404
venue_not_supporteddex is a valid venue but has no movers ranking.
{ "error": "movers not available for this venue" } - 503
market_data_unavailableLive data for this market is temporarily unavailable. Retry shortly.
{ "error": "market data unavailable" }