Google Timeline JSON Export Formats: Which Structures Are Supported?

TLDR: The mahlernim/google-timeline-visualizer library supports two distinct Google Timeline JSON export formats: the modern direct-array structure produced by current Android and iOS devices, and the legacy semanticSegments object format used by earlier Google Maps versions.

The mahlernim/google-timeline-visualizer repository provides a Python-based toolset for parsing and visualizing location history data from Google Maps Timeline. Understanding which Google Timeline JSON export formats are compatible is essential for correctly loading movement data regardless of when the export was generated or which platform produced it.

The Two Google Timeline JSON Export Formats

The parser in visualizer.py automatically detects which schema variant you provide by inspecting the root structure of the imported JSON file. You do not need to specify the format manually when calling the parsing functions.

Current Direct-Array Export (Android & iOS)

Modern exports from contemporary Android and iOS devices return a JSON file where the root element is a top-level array. Each item within this array represents an individual timeline segment containing location and timestamp data. This flat structure eliminates the nested object wrapper found in earlier implementations and represents the current standard for Google Maps Timeline exports.

Legacy SemanticSegments Export

Older Google Maps exports wrap location data in a JSON object containing a single key named semanticSegments. The value associated with this key contains the array of segment objects. This structure was standard in earlier iterations of Google Maps Timeline before Google transitioned to the direct-array convention.

Automatic Format Detection in visualizer.py

According to the source code in mahlernim/google-timeline-visualizer, the extract_timeline_points function in visualizer.py implements automatic format inference. When processing input, the function checks whether the JSON root is an array (current format) or an object containing the semanticSegments key (legacy format). It then normalizes both structures into a unified internal representation for coordinate projection and distance calculations.

Parsing Both Export Types

You can process either variant using the same high-level API. The parse_timeline function accepts the file path and an optional year filter, returning standardized data structures regardless of which Google Timeline JSON export format the source file uses.

Example: Direct-Array Export (Current Format)

from visualizer import parse_timeline

# Timeline.json contains a top-level list [...]

points = parse_timeline("path/to/Timeline.json", year=2023)
print(f"Found {len(points[0])} timestamps")

Example: Legacy SemanticSegments Export

from visualizer import parse_timeline

# Timeline.json is an object with a "semanticSegments" field

points = parse_timeline("path/to/legacy_Timeline.json", year=2023)
print(f"Found {len(points[0])} timestamps")

Both calls return an identical tuple structure:

timestamps, xs, ys, cum_dist, lats, lons

Where timestamps contains datetime objects representing chronological movement events, while xs and ys hold projected map coordinates, cum_dist contains cumulative distance data, and lats/lons store the original latitude and longitude values.

Testing Coverage for Export Variants

The repository maintains comprehensive test coverage in tests/test_parser.py. This test suite includes fixtures for both the direct-array and semanticSegments formats, ensuring that updates to visualizer.py do not break compatibility with either historical or current Google Timeline JSON export formats.

Summary

  • The mahlernim/google-timeline-visualizer supports two Google Timeline JSON export formats: the current direct-array structure and the legacy semanticSegments object.
  • The extract_timeline_points function in visualizer.py automatically detects which format you provide based on the JSON root type.
  • Both formats return identical data structures when processed through parse_timeline, containing timestamps, projected coordinates, and cumulative distance metrics.
  • Test coverage in tests/test_parser.py validates parsing accuracy across both export variants.

Frequently Asked Questions

What is the difference between the direct-array and semanticSegments formats?

The direct-array format presents timeline data as a top-level JSON array where each element is a segment, while the semanticSegments format wraps this array inside a JSON object under the semanticSegments key. The direct-array format is produced by current Android and iOS versions of Google Maps, whereas semanticSegments appears in older exports.

How do I know which export format my Timeline JSON uses?

Open the JSON file in a text editor. If the file begins with a square bracket [, you have the direct-array format. If it begins with a curly brace { and contains a semanticSegments property, you have the legacy format. The mahlernim/google-timeline-visualizer library detects this automatically when you call parse_timeline.

Can the visualizer handle exports from both Android and iOS devices?

Yes. Both mobile platforms currently produce the direct-array format, and the parser handles these identically. The library also supports historical exports from either platform that may use the legacy semanticSegments structure.

What data structure does parse_timeline return after parsing the JSON?

The function returns a tuple containing six elements: timestamps (list of datetime objects), xs and ys (projected coordinate arrays), cum_dist (cumulative distance values), and lats and lons (raw latitude and longitude arrays). This standardized output format remains consistent regardless of which input Google Timeline JSON export format was used.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →