When a chart is empty, debug from the ingestion response toward the visualization. Changing multiple filters at once usually hides the actual cause.
1. Check the HTTP response#
Log the response status and body from the ingestion request:
const response = await fetch("https://api.graphjson.com/api/log", options);
const body = await response.text();
console.log(response.status, body);
A successful network call is not the same as a successful ingestion. Treat only a 2xx status as accepted.
Common failures:
| Symptom | Likely cause |
|---|---|
Invalid API KEY |
Missing, mistyped, or replaced key |
Invalid JSON |
json is not a serialized JSON object |
Invalid Unix Timestamp |
Milliseconds, decimals, or malformed timestamp |
JSON too big |
Serialized event exceeds 10,000 characters |
429 Too Many Requests |
Requests exceeded the ingestion rate guardrail |
2. Confirm the collection#
The request collection must exactly match the collection you are viewing:
{
"collection": "product_events"
}
Collection names are lowercase in the dashboard. Check for singular/plural mismatches and whitespace in code or environment configuration.
If you are unsure, inspect all_events to determine whether the event reached the workspace under another collection.
3. Open Samples#
Use:
- visualization: Samples
- range: 7 days ago → now
- order: Descending
- filters: none
Samples removes aggregation and split logic from the problem. If the event appears, ingestion worked and the issue is in the chart configuration.
4. Check event time#
A request can succeed while its event falls outside the visible range.
Confirm the timestamp is Unix seconds:
console.log(new Date(timestamp * 1000).toISOString());
For webhooks and backfills, confirm you are using the source event time you intended. Check whether the dashboard’s IANA time zone moves the event across a calendar boundary.
5. Check field names and types#
Field names are case-sensitive. These are different:
user_id
userId
User_ID
Numeric aggregations require JSON numbers:
{"amount": 4900}
not:
{"amount": "4900"}
Nested fields are flattened by default, so context.page.path is the field name shown by the visualizer.
6. Reduce the visualization#
Rebuild the chart in this order:
- Count
- no metric
- no split
- no comparison
- no filters
- broad range
Then add one setting at a time. The first change that empties the result identifies the problem.
7. Inspect the generated API call#
Use Export → As Data API Call and compare the generated payload with the chart controls. Look for:
- an old collection name
- a stale or overly narrow time range
- filters with the wrong type
- a metric that is not numeric
- a split with no matching values
- an unintended
compare
8. Reproduce with SQL#
Run:
SELECT
timestamp,
json
FROM product_events
ORDER BY timestamp DESC
LIMIT 50
Then add the failing condition directly:
SELECT count()
FROM product_events
WHERE JSONExtractString(json, 'event') = 'checkout_completed'
SQL separates the stored data from visualizer configuration and makes type mismatches visible.
Contact support#
If the event has a 2xx ingestion response but cannot be found, email hi@graphjson.com with:
- approximate request time and time zone
- endpoint
- collection name
- HTTP status and response body
- a redacted example payload
Do not include the API key or sensitive event values.