CrUX API

The CrUX API gives low-latency access to aggregated real-user experience data at page and origin granularity.

Published on Updated on

Common use case

The CrUX API allows for the querying of user experience metrics for a specific URI like "Get metrics for the https://example.com origin."

CrUX API Key

Using the CrUX API requires a Google Cloud API key. You can create one in the Credentials page and provision it for Chrome UX Report API usage.

After you have an API key, your application can append the query parameter key=[YOUR_API_KEY] to all request URLs.

The API key is safe for embedding in URLs; it doesn't need any encoding.

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 Mobile indicates that the record contains information about loads that took place on a mobile device. Each dimension will have a certain number of values, and implicitly the lack of specifying that dimension will mean that the dimension is aggregated over all values. For example, specifying no form factor indicates that record contains information about loads that took place on any form factor.

Form Factor

The device class that the end-user used to navigate to the page. This is a general class of device split into PHONE, TABLET, and DESKTOP.

Effective Connection Type

Effective Connection Type is the estimated connection quality of the device when navigating to the page. This is a general class split into offline, slow-2G, 2G, 3G and 4G.

Metric

Metrics are expressed in a histogram, which represents the percent of users that experienced a metric with that value proportionally to all.

A simple three bin histogram for an example metric looks like this:

{
"histogram": [
{
"start": 0,
"end": 1000,
"density": 0.38179
},
{
"start": 1000,
"end": 3000,
"density": 0.49905
},
{
"start": 3000,
"density": 0.11916
}
],
}

This data indicates that 38.2% of users experience the example metric value between 0ms and 1,000ms. The units of the metric are not contained in this histogram, in this case we will assume milliseconds.

Additionally, 49.9% of users experience the example metric value between 1,000ms and 3,000ms, and 11.9% of users experience a value greater than 3,000ms.

Metrics will also contain percentiles that can be useful for additional analysis.

{
"percentiles": {
"p75": 2063
},
}

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 do not necessarily match an interpolated percentile that is based on the final binned histogram.

Note: The values for each percentile are synthetically derived, it does not imply that any user actually experienced the value indicated, only that some percentage of users experienced a metric value that was less than the value given.

Metric value types

CrUX API Metric NameData TypeMetric Unitsweb.dev Docs
first_contentful_paintintmillisecondsfcp
largest_contentful_paintintmillisecondslcp
cumulative_layout_shiftdouble encoded as stringunitlesscls
first_input_delayintmillisecondsfid
experimental_time_to_first_byteintmillisecondsttfb
experimental_interaction_to_next_paintintmillisecondsinp

BigQuery metric name mapping

CrUX API Metric NameBigQuery Metric Name
first_contentful_paintfirst_contentful_paint
largest_contentful_paintlargest_contentful_paint
cumulative_layout_shiftlayout_instability.cumulative_layout_shift
first_input_delayfirst_input.delay
experimental_time_to_first_byteexperimental.time_to_first_byte
experimental_interaction_to_next_paintexperimental.interaction_to_next_paint

Example queries

Queries are submitted as JSON objects via a POST request to https://chromeuxreport.googleapis.com/v1/records:queryRecord?key=[YOUR_API_KEY]" with query data as a JSON object in the POST body, e.g.

{
"origin": "https://example.com",
"formFactor": "PHONE",
"metrics": [
"largest_contentful_paint",
"experimental_time_to_first_byte"
]
}

For example, this can be called from curl with the following command line (replacing API_KEY with your key):

curl -s --request POST 'https://chromeuxreport.googleapis.com/v1/records:queryRecord?key=API_KEY' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{"formFactor":"PHONE","origin":"https://www.example.com","metrics",["largest_contentful_paint", "experimental_time_to_first_byte"]}'

Page-level data is available through the API by passing a url property in the query, instead of origin:

{
"url": "https://example.com/page",
"formFactor": "PHONE",
"metrics": [
"largest_contentful_paint",
"experimental_time_to_first_byte"
]
}

If the metrics property is not set then all available metrics will be returned:

  • largest_contentful_paint
  • cumulative_layout_shift
  • experimental_interaction_to_next_paint
  • experimental_time_to_first_byte
  • first_contentful_paint
  • first_input_delay

If no formFactor value is provided then the values will be aggregated across all form factors.

See Using the Chrome UX Report API on web.dev for more example queries.

Data pipeline

The CrUX dataset is processed through a pipeline to consolidate, aggregate and filter the data before becoming available via the API.

The rolling average

The data in the Chrome UX Report is a 28-day rolling average of aggregated metrics. This means that the data presented in the Chrome UX Report at any given time is actually data for the past 28 days aggregated together.

This is similar to how the CrUX dataset on BigQuery aggregates monthly reports.

Daily updates

Data is updated daily around 04:00 UTC. There is no service level agreement for update times; it is run on a best-effort basis every day.

Caution

Data will not differ within the same day after it has been updated around 04:00 UTC, repeated calls will yield the same results.

Schema

There is a single endpoint for the CrUX API which accepts POST HTTP requests. The API returns a record which contains one or more metrics corresponding to performance data about the requested origin or page.

HTTP request

POST https://chromeuxreport.googleapis.com/v1/records:queryRecord

The URL uses gRPC Transcoding syntax.

Request body

The request body should contain data with the following structure:

{
"effectiveConnectionType": string,
"formFactor": enum (FormFactor),
"metrics": [
string
],

// Union field url_pattern can be only one of the following:
"origin": string,
"url": string
// End of list of possible types for union field url_pattern.
}
Fields
effectiveConnectionType

