Skip to main content

Learn how to use the Chrome UX Reporting API for easy RESTful access to actual UX data across millions of websites.

It appears in:
Fast loading times

the Chrome UX Report The dataset (CrUX) represents how real-world Chrome users experience popular destinations on the web. Since 2017, when the queryable dataset was first released in BigQuery, CrUX field data has been integrated into developer tools such as PageSpeed ​​Insights, CrUX Dashboard, and Search Console. Core Web Vitals Report, allowing developers to easily measure and monitor real user experiences. The piece that has been missing all this time has been a tool that provides free and RESTful access to CrUX data programmatically. To help close that gap, we are pleased to announce the launch of the new Chrome UX Reporting API!

This API has been created with the goal of providing developers with easy, fast and comprehensive access to CrUX data. The CrUX API only reports field user experience data, as opposed to existing PageSpeed ​​Insights API, which also informs laboratory data from Lighthouse performance audits. The CrUX API is streamlined and can quickly serve user experience data, making it ideal for real-time auditing applications.

To ensure developers have access to all the metrics that matter most (the core elements of Web Vitals), the CrUX API audits and monitors Largest Content Paint (LCP), First Entry Delay (FID), and Cumulative Design Change (CLS) at both the source and the URL level.

So let's dive in and see how to use it!

Source data query

The origins in the CrUX dataset span all the underlying experiences at the page level. The following example demonstrates how to query the CrUX API to get user experience data from a source using cURL on the command line.

API_KEY = "[YOUR_API_KEY]"
curl "https://chromeuxreport.googleapis.com/v1/records:queryRecord?key= $API_KEY "
--header 'Content-Type: application / json'
--data '{"origin": "https://web.dev"}'

Run this query interactively on the CrUX API Explorer.

All API requests must provide a value for the key parameter-[YOUR_API_KEY] in the example above it is left as a placeholder. Get your own private CrUX API key with the click of a button on the CrUX API documentation. For added convenience, the interactive CrUX API Explorer it does not require an API key.

the curl The command consists of three parts:

  1. The endpoint of the API URL, including the caller's private API key.
  2. the Content-Type: application / json header, which indicates that the request body contains JSON.
  3. The JSON encoding request body, specifying the https://web.dev source.

To do the same in JavaScript, use the CrUXApiUtil utility, which makes the API call and returns the decoded response.

const CrUXApiUtil = { } ;

CrUXApiUtil . API_KEY = '[YOUR_API_KEY]' ;
CrUXApiUtil . API_ENDPOINT = ` https://chromeuxreport.googleapis.com/v1/records:queryRecord?key= $ { CrUXApiUtil . API_KEY } ` ;
CrUXApiUtil . query = function ( requestBody ) {
if ( CrUXApiUtil . API_KEY == '[YOUR_API_KEY]' ) {
throw 'Replace "YOUR_API_KEY" with your private CrUX API key. Get a key at https://goo.gle/crux-api-key. ' ;
}
return fetch ( CrUXApiUtil . API_ENDPOINT , {
method : 'POST' ,
body : JSON . stringify ( requestBody )
} ) . then ( response => response . json ( ) ) . then ( response => {
if ( response . error ) {
return Promise . reject ( response ) ;
}
return response ;
} ) ;
} ;

Replace [YOUR_API_KEY] with your wrench. Then call CrUXApiUtil.query function and pass in the request body object.

CrUXApiUtil . query ( {
origin : 'https://web.dev'
} ) . then ( response => {
console . log ( response ) ;
} ) . catch ( response => {
console . error ( response ) ;
} ) ;

If data exists for this source, the API response is a JSON-encoded object that contains metrics A representing the distribution of user experiences. The distribution metrics are histogram intervals and percentiles.

{
"record" : {
"key" : {
"origin" : "https://web.dev"
} ,
"metrics" : {
"largest_contentful_paint" : {
"histogram" : [
{
"start" : 0 ,
"end" : 2500 ,
"density" : 0.7925068547983514
} ,
{
"start" : 2500 ,
"end" : 4000 ,
"density" : 0.1317422195536863
} ,
{
"start" : 4000 ,
"density" : 0.07575092564795324
}
] ,
"percentiles" : {
"p75" : 2216
}
} ,

}
}
}

