This endpoint serves as the entry point to the historical holdings dataset in the FinImpulse API. It lists the dates for which holdings data is available for the requested ETF, so you can build a valid request to v1/holdings/history.
Note that historical holdings coverage begins on January 1, 2026, for most ETFs (~8,000 symbols). A subset of ~500 ETFs includes records dating back to 2023-2025. The full list of covered symbols with individual start and end dates is available for download here.
Historical Holdings Workflow
This endpoint is the first step in a two-stage historical holdings workflow:
- v1/holdings/history/dates/{symbol}: Retrieve the list of available holdings reporting dates for the selected ETF.
- v1/holdings/history: The primary data endpoint. Retrieve the full holdings composition for a selected symbol and reporting date.
Asset Type Compatibility
This endpoint is applicable only to ETFs. Stocks and mutual funds are not supported.
If no holdings data is available for the requested symbol, the response returns an empty items array.
When to Use This Endpoint
- Load the available reporting dates before requesting a holdings snapshot.
- Check whether an ETF has historical holdings coverage.
- Preselect the most recent available date for a default holdings workflow.
- Build date selectors or calendars for portfolio composition tools and ETF analysis flows.
- Filter available dates by range using start_date to scope results to a specific period.
Request Parameters
v1/holdings/history/dates/{symbol}
Start of the date range filter (YYYY-MM-DD). Only dates on and after this value are returned.
Note that historical holdings coverage begins from January 1, 2026 for most symbols. A subset of ~500 ETFs has records available from 2023-2025.
Requests with a start_date prior to the earliest available record for the requested symbol will return dates from that record onward.
Pagination offset (0-based).
Maximum number of records returned (user-defined).
User-defined identifier for the task (max 255 characters).
It is returned in the response data object, allowing you to match results with the corresponding request. It does not affect API processing or filtering logic.
curl --location "https://api.finimpulse.com/v1/holdings/history/dates/{symbol}" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer <API_TOKEN>" \
-d '{
"start_date": "2026-05-17",
"limit": 3,
"offset": 0,
"tag": "just tag"
}'
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
var client = new HttpClient();
var url = "https://api.finimpulse.com/v1/holdings/history/dates/{symbol}";
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "<API_TOKEN>");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var json = @"{
""start_date"": ""2026-05-17"",
""limit"": 3,
""offset"": 0,
""tag"": ""just tag""
}";
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync(url, content);
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.finimpulse.com/v1/holdings/history/dates/{symbol}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"Authorization: Bearer <API_TOKEN>"
],
CURLOPT_POSTFIELDS => json_encode(
[
"start_date" => "2026-05-17",
"limit" => 3,
"offset" => 0,
"tag" => "just tag"
]
)
]);
$response = curl_exec($curl);
curl_close($curl);
echo $response;
import urllib.request
import json
url = "https://api.finimpulse.com/v1/holdings/history/dates/{symbol}"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer <API_TOKEN>"
}
data = {
"start_date": "2026-05-17",
"limit": 3,
"offset": 0,
"tag": "just tag"
}
req = urllib.request.Request(url,
data=json.dumps(data).encode("utf-8"),
headers=headers,
method="POST")
with urllib.request.urlopen(req) as response:
result = json.loads(response.read().decode("utf-8"))
print(result)
const https = require('https');
const data = JSON.stringify({
"start_date": "2026-05-17",
"limit": 3,
"offset": 0,
"tag": "just tag"
});
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer <API_TOKEN>',
'Content-Length': Buffer.byteLength(data)
}
};
const req = https.request('https://api.finimpulse.com/v1/holdings/history/dates/{symbol}', options, (res) => {
let body = '';
res.on('data', chunk => body += chunk);
res.on('end', () => console.log(JSON.stringify(JSON.parse(body), null, 2)));
});
req.on('error', (e) => console.error(e));
req.write(data);
req.end();
Response
Pagination Fields
Total number of available reporting dates.
Number of records returned in this response.
Array of reporting date entries.
Date Item
Each item represents one available holdings reporting date for the requested ETF.
Record type (date expected).
Available holdings reporting date (YYYY-MM-DD).
{
"task_id": "b2ef0532-0609-4c80-b1dd-d0d63cb057c8",
"status_code": 20000,
"status_message": "OK",
"live": true,
"cost": 0.0004,
"data": {
"symbol": "SPY",
"start_date": "2026-05-17",
"limit": 3,
"offset": 0,
"tag": "just tag"
},
"result": {
"total_count": 6,
"items_count": 3,
"items": [
{
"type": "date",
"history_date": "2026-05-18"
},
{
"type": "date",
"history_date": "2026-05-19"
},
{
"type": "date",
"history_date": "2026-05-21"
}
]
}
}