Every GraphJSON event has an event timestamp. Getting this value and its time zone semantics right is essential for accurate trends, comparisons, and cohorts.
Use Unix seconds#
Send the number of whole seconds since 1970-01-01T00:00:00Z:
const timestamp = Math.floor(Date.now() / 1000);
timestamp = int(time.time())
Do not send JavaScript’s raw Date.now() value; it is milliseconds and will be rejected.
| Representation | Example | Send it? |
|---|---|---|
| Unix seconds | 1785081600 |
Yes |
| Unix milliseconds | 1785081600000 |
No |
| Floating-point seconds | 1785081600.25 |
No |
ISO string in timestamp |
"2026-07-26T12:00:00Z" |
No |
Event time, not send time#
The timestamp should represent when the event occurred. For a live request that is usually “now.” For a delayed webhook or backfill, use the source event’s original time.
Using send time for a backfill creates an artificial spike and corrupts retention, funnels, and period comparisons.
Time zones affect buckets#
The visualization and data APIs accept an IANA time zone such as:
America/Los_Angeles
Europe/London
Asia/Tokyo
UTC
The zone determines how GraphJSON interprets calendar boundaries and formats time buckets. The underlying event is still an absolute instant.
Use one business reporting zone consistently for shared dashboards. A “day” grouped in Los Angeles is not the same interval as a day grouped in UTC.
Relative ranges#
GraphJSON accepts relative values for start, end, and compare:
30 minutes ago
12 hours ago
7 days ago
4 weeks ago
3 months ago
1 year ago
now
The API also accepts numeric Unix seconds and parseable date/time strings.
For deterministic reports, send numeric boundaries. Relative values are convenient for live dashboards because the window advances automatically.
Boundary behavior#
Visualizer queries use events after start and before end. Treat both boundaries as exclusive when reconciling exact counts.
When running adjacent fixed windows, choose boundaries carefully so an event exactly on the boundary is handled consistently.
Granularity#
Time-series buckets can be minute, hour, day, week, or month. Auto chooses based on the range:
- short ranges use finer buckets
- long ranges use coarser buckets
Set granularity explicitly when an embed or downstream consumer depends on a stable result shape.
Daylight saving time#
IANA zones apply daylight-saving rules. A local calendar day around a transition can contain 23 or 25 hours. This is correct calendar behavior, but it can surprise hourly comparisons.
Use UTC for infrastructure metrics that should have uniform hours. Use the business’s local zone for calendar reporting such as daily signups or revenue.
Backfills#
For historical imports:
- preserve the source event time
- convert it to Unix seconds
- sort or batch events for efficient ingestion
- validate a small sample before sending the full history
- compare a known daily total with the source system
Use bulk logging in batches of at most 50 events.