Ticker Changes, Intraday Runners, Ownership Data in the Screener & Explicit Timestamp Offsets
Covers changes shipped between June 3 and September 12, 2026.
Breaking changes — read this first
All response timestamps now carry an explicit -05:00 offset
-05:00 offsetEvery datetime in every endpoint's response is now RFC 3339 in fixed EST, for example 2026-08-07T07:00:00-05:00. Previously /v1/news returned Eastern wall-clock time with a misleading Z (UTC) suffix, and every other endpoint returned a naive string with no offset at all. Any RFC 3339 parser now resolves every value to the correct instant with no assumptions.
The offset is fixed EST year-round — it does not become -04:00 in summer. Date-only fields (filed_at, date, effective_date, usage_date, maturity_date and similar) are unchanged.
Stored data was not modified; only serialization changed. Whether the printed digits moved depends on how each field was stored, so check the group your integration reads:
| Fields | What changed |
|---|---|
/v1/news, /v1/news-basic: created_at, last_updated. /v1/afterhours-stats, /v1/premarket-stats, /v1/intraday-runners: last_updated | Digits unchanged. Only the suffix changed. If you parsed the old news Z as real UTC you were reading an instant five hours early — the corrected instant now moves five hours later. |
/v1/gap-stats and /v1/gap-stats-advanced: last_updated. /v1/research-reports (ultimate): created_at, last_updated. All /v1/account/*, /v1/usage* and /v1/overview timestamps: requested_at, created_at, last_used_at, last_charged_at | These were true UTC and now print five hours earlier on the EST clock. Same instant. |
Intraday session times — high_time, low_time, spike_start_time — on /v1/gap-stats, /v1/gap-stats-advanced, /v1/afterhours-stats, /v1/premarket-stats, /v1/intraday-runners. Also /v1/news filed_at_time, /v1/nasdaq-compliance notes_updated, and last_updated on most other endpoints | Stored as New York wall clock. Values recorded during EDT (roughly March to November) now print one hour earlier. A 9:30 AM EDT market-open high serializes as 08:30:00-05:00. |
report_id removed from /v1/research-reports-tldr
report_id removed from /v1/research-reports-tldrThe field previously linked a TL;DR row back to the full report for the same event. There is no replacement key in the TL;DR response today. In practice the value was almost always null, but the field is gone from the schema. If you used it to correlate TL;DR rows with /v1/research-reports, contact us and we will prioritize a replacement.
market_cap on /v1/historical-float-pro now means something different
market_cap on /v1/historical-float-pro now means something differentField name and type are unchanged, so parsing will not break — but the numbers have changed and the field is null more often. See "Redefined" below.
/v1/float-outstanding no longer converts a reported 0 to null
/v1/float-outstanding no longer converts a reported 0 to nullOn insider_percent, affiliate_percent and institutions_percent, a genuinely reported zero now serializes as 0. Previously it was indistinguishable from missing data. As a result the message data-quality disclaimer appears on fewer responses, because it no longer treats 0 as missing. If your code reads null on these three fields as "zero insider ownership", it must now handle 0 as well.
An invalid ticker in a list no longer fails the request
Passing ticker=AAPL,BAD!,MSFT previously returned 422 for the whole request. It now returns 200 for AAPL and MSFT, and silently drops BAD!. Only when every symbol you pass is invalid do you get a 422. Validate your own symbol lists if a silently narrowed result set would be a problem for you — a typo now costs you a ticker's worth of data rather than raising an error.
New: Ticker Changes
GET /v1/ticker-changes returns the complete symbol-change history for a security, plus the latest ticker that history establishes. Pass any ticker in a chain — today's symbol or one from years ago — and you get the same history and the same current_ticker back. Available on all tiers. This endpoint supersedes Historical Tickers, which is now deprecated.
Use it to map an old ticker in a backtest, watchlist or filing archive to the symbol it trades under today, to show a dated "formerly known as" trail on a company profile, or to detect whether a ticker you hold has ever been renamed.
Parameters
ticker(required) — current or former symbol. Case-insensitive, surrounding whitespace trimmed, one to six characters. This is the only parameter; the endpoint is not paginated.
Response
query_ticker— the normalized symbol that was searched.has_changes—truewhen at least one eligible change event involves the symbol.current_ticker— the latest ticker established by the change history, ornullwhenhas_changesisfalse.history— the complete change chain, ordered oldest first, each entry{ old_ticker, new_ticker, effective_date }.
Note that count is the number of events in history, not the number of entries in results. results always contains exactly one object.
Two behaviors worth knowing before you integrate.
current_ticker is a statement about the change record only. It does not assert that the security is currently listed or actively trading. A company can be renamed and later delisted; this endpoint will still report the rename.
has_changes: false returns 200, not 404. It means only that no eligible change event involves the symbol you passed. It does not tell you whether that ticker is valid or active. This differs from Historical Tickers, which returns 404 for an unmatched symbol.
Ambiguous histories return 409 rather than a guess. Ticker symbols get recycled between unrelated companies, and a company can return to a symbol it previously used. When the record cannot be resolved to a single unambiguous chain, the endpoint fails loudly with error.code of ambiguous_ticker_lineage, and error.details carrying query_ticker, a machine-readable reason, and tickers — the symbols involved. The reason values are multiple_cik_lineages (the chain spans more than one issuer), same_date_events (two changes share an effective date), competing_destinations (a symbol was vacated twice), broken_chain (events do not connect), and max_hops_exceeded (the chain exceeded twelve links and is treated as bad data). We would rather return an error you can see than silently pick one branch.
Only effective, confirmed events count. A future-dated change does not move current_ticker until its effective date passes, measured in US Central time. Events recorded as reverted or manually blocked are excluded, as are unconfirmed estimates and backfills.
Deprecated: Historical Tickers
GET /v1/historical-tickers is now marked deprecated. Nothing about it has changed — same URL, same request, same response shape, same 404 on an unmatched ticker. It continues to work and we are not announcing a sunset date. Only its documentation label changed, to "DEPRECATED Historical Tickers".
New integrations should use Ticker Changes instead. It is backed by a dedicated symbol-change ledger with effective dates for every event, returns the full chain rather than a flat alias list, and tells you explicitly when a symbol's history is ambiguous instead of resolving it silently.
One knock-on effect if you consume the endpoint catalogue: GET /endpoints now prefixes the label of any deprecated route with the word DEPRECATED, so Historical Tickers appears as DEPRECATED Historical Tickers. The path field is unchanged. Match on path, not label, if you are keying off that response.
New: Intraday Runners
GET /v1/intraday-runners returns high-conviction intraday runner sessions: days where AskEdgar's anomaly detector flagged unusual volume and the ticker traded at more than 9x its normal daily volume. Each row is a full session narrative — the gap into the open, the spike, estimated halt minutes, intraday extremes, how the session closed relative to its range, plus premarket and after-hours context. Ordered by date descending. Available on all tiers.
Use it to backtest momentum strategies against confirmed high-volume runners rather than every gapper, to build a historical "biggest runners" dataset with halt and fade context, or to check whether a ticker has a history of anomaly-volume runs and how those sessions resolved.
Parameters (all optional)
ticker— symbol, comma-separated for multiple.date(exact match) ordate_from/date_to(range) — mutually exclusive; passing both returns422.min_gap_percentage/max_gap_percentage— bound the opening gap (may be negative).page,limit— pagination (defaults: 1, 10; max limit 100).
Response highlights
- Setup into the open:
gap_percentage,market_open,previous_day_close. - How far and when it ran:
percentage_gain,open_to_high_pct,high_price/high_time,low_price/low_time. - Spike and halt anatomy:
spike_start_time,spike_start_price,spike_duration_minutes,est_halt_minutes. - Volume:
daily_volume_ratio(always greater than 9 here),volume,dollar_volume,rth_volume,rth_dollar_volume. - Did it hold the move:
market_close,close_under_50pct_of_range. - After-hours coda:
afterhours_close,afterhours_high,afterhours_low,afterhours_volume,afterhours_dollar_volume. - Premarket context:
premarket_vwap,premarket_volume,premarket_dollar_volume,premarket_high,premarket_low. - Plus
market_cap,filing_typesandall_tags.
New fields
/v1/dilution-data and /v1/dilution-data-advanced: floor_price. The minimum conversion or exercise price under an instrument's price-protection terms. Present on both warrant and convertible objects, on both endpoints. null when no floor is recorded. Up to three decimal places.
/v1/screener: seven new fields. All are read-only response fields — none are filterable.
insider_percent,affiliate_percent,institutions_percent— most recent ownership percentages. These are decimals, not percentages:0.125means 12.5%.ownership_source_url— source filing for those ownership percentages.high_365,low_365— 365-day high and low price.website— company website URL.
Unlike the older screener fields, a reported 0 on these stays 0 and does not trigger the data-quality disclaimer.
/v1/historical-float-pro: restricted_shares. Count of restricted shares as reported at that point in time, ADR-adjusted where applicable. This is the component subtracted from float to arrive at tradable_float.
Redefined: market_cap on /v1/historical-float-pro
market_cap on /v1/historical-float-promarket_cap is now a true point-in-time figure, computed per row as the unadjusted closing price on that row's reported_date multiplied by that row's outstanding_shares, rounded to two decimals. Previously it was a stored value whose as-of date and provenance were unspecified.
- When
reported_dateis not a trading day, the most recent close on or before that date is used. market_capisnullwhen the closing price is unavailable, or whenoutstanding_sharesorreported_dateis missing. There is no longer a fallback to the previously stored value.- Prices are deliberately unadjusted for later splits. Using split-adjusted prices against point-in-time share counts double-counted splits and inflated pre-split rows by the split factor. Historical rows for split-affected tickers are now correct.
- Values no longer carry floating-point artifacts such as
1782816.0000000002.
The closing price used and the date it came from are not exposed as separate fields. If that would help you reconcile figures, tell us and we will consider adding them.
We also fixed an intermittent 503 on this endpoint caused by a numeric type error during the market-cap computation.
Updated: errors and retries
Two new retryable 503 codes. During bulk-ingest windows and connection saturation, requests that previously failed as an opaque 500 database_error after about 30 seconds now fail fast with a specific code and a Retry-After: 5 header:
data_refreshing— "Data is being refreshed, please retry in a few seconds." Raised when a query cannot acquire a lock on a table being reloaded. Queries now wait two seconds and retry once automatically before surfacing this, so brief contention is absorbed rather than returned.database_pool_timeout— "Database connections are temporarily saturated, please retry in a few seconds."
Both are safe to retry after the advertised delay.
The 60-second 504 request_timeout response has been removed. It returned a non-standard body with no error.code or request_id. Requests are now bounded per resource instead — database queries cap at 30 seconds and surface as 503 data_refreshing. This also eliminated a class of spurious 500s on slow requests.
Failures now report their real status and code. A bug in the rate-limit layer was swallowing downstream exceptions and returning a generic 503 service_unavailable for all of them. Errors now surface with their correct status and code — 422 validation_error, 503 data_refreshing, 500 internal_error and so on.
Clearer errors when every ticker you pass is invalid. You now get a 422 naming the offending symbols: Invalid ticker(s): ... Tickers must contain only uppercase letters, numbers, dots, hyphens, or carets. Previously this produced a misleading "At least one filter is required" message and, on endpoints where ticker is optional and another filter was supplied, could quietly widen the query across all tickers. /v1/split-status now explicitly requires at least one valid ticker.
Updated: filters and validation
Future dates are now accepted on forward-looking contract filters. These four parameters previously rejected any future date with 422 "Date must be in the past":
/v1/registrations—expiration_date_from,expiration_date_to/v1/pump-and-dump-tracker—lock_up_expiration_from,lock_up_expiration_to
You can now ask which shelf registrations expire in the next twelve months, or which lock-ups expire before a given date. Other date parameters on these endpoints — filed_at_*, effective_date_*, ipo_date_*, last_liquidation_date_* — still reject future dates. Range ordering is still enforced.
More forgiving ticker parsing. Internal whitespace inside a symbol is now stripped, so AA PL resolves to AAPL. The 100-ticker-per-request cap is counted after invalid entries are filtered out rather than before. These changes apply to endpoints accepting comma-separated ticker lists; single-ticker endpoints are unchanged.
Updated: data quality
/v1/ownership now returns the newest filing that actually contains a holder table. Some filings incorporate their ownership table by reference rather than restating it, and those produced placeholder rows with every holder field empty. Because the newest filing won, a request could return a blank table while the real one sat one filing behind it. Placeholder-only groups are now skipped, so the group you get back may carry an earlier reported_date than before — and it will contain holders. A ticker whose filings are all placeholders now returns an empty results array instead of a group of empty rows.
/v1/historical-tickers no longer returns duplicate entries. The upstream data could repeat the same ticker-and-date pair, and those duplicates were passed through into the historical_tickers array. They are now removed, which means count can be lower than before for affected tickers. A ticker that legitimately appears more than once with different dates is preserved. Ordering within the array is now by change date with undated entries last, then alphabetically by ticker.
Sharper cost estimates. /estimate for /v1/dilution-data, /v1/dilution-data-advanced and /v1/ownership now samples only the rows those endpoints would actually return, so the projected cost tracks real responses more closely. Ownership is counted in filing groups rather than raw rows.
Minor
last_used_at on /v1/account/api-keys is now updated at most once per minute per key, so it can lag real usage by up to 60 seconds. This removed a source of intermittent failures under load.