Start a chat at massive.com/contact and fill in the template below. Every line in it is there so we can do something specific with your report: rerun your exact request, find that request in our logs, or rule out the handful of causes that explain most reports. Send those details and the first reply is usually the answer. Send a description without them and the first reply is a list of questions.
Applies to
- Plans: all plans.
- Endpoints: any REST endpoint, WebSocket channel or flat file. The template has a section for each, because they identify a request differently.
- Asset classes: all.
The template
The template is deliberately in sections, because REST, the WebSocket and the flat files identify a request in three different ways. Copy it into the chat, fill in what applies and delete the rest:
WHAT I SAW
Ticker(s):
Timestamp or date range (UTC):
What the API returned:
What I expected:
Where my expectation came from:
HOW I ASKED (REST)
Request URL (key replaced with apiKey=YOUR_API_KEY):
request_id, or the x-request-id response header:
adjusted= value, if this was an aggregates call:
Which timestamp field I filtered on:
HOW I ASKED (WebSocket)
Cluster URL:
Exact subscribe message:
UTC time of the events involved:
A few of the raw messages received:
HOW I ASKED (flat files)
Full object key, e.g. us_stocks_sip/trades_v1/2024/03/2024-03-07.csv.gz:
The line or lines in question:
CONTEXT
Plan and asset class:
Does the same request still return the same thing right now?
First noticed:
What each field lets us do
Nothing here is bureaucracy. This is what each line is for:
| Field | What it lets us do |
|---|---|
| Request URL, key redacted | Rerun your exact request against the same endpoint. Most reports are settled here |
| request_id, or the x-request-id header | Find that single request in our own logs: which service answered it and what it returned |
| Ticker and UTC timestamps | Narrow to the window. Many discrepancies are minutes wide, so a date alone is not enough |
| What you expected, and its source | Turn "the data is wrong" into something testable. Another vendor, an exchange page, your own earlier pull |
| adjusted= | Rule out the single most common false positive, a split-adjusted bar compared against an unadjusted source |
| Which timestamp field you filtered on | Rule out the second most common one. A trade carries participant, SIP and TRF timestamps, and they differ |
| Plan and asset class | Reproduce with the same entitlements you have. Results genuinely differ by plan |
| Still reproduces? | Separate a live problem from one already corrected. Late prints and corrections arrive after the fact |
| Full object key, for flat files | Fetch the same file. Flat files have no request_id |
Where to find the request_id
Most REST responses carry request_id in the body, including error responses:
curl -X GET "https://api.massive.com/v2/aggs/ticker/AAPL/range/1/day/2026-09-10/2026-09-10?apiKey=YOUR_API_KEY"
Response
{
"ticker": "AAPL",
"queryCount": 1,
"resultsCount": 1,
"adjusted": true,
"results": [
{ "v": 70011913.06091, "vw": 322.9591, "o": 316.67, "c": 326.57,
"h": 326.74, "l": 316.51, "t": 1789012800000, "n": 1226854 }
],
"status": "OK",
"request_id": "e24b806121fda70c1633fb4bd32e8c6d",
"count": 1
}
Two things in that block are worth naming. adjusted is echoed back, so the response tells you which of the two price series you actually got without your having to remember what you sent. And t is the bar's start in Unix milliseconds: 1789012800000 is 2026-09-10 00:00 Eastern, not 09:30, because daily bars are anchored to the start of the day.
The header is the one to rely on. x-request-id comes back on every call and carries the same value, while the body field is common rather than universal: /v1/open-close, /v1/marketstatus/now, /v1/marketstatus/upcoming and /v2/reference/markets all answer without it. So take the id from the headers with curl -D - and you never have to know which endpoint you are on:
curl -D - -o /dev/null -s "https://api.massive.com/v1/marketstatus/now?apiKey=YOUR_API_KEY" | grep -i x-request-id
Response
x-request-id: 851353d1a8d27cbea9c010ed0b05852d
There is no request_id on the WebSocket or on flat files. That is why the template asks for the subscribe message and the object key instead: those identify the request in the only way those two surfaces can.
Four checks that resolve most reports before you send one
Each of these takes a minute and each one accounts for a large share of reports that turn out not to be defects:
- Was the market open? Call /v1/marketstatus/upcoming and check the date for a holiday or an early close. A short or absent session is the most common cause of data that looks missing.
- Are the prices adjusted the same way on both sides? Aggregate bars are split-adjusted by default. Add &adjusted=false to compare against an unadjusted source.
- Was the trade eligible? Not every trade updates a bar. A bar that disagrees with your own sum of the trades is usually sale conditions, not arithmetic.
- Has it been corrected since? A bar you stored live can be superseded. REST holds the current version, so compare against a fresh pull rather than your stored copy.
If one of those explains it, there is nothing to report. If none does, you now have most of the template filled in as a side effect.
Why we ask for the request_id rather than a screenshot
We ask for the request_id because it identifies the single request you made, including which service answered it and what it returned. A screenshot shows the symptom; the id shows the request. With it, a data question that would take a day of back and forth is often one lookup.
The same logic runs through the rest of the template: we are trying to get to the point where we can run what you ran, with the entitlements you have, against the window you meant, and see what you saw. Everything the template asks for is in service of that.
If you see an error
If a request returns a request_id you can quote, quote it, even for an error rather than a discrepancy.
Never paste a live API key into a chat, a ticket or a screenshot. Replace it with apiKey=YOUR_API_KEY. If you already sent one, delete it from your dashboard and make a new one.
You can also open an issue on our GitHub organization for problems with the client libraries. Data questions are better in the chat at massive.com/contact, where we can see your account.

