Published: Feb 7, 2023, Last updated: Apr 11, 2025
The CrUX History API gives low-latency access to six months of historical real-user experience data at page and origin granularity.
Common use case
The CrUX History API allows for the querying of historical user experience metrics for a specific URI like "Get the historical UX trends for the https://example.com origin."
The History API follows the same structure as the daily CrUX API except values are given in an array, and keys are labelled with plural names (for example, histogramTimeseries instead of histogram, or p75s instead of p75).
CrUX API Key
Like the daily API, using the CrUX History API requires a Google Cloud API key provisioned for Chrome UX Report API usage. The same key can be used for the daily and history API.
Acquiring and using an API key
Get a KeyOr create one in the Credentials page.
After you have an API key, your application can append the query parameter
key=yourAPIKey to all request URLs.
The API key is safe for embedding in URLs; it doesn't need any encoding.
See Example queries.
Data model
This section details the structure of data in requests and responses.
Record
A discrete piece of information about a page, or site. A record can have data that is specific for an identifier and for a specific combination of dimensions. A record can contain data for one or more metrics.
Identifiers
Identifiers specify what records should be looked up. In CrUX these identifiers are webpages and websites.
Origin
When the identifier is an origin all data present for all pages in that origin are aggregated together. For example, say the http://www.example.com origin had pages as laid out by this sitemap:
http://www.example.com/
http://www.example.com/foo.html
http://www.example.com/bar.html
This would mean that when querying the Chrome UX Report with the origin set to http://www.example.com, data for http://www.example.com/, http://www.example.com/foo.html, and http://www.example.com/bar.html would be returned, aggregated together, because those are all pages under that origin.
URLs
When the identifier is a URL, only data for that specific URL will be returned. Looking again to the http://www.example.com origin sitemap:
http://www.example.com/
http://www.example.com/foo.html
http://www.example.com/bar.html
If the identifier is set to URL with the value of http://www.example.com/foo.html, only data for that page will be returned.
Dimensions
Dimensions identify a specific group of data that a record is being aggregated against. For example, a form factor of PHONE indicates that the record contains information about loads that took place on a mobile device.
Form Factor
The CrUX History API is only available aggregated by form factor dimension. This is a general class of device split into PHONE, TABLET, and DESKTOP.
Metric
We report metrics in timeseries of statistical aggregations, which are histograms, percentiles, and fractions.
Histograms
When metrics are expressed in a histogram array, then each timeseries entry represents the percentage of page loads for which the metric fell into an interval, proportionally to all. The data points are presented in the order of the collection period dates also returned by the API, with the first point being the earliest period, and the final point being the most recent collection period.
A three bin histogram for an example metric looks like this:
{
"histogramTimeseries": [
{
"start": 0,
"end": 2500,
"densities": [0.9190, 0.9203, 0.9194, 0.9195, 0.9183, 0.9187]
},
{
"start": 2500,
"end": 4000,
"densities": [0.0521, 0.0513, 0.0518, 0.0518, 0.0526, 0.0527]
},
{
"start": 4000,
"densities": [0.0288, 0.0282, 0.0286, 0.0285, 0.0290, 0.0285]
}
],
}
This data indicates that 91.90% of page loads experienced the example metric value between 0ms and 2,500ms for the first collection period in the history, followed by 92.03%, 91.94%... The units of the metric are not contained in this histogram, in this case we will assume milliseconds.
Additionally, 5.21% of page loads experienced the example metric value between 2,500ms and 4,000ms in the first collection period in the history, and 2.88% of page loads experienced a value greater than 4,000ms in the first collection period in the history.
Percentiles
Metrics may also contain timeseries of percentiles that can be useful for additional analysis.
The data points are presented in the order of the collection period dates also returned by the API, with the first point being the earliest period, and the final point being the most recent collection period.
{
"percentilesTimeseries": {
"p75s": [1362, 1352, 1344, 1356, 1366, 1377]
},
}
These percentiles can show specific metric values at the given percentile for that metric. They are based on the full set of available data and not the final binned data, so they don't necessarily match an interpolated percentile that is based on the final binned histogram.
Fractions
Metrics may be expressed as timeseries of labeled fractions; each label describes a page load in a particular way. The data points are presented in the order of the collection period dates also returned by the API, with the first point being the earliest period, and the final point being the most recent collection period.
Example:
{
"fractionTimeseries": {
"desktop": {"fractions": [0.3195, 0.2115, 0.1421]},
"phone": {"fractions": [0.6295, 0.7544, 0.8288]},
"tablet": {"fractions": [0.051, 0.0341, 0.029]}
}
}
In this example, the most recent data point indicates 14.21% of page loads came from desktop, and 82.88% came from phones.
Metric value types
As the CrUX History API uses the same metric value types, you can reference the daily CrUX API metric value types documentation for more details.
Metric eligibility
Based on the eligibility criteria an origin or URL may only be eligible for some of the collection periods covered by the CrUX History API. In these cases the CrUX History API will return "NaN" for the histogramTimeseries densities and null for the percentilesTimeseries for the collection periods which have no eligible data. The reason for the difference is the histogram densities are always numbers, while the percentiles can be numbers or strings (CLS uses strings, even if they look like numbers).
For example, if the second period did not have any eligible data, this would show as:
{
"histogramTimeseries": [
{
"start": 0,
"end": 2500,
"densities": [0.9190, "NaN", 0.9194, 0.9195, 0.9183, 0.9187]
},
{
"start": 2500,
"end": 4000,
"densities": [0.0521, "NaN", 0.0518, 0.0518, 0.0526, 0.0527]
},
{
"start": 4000,
"densities": [0.0288, "NaN", 0.0286, 0.0285, 0.0290, 0.0285]
}
],
"percentilesTimeseries": {
"p75s": [1362, null, 1344, 1356, 1366, 1377]
},
}
For URLs or origins that fall in and out of eligibility over time, you may notice many missing entries.
Collection periods
The CrUX History API contains a collectionPeriods object with an array of firstDate and endDate fields representing the beginning and end dates of each aggregation window. For example:
"collectionPeriods": [{
"firstDate": { "year": 2022, "month": 7, "day": 10 },
"lastDate": { "year": 2022, "month": 8, "day": 6 }
}, {
"firstDate": { "year": 2022, "month": 7, "day": 17 },
"lastDate": { "year": 2022, "month": 8, "day": 13 }
}, {
"firstDate": { "year": 2022, "month": 7, "day": 24 },
"lastDate": { "year": 2022, "month": 8, "day": 20 }
}, {
"firstDate": { "year": 2022, "month": 7, "day": 31 },
"lastDate": { "year": 2022, "month": 8, "day": 27 }
},