DocsGuides

Guides

Troubleshoot GraphJSON

7 min readReviewed July 2026

Use this page when you know the symptom but not which product layer caused it. Start at the top of the request path and change one variable at a time.

producer
  → GraphJSON API
    → collection storage
      → query or visualizer
        → dashboard, alert, export, or embed

A problem at an earlier layer affects everything after it. An embed cannot display an event that never arrived, and an alert cannot evaluate a chart that returns too little history.

Fast symptom index#

Symptom Start here
Logging request fails Ingestion requests
Request succeeds but event is absent Accepted event is missing
Samples has data but a chart is empty Empty or incorrect visualization
SQL fails, times out, or returns surprising data SQL queries
Dashboard tile is broken or stale Dashboards
Iframe is blank, wrong, or exposes too much Embeds
Alert did not evaluate or notify Alerts
Segment, Stripe, or Vercel data stopped Integrations
Cannot sign in, reset a password, or complete 2FA Account access
Subscription or invoice looks wrong Billing
Several unrelated surfaces fail together Possible service incident

Record the boundary first#

Before changing anything, record:

workspace:
environment:
surface or endpoint:
collection:
approximate time:
time zone:
HTTP status or visible error:
one request, one producer, or everyone:
last known working time:
recent deployment or configuration change:

Do not record an API key, password, session token, complete private payload, full generated embed URL, or payment-card data.

Ingestion requests#

Read the status before parsing the body:

const response = await fetch("https://api.graphjson.com/api/log", options);
const text = await response.text();

console.log({
  status: response.status,
  body: text.slice(0, 300)
});
Result Meaning Next action
2xx Request accepted Search the correct workspace, collection, and event time
400 Key, method, JSON, timestamp, query, or field is invalid Fix the request; do not retry unchanged
429 Ingestion request guardrail exceeded Back off with jitter and reduce concurrency
500 Ingestion failed internally Retry a bounded number of times
Timeout or network error Outcome may be unknown Retry only with a stable event_id and deduplicate later

Validate the logging envelope separately from the event:

{
  "api_key": "redacted",
  "collection": "product_events",
  "timestamp": 1785081600,
  "json": "{\"event\":\"signup_completed\",\"event_id\":\"evt_01J...\"}"
}

The outer body is JSON and json is a serialized JSON object. Timestamps are whole Unix seconds, not milliseconds.

For exact error handling and limits, use Errors and limits.

Accepted event is missing#

If logging returned 2xx:

  1. confirm the API key belongs to the intended workspace
  2. confirm the request’s exact collection
  3. open all_events and use Samples
  4. set a broad range such as 7 days ago → now
  5. remove every filter
  6. order descending
  7. convert the request timestamp to an ISO time
  8. check collection retention
  9. search by a stable event_id
console.log(new Date(timestamp * 1000).toISOString());

An event can be accepted but appear outside the expected day because its source timestamp or analysis time zone is wrong.

Use the focused missing-data checklist for a step-by-step investigation.

Empty or incorrect visualization#

First prove that Samples contains representative events. Then rebuild:

  1. graph type: Single Line
  2. aggregation: Count
  3. metric: none
  4. split: none
  5. filters: none
  6. comparison: none
  7. range: broad

Add one control at a time. The first control that changes the result identifies the likely boundary.

Common causes:

Symptom Check
Sum or Avg is empty Metric is a JSON number, not a numeric-looking string
Split is empty Field is present and consistently a string
Counts differ by day IANA time zone and exclusive range boundaries
Unexpected zero buckets hideMissing customization and sparse data
Too many categories High-cardinality split such as request or user ID
Comparison is empty Comparison window has equivalent history
Nested field is absent Flattening choice and exact dot-separated field name

Export the chart as a Data API call and inspect the generated payload. The export is more reliable than manually reconstructing a complex configuration.

SQL queries#

Begin with the smallest possible query:

SELECT timestamp, json
FROM product_events
ORDER BY timestamp DESC
LIMIT 10

Then add extraction, filters, aggregation, and joins one at a time.

Symptom Likely cause
Unknown table Collection name is wrong or used in an unsupported position
Unknown identifier Alias or extracted column is unavailable at that query level
Empty extraction Wrong field name or JSON type
Mutation error Notebook is read-only
Result stops at 2,000 rows Outer result guardrail
Query is slow Wide scan, repeated JSON parsing, large join, or high-cardinality grouping
Chart tab is empty Result columns are not mapped to the selected graph shape

