Allows to download CSV file with raw RUM data.
Overview and requirements
This endpoint returns an S3 pre-signed URL for the specified RUM export file. The URL expires in 10 minutes.
Daily exports
RUM export files are done on a daily basis and contain the data from 00:00:00 to 23:59:59 UTC.
Files become available after 5am UTC. If you try to access the file between midnight and 5am you'll get a URL that returns an error.
This API endpoint is not enabled by default. In order to use this endpoint, you must check the Enable RUM export API checkbox in your SpeedCurve team's RUM settings. Please note that RUM export data will only be generated from that point in time forwards.
Hourly exports
Use date
(day in YYYYMMDD
format) and hour
(0-23) request parameters to retrieve hourly exports up to last hour.
Last hour data becomes available 15 minutes past.
Example request: https://api.speedcurve.com/v1/lux/export/?date=20241025&hour=3
Rate limits
Please note that rate limits applied to this API and you can only send 3 requests per minute.
File Format and Schema
The RUM export file is in CSV syntax. Instead of comma, the delimiter is the caret character (^).
Each row in the export can be one of three types:
-
Main Row
There will always be one main row and it can be identified by
dom_element_count > 0
-
User Timing Row
There can be zero or more user timing rows depending on how many marks and measures are present on the page. These rows can be identified by
user_timing_start > 0
-
Interaction Row
If a visitor interacts with the page after the main beacon was been sent then there will be a separate interaction row that can be identified by
interaction_time > 0
-
Custom Data Row
IfLUX.addData()
is called after the main beacon was sent, the custom data will be present in one or more custom data rows.
The column names are as follows. You can also find them below in the Exact order of columns in the CSV section.
page_id^session_id^epoch^account_id^page_label^url_unused^user_agent^browser_and_version^page_flags^continent^country^country_subdivision^city^external_script_count^blocking_external_script_count^stylesheet_count^blocking_stylesheet_count^font_count^image_above_the_fold_count^average_dom_depth^dom_element_count^viewport_width^viewport_height^document_width^document_height^navigation_start^redirect_start^redirect_end^fetch_start^domain_lookup_start^domain_lookup_end^connect_start^secure_connection_start^connect_end^request_start^response_start^response_end^dom_loading^dom_interactive^dom_content_loaded_event_start^dom_content_loaded_event_end^dom_complete^load_event_start^load_event_end^start_render^first_input_delay^long_tasks^interaction_type^interaction_time^interaction_element_selector^interaction_x_coordinate^interaction_y_coordinate^user_timing_name^user_timing_start^custom_data^device_type^image_count^document_transfer_size^connection_type^first_contentful_paint^inline_script_size^inline_style_size^device_memory^largest_contentful_paint^element_timing^cumulative_layout_shift^hostname^pathname^interaction_to_next_paint^inp_element_selector^inp_start_time^inp_input_delay^inp_processing_time^inp_presentation_delay^lcp_element_render_delay^lcp_element_selector^lcp_element_type^lcp_resource_load_delay^lcp_resource_load_time^cls_largest_entry_start_time^cls_largest_entry_value^delivery_type^operating_system^user_timing_duration^beacon_type
Detailed information about each column is below. Please note this information is grouped by the type of data - it is not listed in the column order.
Page Information
Field | Type | Description |
---|---|---|
page_id | BIGINT | Unique ID for this page view |
session_id | BIGINT | Unique ID for this session |
epoch | INT | Unix timestamp (seconds since the Unix epoch) of the time the information was recorded |
account_id | INT | Your account/team ID |
page_label | VARCHAR (255) | Label for the page. If no label was specified, the document title is used |
page_flags | INT | Bitmask of flags. View the lux.js source code for up-to-date flag definitions |
url_unused | Empty field | Deprecated in July 2020 and removed in February 2022. Use the hostname and pathname fields instead |
hostname | VARCHAR (255) | The hostname portion of the page URL |
pathname | VARCHAR (255) | The pathname portion of the page URL |
delivery_type | VARCHAR (32) | Delivery type of the page |
beacon_type | ENUM | The type of beacon row: main , user_timing , interaction , custom_data , or other |
Device Information
Field | Type | Description |
---|---|---|
user_agent | VARCHAR (500) | Full User-Agent HTTP request header |
browser_and_version | VARCHAR (64) | Browser name and browser version e.g. "Chrome 128" or "Firefox 99" |
operating_system | VARCHAR (16) | Device operating system e.g. "Windows" or "iOS" |
device_type | VARCHAR (32) | mobile , tablet , or desktop |
device_memory | SMALLINT | Estimated device memory in GB |
connection_type | VARCHAR (32) | Browser connection type, if available. Values are Slow 2G , 2G , 3G , or 4G |
Geographical Information
Field | Type | Description |
---|---|---|
continent | VARCHAR (2) | |
country | VARCHAR (2) | ISO 3166 country code |
country_subdivision | VARCHAR (16) | ISO 3166-2 country subdivision |
city | VARCHAR (64) |
Page Stats
Field | Type | Description |
---|---|---|
external_script_count | SMALLINT | Number of external scripts |
blocking_external_script_count | SMALLINT | Number of blocking external scripts |
inline_script_size | INT | Uncompressed inline script size in bytes |
stylesheet_count | SMALLINT | Number of stylesheets |
blocking_stylesheet_count | SMALLINT | Number of blocking stylesheets |
inline_style_size | INT | Uncompressed inline style size in bytes |
inline_style_size | INT | Uncompressed inline style size in bytes |
font_count | SMALLINT | Number of font files |
image_count | SMALLINT | Number of <img> tags on the page |
image_above_the_fold_count | SMALLINT | Number of images in the viewport |
document_transfer_size | INT | Transfer size of the HTML document in bytes |
average_dom_depth | SMALLINT | Average DOM depth |
dom_element_count | INT | Total number of DOM elements on the page |
viewport_width | INT | Viewport width in pixels |
viewport_height | INT | Viewport height in pixels |
document_width | INT | Document width in pixels |
document_height | INT | Document height in pixels |
Navigation Timing Metrics
For more information about these metrics, please see the PerformanceNavigationTiming documentation on MDN. All values are in milliseconds.
Field | Type | Description |
---|---|---|
navigation_start | INT | |
redirect_start | INT | |
redirect_end | INT | |
fetch_start | INT | |
domain_lookup_start | INT | |
domain_lookup_end | INT | |
connect_start | INT | |
secure_connection_start | INT | |
connect_end | INT | |
request_start | INT | |
response_start | INT | Also known as Time to First Byte (TTFB) |
response_end | INT | |
dom_loading | INT | |
dom_interactive | INT | |
dom_content_loaded_event_start | INT | |
dom_content_loaded_event_end | INT | |
dom_complete | INT | |
load_event_start | INT | |
load_event_end | INT |
Rendering Metrics
Field | Type | Description |
---|---|---|
start_render | INT | Also known as First Paint. When the browser first renders pixels to the screen (milliseconds since navigation start) |
first_contentful_paint | INT | When the browser first renders any text, image, video, non-empty SVG, or non-empty canvas (milliseconds since navigation start) |
largest_contentful_paint | INT | When the browser renders the largest image or block of text (milliseconds since navigation start) |
lcp_element_render_delay | INT | The time between when the LCP resource finishes loading and the LCP element renders fully (milliseconds) |
lcp_resource_load_delay | INT | The time between TTFB and when the browser starts loading the LCP resource (milliseconds) |
lcp_resource_load_time | INT | The duration of time it takes to load the LCP resource itself (milliseconds) |
lcp_element_selector | VARCHAR (120) | |
lcp_element_type | VARCHAR (32) | |
cumulative_layout_shift | FLOAT (4) | A measure of the largest burst of layout shift scores over the lifecycle of the page |
cls_largest_entry_start_time | INT | When the largest layout shift started (milliseconds since navigation start) |
cls_largest_entry_value | FLOAT (4) | The score of the largest layout shift |
element_timing | VARCHAR (255) | Element timing data. Format detail. |
Long Task and CPU Information
Field | Type | Description |
---|---|---|
long_tasks | VARCHAR (512) | Long task information. Format detail |
Interaction (IX) Metrics
SpeedCurve collects information about the first page interaction and stores it in the interaction_*
columns. INP data is collected continuously and may not be from the first interaction.
Field | Type | Description |
---|---|---|
interaction_type | VARCHAR (32) | scroll , click , or key |
interaction_time | INT | When the interaction occurred. |
interaction_element_selector | VARCHAR (32) | DOM element data-sctrack attribute or ID (only valid for click and key) |
interaction_x_coordinate | INT | The x position of the trackid DOM element. |
interaction_y_coordinate | INT | The y position of the trackid DOM element. |
interaction_to_next_paint | INT | Interaction to Next Paint duration value |
inp_element_selector | VARCHAR (100) | INP Element Selector |
inp_start_time | INT | When the user interacted with the page (milliseconds since navigation start) |
inp_input_delay | INT | How long between the user interacting with the page and the event handlers to start (milliseconds) |
inp_processing_time | INT | How long it took the event handlers to run until completion (milliseconds) |
inp_presentation_delay | INT | How long it took for the browser to present the next frame which contains the visual result of the interaction (milliseconds) |
first_input_delay | INT | First Input Delay value (milliseconds) |
Learn more about INP attribution and subparts.
User Timing and Custom Data
Field | Type | Description |
---|---|---|
user_timing_name | VARCHAR (128) | Name of the mark or measure |
user_timing_start | INT | Time of the mark (milliseconds since navigation start) |
user_timing_duration | INT | Duration of the measure (milliseconds) |
custom_data | VARCHAR (1000) | Data specified using LUX.addData() Format detail |
Long Task Format
The long_tasks
field is a delimited string with this syntax:
type|total,n|count,d|median,x|max,[i|first_cpu_idle,]start|duration[,start|duration] [|type|total,n|count,d|median,x|max,start|duration[,start|duration]]
Currently the only type supported is JavaScript ("s") as this is the only data available from the Long Tasks API at this time. This example shows there were three long tasks starting at 306 ms, 448 ms, and 534 ms that totalled to 806 ms:
s|806,n|3,d|448,x|534,i|1134,306|128,448|78,534|600
Custom Data Format
The custom_data
field represents custom data variables as a delimited string containing name-value tuples for each variable set using LUX.addData()
. The name-value tuple is delimited by "|". The tuples are comma-delimited. An example value from speedcurve.com is:
,loggedin|yes,team|1,tvmode|0,
Element Timing Format
The element_timing
field is a delimited string containing name-value pairs for each element measured using the Element Timing API. The name-value pair is delimited by "|". The pairs are comma-delimited. An example value is:
nav-links|1409,nav-title|1409,lead-image|2255
This indicates that the nav-links element was displayed 1409 ms after navigation start, nav-title after 1409 ms, and lead-image after 2255 ms.
Data Structure
There are four types of rows in the export file: Main, User Timing, Custom Data, and Interaction Metrics. For a given page view, there can be multiple rows:
- There is always one-and-only-one Main row.
- If there are "n" User Timing marks and measures in the page, then there are "n-1" separate User Timing rows. (The first User Timing mark or measure is included in the Main row.)
- If the user interacts with the page after the main beacon has been sent, then a supplementary interaction row will be present.
- If custom data is sent with
LUX.addData()
after the main beacon has been sent then there may be several supplementary Custom Data rows.
Exact order of columns in the CSV
The following is the order of columns in the exported CSV file. Please find column descriptions in the tables above.
page_id
session_id
epoch
account_id
page_label
url_unused
user_agent
browser_and_version
page_flags
continent
country
country_subdivision
city
external_script_count
blocking_external_script_count
stylesheet_count
blocking_stylesheet_count
font_count
image_above_the_fold_count
average_dom_depth
dom_element_count
viewport_width
viewport_height
document_width
document_height
navigation_start
redirect_start
redirect_end
fetch_start
domain_lookup_start
domain_lookup_end
connect_start
secure_connection_start
connect_end
request_start
response_start
response_end
dom_loading
dom_interactive
dom_content_loaded_event_start
dom_content_loaded_event_end
dom_complete
load_event_start
load_event_end
start_render
first_input_delay
long_tasks
interaction_type
interaction_time
interaction_element_selector
interaction_x_coordinate
interaction_y_coordinate
user_timing_name
user_timing_start
custom_data
device_type
image_count
document_transfer_size
connection_type
first_contentful_paint
inline_script_size
inline_style_size
device_memory
largest_contentful_paint
element_timing
cumulative_layout_shift
hostname
pathname
interaction_to_next_paint
inp_element_selector
inp_start_time
inp_input_delay
inp_processing_time
inp_presentation_delay
lcp_element_render_delay
lcp_element_selector
lcp_element_type
lcp_resource_load_delay
lcp_resource_load_time
cls_largest_entry_start_time
cls_largest_entry_value
delivery_type
operating_system
user_timing_duration
beacon_type
Query tips
Here are some tips for querying the data.
- Use
page_id
to get all the rows for a single page view. - Use
session_id
to get all the rows for a single session. - To find all Main rows, query for
dom_element_count > 0
. This is because some browsers still do not support Navigation Timing, but all pages have a non-zero number of DOM elements, and the number of DOM elements is only stored in Main rows. - The easiest way to find all User Timing rows is to query for
user_timing_start > 0
. Note that this can return one Main row that has the first User Timing metric. - The easiest way to find all Interaction Metrics rows is to query for
interaction_time > 0
. Note that this may return a Main row is the user interacted with the page before the main beacon was sent. - To find a specific custom data variable, prepend it with a comma. For example with SQL:
custom_data LIKE ',loggedin%'