string

The effective connection type is a query dimension that specifies the effective network class that the record's data should belong to. This field uses the values ["offline", "slow-2G", "2G", "3G", "4G"] as specified in: https://wicg.github.io/netinfo/#effective-connection-types

Note: If no effective connection type is specified, then a special record with aggregated data over all effective connection types will be returned.

formFactor

enum (FormFactor)

The form factor is a query dimension that specifies the device class that the record's data should belong to.

Note: If no form factor is specified, then a special record with aggregated data over all form factors will be returned.

metrics[]

string

The metrics that should be included in the response. If none are specified then any metrics found will be returned.

Allowed values: ["first_contentful_paint", "first_input_delay", "largest_contentful_paint", "cumulative_layout_shift", "experimental_time_to_first_byte", "experimental_interaction_to_next_paint"]

Union field url_pattern. The url pattern is the main identifier for a record lookup. It can be one of multiple types of values. url_pattern can be only one of the following:
origin

string

The url pattern "origin" refers to a url pattern that is the origin of a website.

Examples: "https://example.com", "https://cloud.google.com"

url

string

The url pattern "url" refers to a url pattern that is any arbitrary url.

Examples: "https://example.com/", "https://cloud.google.com/why-google-cloud/"

For example, to request the desktop largest contentful paint values for the Chrome developer documentation homepage:

{
"url": "https://developer.chrome.com/docs/",
"formFactor": "DESKTOP",
"metrics": [
"largest_contentful_paint"
]
}

Response body

Successful requests return responses with a record object and urlNormalizationDetails in the following structure:

{
"record": {
"key": {
object (Key)
},
"metrics": [
string: {
object (Metric)
}
]
},
"urlNormalizationDetails": {
object (UrlNormalization)
}
}

For example, the response to the request body in the above request could be:

{
"record": {
"key": {
"formFactor": "DESKTOP",
"url": "https://developer.chrome.com/docs/"
},
"metrics": {
"largest_contentful_paint": {
"histogram": [
{
"start": 0,
"end": 2500,
"density": 0.98148451581189577
},
{
"start": 2500,
"end": 4000,
"density": 0.010814353596591841
},
{
"start": 4000,
"density": 0.0077011305915124116
}
],
"percentiles": {
"p75": 651
}
}
}
}
}

Key

Key defines all the dimensions that identify this record as unique.

{
"effectiveConnectionType": string,
"formFactor": enum (FormFactor),

// Union field url_pattern can be only one of the following:
"origin": string,
"url": string
// End of list of possible types for union field url_pattern.
}
Fields
formFactor

enum (FormFactor)

The form factor is the device class that all users used to access the site for this record.

If the form factor is unspecified, then aggregated data over all form factors will be returned.

effectiveConnectionType

string

The effective connection type is the general connection class that all users experienced for this record. This field uses the values ["offline", "slow-2G", "2G", "3G", "4G"] as specified in: https://wicg.github.io/netinfo/#effective-connection-types

If the effective connection type is unspecified, then aggregated data over all effective connection types will be returned.

Union field url_pattern. The url pattern is the url that the record applies to. url_pattern can be only one of the following:
origin

string

Origin specifies the origin that this record is for.

Note: When specifying an origin, data for loads under this origin over all pages are aggregated into origin level user experience data.

url

string

Url specifies a specific url that this record is for.

Note: When specifying a "url" only data for that specific url will be aggregated.

Metrics

A metric is a set of user experience data for a single web performance metric, such as first contentful paint. It contains a summary histogram of real world Chrome usage as a series of bins.

{
"histogram": [
{
object (Bin)
}
],
"percentiles": {
object (Percentiles)
}
}
Fields
histogram[]

object (Bin)

The histogram of user experiences for a metric. The histogram will have at least one bin and the densities of all bins will add up to ~1.

percentiles

object (Percentiles)

Common useful percentiles of the Metric. The value type for the percentiles will be the same as the value types given for the Histogram bins.

Bin

A bin is a discrete portion of data spanning from start to end, or if no end is given from start to positive infinity.

A bin's start and end values are given in the value type of the metric it represents. For example, first contentful paint is measured in milliseconds and exposed as ints, therefore its metric bins will use int32s for its start and end types. However cumulative layout shift is measured in unitless decimals and is exposed as a decimal encoded as a string, therefore its metric bins will use strings for its value type.

{
"start": value,
"end": value,
"density": number
}
Fields
start

value (Value format)

Start is the beginning of the data bin.

end

value (Value format)

End is the end of the data bin. If end is not populated, then the bin has no end and is valid from start to +inf.

density

number

The proportion of users that experienced this bin's value for the given metric.

Percentiles

Percentiles contains synthetic values of a metric at a given statistical percentile. These are used for estimating a metric's value as experienced by a percentage of users out of the total number of users.

{
"P75": value
}
Fields
p75

value (Value format)

75% of users experienced the given metric at or below this value.

UrlNormalization

Object representing the normalization actions taken to normalize a url to achieve a higher chance of successful lookup. These are simple automated changes that are taken when looking up the provided url_patten would be known to fail. Complex actions like following redirects are not handled.

{
"originalUrl": string,
"normalizedUrl": string
}
Fields
originalUrl

string

The original requested URL prior to any normalization actions.

normalizedUrl

string

The URL after any normalization actions. This is a valid user experience URL that could reasonably be looked up.

Last updated: Improve article

We serve cookies on this site to analyze traffic, remember your preferences, and optimize your experience.