the start and end properties of histogram The object represents the range of values that users experience for the given metric. the density The property represents the proportion of user experiences within that range. In this example, the 79% of LCP user experiences on all web.dev pages are below 2500 milliseconds, which is the "good" LCP threshold. the percentiles.p75 The value means that the 75% of user experiences in this distribution is less than 2216 milliseconds. Learn more about the response structure in the response body documentation.

Mistakes

When the CrUX API doesn't have any data for a given origin, it responds with a JSON-encoded error message:

{
"error" : {
"code" : 404 ,
"message" : "chrome ux report data not found" ,
"status" : "NOT_FOUND"
}
}

To debug this bug, first verify that the requested origin is publicly browsable. You can test this by entering the origin in your browser's URL bar and comparing it to the final URL after any redirects. Common problems include unnecessarily adding or omitting the subdomain and using the wrong HTTP protocol.

Error

{ "origin" : "http://www.web.dev" }

This source incorrectly includes the http: // protocol and www. subdomain.

Success

{ "origin" : "https://web.dev" }

This origin is publicly navigable.

If the requested origin it is the browsable version, this error can also occur if the source has an insufficient number of samples. All sources and URLs included in the dataset must have a sufficient number of samples to anonymize individual users. Also, the origins and URLs must be publicly traceable. Refer to CrUX methodology for more information on how websites are included in the dataset.

URL data query

You have seen how to query the CrUX API for the overall user experience in a source. To restrict the results to a particular page, use the url request parameter.

API_KEY = "[YOUR_API_KEY]"
curl "https://chromeuxreport.googleapis.com/v1/records:queryRecord?key= $API_KEY "
--header 'Content-Type: application / json'
--data '{"url": "https://web.dev/fast/"}'

This cURL command is similar to the source example, except that the request body uses the url parameter to specify the page to search for.

To query URL data from the CrUX API in JavaScript, call CrUXApiUtil.query function using the url parameter in the request body.

CrUXApiUtil . query ( {
url : 'https://web.dev/fast/'
} ) . then ( response => {
console . log ( response ) ;
} ) . catch ( response => {
console . error ( response ) ;
} ) ;

If data for this URL exists in the CrUX dataset, the API will return a JSON-encoded response like the one shown below.

{
"record" : {
"key" : {
"url" : "https://web.dev/fast/"
} ,
"metrics" : {
"largest_contentful_paint" : {
"histogram" : [
{
"start" : 0 ,
"end" : 2500 ,
"density" : 0.8477304539092148
} ,
{
"start" : 2500 ,
"end" : 4000 ,
"density" : 0.08988202359528057
} ,
{
"start" : 4000 ,
"density" : 0.062387522495501155
}
] ,
"percentiles" : {
"p75" : 1947
}
} ,

}
}
}

True to form, the results show that https://web.dev/fast/ it has an 85% of "good" LCP experiences and a 75th percentile of 1,947 milliseconds, which is slightly better than the whole source distribution.

URL normalization

The CrUX API can normalize the requested URLs to better match the list of known URLs. For example, query the URL https://web.dev/fast/#measure-performance-in-the-field will result in data for https://web.dev/fast/ due to standardization. When this happens, a urlNormalizationDetails The object will be included in the response.

{
"record" : {
"key" : {
"url" : "https://web.dev/fast/"
} ,
"metrics" : { ... }
} ,
"urlNormalizationDetails" : {
"normalizedUrl" : "https://web.dev/fast/" ,
"originalUrl" : "https://web.dev/fast/#measure-performance-in-the-field"
}
}

Learn more about URL normalization in the CrUX documentation.

Query by form factor

Key term:
A form factor is the type of device on which a user visits a website. Common device types include desktops, phones, and tablets.

User experiences can vary significantly based on website optimizations, network conditions, and user devices. To better understand these differences, dig into the origin and performance of the URL using the formFactor CrUX API dimension.

The API supports three explicit form factor values: DESKTOP, PHONEand TABLET. In addition to the origin or URL, specify one of these values in the request body to restrict results to user experiences only. The following example demonstrates how to query the API by form factor using cURL.

API_KEY = "[YOUR_API_KEY]"
curl "https://chromeuxreport.googleapis.com/v1/records:queryRecord?key= $API_KEY "
--header 'Content-Type: application / json'
--data '{"url": "https://web.dev/fast/", "formFactor": "PHONE"}'

To query the CrUX API for form factor specific data using JavaScript, call CrUXApiUtil.query function using the url and formFactor parameters in the request body.