Use GraphJSON SQL compatibility for the supported surface and SQL performance and troubleshooting for query design.

Dashboards#

If one tile fails:

  1. open the tile’s source visualization or saved query
  2. verify its collection still exists
  3. verify the saved query still runs
  4. check the time range and time zone
  5. regenerate the tile only after the source works

If every tile fails, check account access and possible service status before editing each tile.

Stale-looking data may be a time-range issue or an embed cache boundary. Deleting and recreating a dashboard is rarely the right first response.

See Manage and share dashboards.

Embeds#

Separate URL generation from iframe rendering:

server generates URL
        ↓
browser receives only generated URL
        ↓
iframe loads GraphJSON result

If URL generation fails, inspect the server-side API status and redacted error. If generation succeeds but rendering fails:

  • load the generated URL in an isolated test page
  • confirm the iframe has a non-zero height
  • inspect browser content-security-policy errors
  • confirm the URL was not truncated or encoded twice
  • verify the source chart still works
  • allow for the documented 15-minute default cache TTL

If the embed shows the wrong tenant, stop distribution immediately. Verify that the server derives the account filter from the authenticated session and that every cache key includes the tenant and configuration version.

Use Production embedded analytics for the full security checklist.

Alerts#

An alert needs at least N + 1 primary result points. A relative alert needs N + 1 comparison points too.

If it does not evaluate:

  • widen the visualization range
  • reduce the alert window
  • confirm the comparison returns data
  • confirm the Single Line chart works

If it is active but no message is visible:

  • determine whether it was already active before this evaluation
  • inspect recent anomaly history
  • verify recipient type and value
  • check spam filtering or SMS restrictions
  • remember that GraphJSON does not currently expose a delivery log or test-notification button

Use Create and operate alerts for the state machine and current limitations.

Integrations#

When provider events stop:

  1. confirm the integration still appears in GraphJSON
  2. confirm the destination collection still exists
  3. trigger a provider test event
  4. inspect the provider’s delivery or destination status
  5. check authentication or authorization changes at the provider
  6. check payload size and event selection
  7. compare the provider event ID with GraphJSON Samples

Provider retry behavior can produce duplicates. Preserve the provider event ID and reconcile it before treating counts as exact.

Use the provider guide under Integrations or the custom-source adapter guide.

Account access#

Symptom Action
Forgot password Use Reset Password
Reset email absent Check the exact account email and spam filtering
SMS code absent Confirm country code, signal, and SMS availability
Lost access to enrolled phone Contact support from the account email
Session expired Sign in again and retry the original page
Former teammate still has access Remove workspace access and rotate exposed shared credentials

Password reset does not rotate the workspace API key. Team offboarding and API-key exposure are separate workflows.

See Account security and recovery.

Billing#

For an unexpected charge or usage value:

  1. open Settings
  2. record Events Stored
  3. open Manage Subscription
  4. inspect the invoice and billing period
  5. compare the invoice with the pricing page’s high-water-mark definition
  6. review recent imports, duplicates, retention changes, and test collections

Do not delete production data solely to investigate a bill. Export required records and understand that lowering current storage does not rewrite a previously recorded monthly high-water mark.

See Billing and subscription management.

Possible service incident#

Suspect a broader incident when several previously working, unrelated requests or surfaces fail at the same time and no deployment, key, collection, or account change explains them.

GraphJSON does not currently publish an automated public status feed or availability SLA. Check Service status and incident communication and send a safe incident report.

Keep product transactions independent of analytics availability. Queue important events and show an unavailable embed state rather than failing the customer’s primary action.

Build a safe support bundle#

Include:

account email:
workspace name:
approximate time and time zone:
endpoint or dashboard path:
collection:
HTTP status:
redacted error:
application event_id or provider event ID:
scope:
last known working time:
recent change:
retries and their outcome:

Exclude:

  • API keys
  • passwords and session tokens
  • complete customer payloads
  • full embed URLs
  • payment-card or authentication data
  • unrestricted raw exports

Email hi@graphjson.com. Begin with the metadata above; GraphJSON can request a narrower, secure sample if needed.

Need a hand?

Tell us what you’re building and we’ll point you in the right direction.

Contact support