Both kinds come from /stocks/v1/splits, in one record shape, and the ratio alone tells you the direction: whichever of split_from and split_to is larger. What the ratio does not tell you is the third category. adjustment_type has three values, not two, and the one people miss changes which records a filter returns.
Applies to
- Plans: every Stocks plan includes splits. The free Basic tier sees the last two years; every paid tier sees all history, which reaches back to 25 October 1978.
- Endpoints: /stocks/v1/splits. The older /v3/reference/splits still responds but is marked deprecated in the documentation and has neither adjustment_type nor historical_adjustment_factor.
- Asset classes: US stocks and ETFs.
How to read a split record
curl -X GET "https://api.massive.com/stocks/v1/splits?ticker=NVDA&sort=execution_date.desc&limit=1000&apiKey=YOUR_API_KEY"
Response
{
"results": [
{ "ticker": "NVDA", "execution_date": "2024-06-10", "split_from": 1.0, "split_to": 10.0,
"adjustment_type": "forward_split", "historical_adjustment_factor": 0.1 },
{ "ticker": "NVDA", "execution_date": "2021-07-20", "split_from": 1.0, "split_to": 4.0,
"adjustment_type": "stock_dividend", "historical_adjustment_factor": 0.025 },
{ "ticker": "NVDA", "execution_date": "2007-09-11", "split_from": 2.0, "split_to": 3.0,
"adjustment_type": "forward_split", "historical_adjustment_factor": 0.016667 },
{ "ticker": "NVDA", "execution_date": "2006-04-07", "split_from": 1.0, "split_to": 2.0,
"adjustment_type": "forward_split", "historical_adjustment_factor": 0.008333 }
],
"status": "OK"
}
The ratio is always split_to / split_from, and it applies the same way in both directions: multiply the share count by it, divide the price by it. A three-for-two split, the 2007 record above, gives a ratio of 1.5; a one-for-ten reverse split gives 0.1.
Sort with sort=execution_date.desc. The older order parameter is not part of this endpoint and is ignored rather than refused, which hides the failure: this endpoint already defaults to execution_date descending, so order=desc appears to work and order=asc quietly returns newest-first when you asked for oldest-first.
Telling the three apart
Telling the three apart is a read of adjustment_type, which names the event, and of the ratio, which measures it. These are the shapes you will meet:
| adjustment_type | Example record | Ratio | Effect |
|---|---|---|---|
| forward_split | split_from: 1, split_to: 10 | 10 | Ten times the shares, a tenth of the price |
| forward_split | split_from: 2, split_to: 3 | 1.5 | Half as many again |
| reverse_split | split_from: 10, split_to: 1 | 0.1 | A tenth of the shares, ten times the price |
| stock_dividend | split_from: 1, split_to: 1.027 | 1.027 | Extra shares issued as a dividend |
The trap is that stock_dividend is not always a small fraction. NVDA's 2021 four-for-one is recorded as a stock_dividend, because that is how the company executed it, so a filter of adjustment_type=forward_split returns NVDA's 2024, 2007 and 2006 records and silently drops the 2021 one. Filter on adjustment_type to study a category, never to build an adjustment.
Companies split forward to bring a share price down into a range retail investors find approachable, and reverse split to bring one up, often to stay above an exchange's minimum listing price. The mechanics in the data are identical.
Applying more than one
Applying more than one split no longer means multiplying ratios yourself. historical_adjustment_factor is cumulative: it is the number you multiply a price by to express it on today's share basis, already accounting for every split after that record. The 2006 NVDA record carries 0.008333, which is 1/120, so a single pre-2006 share corresponds to 120 shares today.
To adjust a price from a date D, take the first record whose execution_date is after D and multiply by its factor. Filter with execution_date.gte so the endpoint does that selection rather than your code doing it after the fact.
If you see an error
A price series that steps on one date with no news is an unadjusted series crossing a split. Check for an execution_date near the step.
A record where split_from is larger than split_to is a reverse split and is correct, not a data entry error.
An adjustment_type that differs from what you stored is not a corruption. The classification follows the filing and can be revised after the event, most often from forward_split to stock_dividend, so treat the field as refreshable rather than fixed at first sight.
An empty results array means the ticker has no split records in the range, which is the normal answer for most companies. On the free Basic tier it can also mean the range predates your two-year window.