CrUXApiUtil . query ( {
url : 'https://web.dev/fast/' ,
formFactor : 'PHONE'
} ) . then ( response => {
console . log ( response ) ;
} ) . catch ( response => {
console . error ( response ) ;
} ) ;

Skipping the formFactor parameter is equivalent to requesting data for all form factors combined.

{
"record" : {
"key" : {
"url" : "https://web.dev/fast/" ,
"formFactor" : "PHONE"
} ,
"metrics" : {
"largest_contentful_paint" : {
"histogram" : [
{
"start" : 0 ,
"end" : 2500 ,
"density" : 0.778631284916204
} ,
{
"start" : 2500 ,
"end" : 4000 ,
"density" : 0.13943202979515887
} ,
{
"start" : 4000 ,
"density" : 0.08193668528864119
}
] ,
"percentiles" : {
"p75" : 2366
}
} ,

}
}
}

the key the response field will echo the formFactor Request setup to confirm that only phone experiences are included.

Caution:
The more detailed the request, for example a specific URL and form factor combination, the fewer user experiences it will include. This can lead to more frequent "not found" errors, especially when viewing less popular URLs or the less popular type of tablet device.

Recall from the previous section that the 85% of user experiences on this page had a "good" LCP. Compare that to specific phone experiences, of which only the 78% is considered "good." The 75th percentile is also slowest among phone experiences, going from 1,947 milliseconds to 2,366 milliseconds. Form factor targeting has the potential to highlight more extreme disparities in user experiences.

Core Web Vitals performance evaluation

The Core Web Vitals program defines goals that help determine whether a user experience or distribution of experiences can be considered "good." In the following example, we use the CrUX API and the CrUXApiUtil.query function to evaluate whether the distribution of Core Web Vitals metrics (LCP, FID, CLS) of a web page is "good".

CrUXApiUtil . query ( {
url : 'https://web.dev/fast/'
} ) . then ( response => {
assessCoreWebVitals ( response ) ;
} ) . catch ( response => {
console . error ( response ) ;
} ) ;

function assessCoreWebVitals ( response ) {

const CORE_WEB_VITALS = [
'largest_contentful_paint' ,
'first_input_delay' ,
'cumulative_layout_shift'
] ;
CORE_WEB_VITALS . forEach ( metric => {
const data = response . record . metrics [ metric ] ;
if ( ! data ) {
console . log ( 'No data for' , metric ) ;
return ;
}
const p75 = data . percentiles . p75 ;
const threshold = data . histogram [ 0 ] . end ;


const passes = p75 < threshold ;
console . log ( ` The 75th percentile ( $ { p75 } ) of $ { metric } ` +
` $ { passes ? 'passes' : 'does not pass' } ` +
` the Core Web Vitals" good "threshold ( $ { threshold } ). ` )
} ) ;
}

Gotchas!

The API can only be called with one origin or URL at a time. To evaluate multiple websites or pages, make separate API calls.

The results show that this page passes the Core Web Vitals assessments for all three metrics.

The 75th percentile (1973) of largest_contentful_paint passes the Core Web Vitals "good" threshold (2500).
The 75th percentile (20) of first_input_delay passes the Core Web Vitals "good" threshold (100).
The 75th percentile (0.05) of cumulative_layout_shift passes the Core Web Vitals "good" threshold (0.10).

Combined with an automated way of monitoring API results, CrUX data can be used to ensure that user experiences get fast and stay fast. For more information on Core Web Vitals and how to measure them, see Web Vitals and Tools for Measuring Core Web Vitals.

Whats Next?

The features included in the initial release of the CrUX API only scratch the surface of the types of information that are possible with CrUX. Users of the CrUX dataset in BigQuery may be familiar with some of the more advanced features, including:

  • Additional metrics
    • first_paint
    • dom_content_loaded
    • onload
    • time_to_first_byte
    • notification_permissions
  • Additional dimensions
    • month
    • country
    • effective connection type (ECT)
  • Additional granularity
    • detailed histograms
    • more percentiles

Over time, we hope to integrate more of these features with the ease of use and free pricing of the CrUX API to enable new ways to explore data and discover insights into the state of user experiences on the web.

Take a look at the official CrUX API documents to acquire your API key and explore more sample applications. We hope you give it a try and would love to hear any questions or comments you may have, so reach out to us at CrUX discussion forum. And to stay up to date with everything we have planned for the CrUX API, subscribe to CrUX Ads Forum or follow us on Twitter at @ChromeUXReport.

R Marketing Digital