Professor Sloth

Feature Release

Announcing Unified Web Performance: automatic lab testing, real user monitoring, and Google SEO scores.

Data API Reference

Pull Core Web Vitals, page load time, and traffic for your website out of Request Metrics as JSON.

The Request Metrics API returns the real user monitoring data for a website as JSON. One endpoint gives totals for the whole website. The other breaks the same numbers down by URL. The API only reads data, so no request can change your account.

Every metric is the 75th percentile across the page views in your date range. That’s the number the Request Metrics dashboard shows, and it’s the number Google uses to judge Core Web Vitals.

What you need

Every request needs three values.

Value Parameter What it is
Account ID customerId 7 characters, one per account
Website ID applicationId 7 characters, one per website in the account
API key key one per account, and it works for every website in the account

Account administrators find all three on the Account Settings page. That page also has example links with your IDs and key filled in. Open one to confirm everything works before you write any code.

Warning: Your API key lets anyone read the performance data for every website in your account. The key travels in the URL, so any copy of a request URL carries a live key. Keep those URLs out of shared documents, tickets, screenshots, and logs.

Authentication

Pass your API key as the key query parameter on every request. There’s no header authentication. Request Metrics checks the key against the account in customerId and returns HTTP 401 when the key is missing or belongs to a different account.

Endpoints

Both endpoints live under https://app.requestmetrics.com/api/v1/{customerId}/{applicationId}.

Overall website performance

GET /api/v1/{customerId}/{applicationId}/performance

Returns one object with totals for the website over the date range. It takes the key, p, and device_filter parameters.

curl "https://app.requestmetrics.com/api/v1/{customerId}/{applicationId}/performance?p=7d&key={apiKey}"
{
  "data": {
    "pageLoads": 48213,
    "userCount": 12050,
    "loadP75": 1840,
    "fcp": 1120,
    "lcp": 2240,
    "cls": 0.04,
    "inp": 160,
    "ttfb": 410,
    "rmUrl": "https://app.requestmetrics.com/app/{applicationId}"
  },
  "metadata": {
    "startDate": "2026-10-20T17:04:12.441+00:00",
    "deviceFilter": "overall"
  }
}
metadata field Meaning
startDate start of the date range, ISO 8601 in UTC
deviceFilter overall, desktop, or mobile

Performance by URL

GET /api/v1/{customerId}/{applicationId}/performance/pages

Returns an array with one object per URL or URL group, sorted by page views from most to fewest. It takes every parameter in the next section.

curl "https://app.requestmetrics.com/api/v1/{customerId}/{applicationId}/performance/pages?p=30d&device_filter=mobile&key={apiKey}"
{
  "data": [
    {
      "pageUrl": "https://example.com/pricing",
      "pageLoads": 8120,
      "userCount": 5230,
      "loadP75": 1600,
      "fcp": 980,
      "lcp": 2010,
      "cls": 0.02,
      "inp": 140,
      "ttfb": 360,
      "rmUrl": "https://app.requestmetrics.com/app/{applicationId}/ux/explore/load/{filter}"
    }
  ],
  "metadata": {
    "startDate": "2026-09-27T17:04:12.441+00:00",
    "deviceFilter": "mobile",
    "urlGroupingMode": "ungrouped",
    "currentPage": 1,
    "pageSize": 50,
    "totalPages": 7,
    "totalItems": 312
  }
}
metadata field Meaning
startDate start of the date range, ISO 8601 in UTC
deviceFilter overall, desktop, or mobile
urlGroupingMode ungrouped, grouped, or custom
currentPage the page of results returned
pageSize results per page
totalPages number of pages at this pageSize
totalItems number of URLs or groups in the date range

Parameters

Parameter Endpoints Values Default
key both your API key required
p both a date range 24h
device_filter both mobile or desktop all devices
urlGrouping by URL ungrouped, grouped, or custom ungrouped
page by URL page number, starting at 1 1
size by URL results per page 50

Date range

p takes a named range or a custom one.

Value Range
60m last 60 minutes
24h last 24 hours
72h last 72 hours
7d last 7 days
30d last 30 days
60d last 60 days
90d last 90 days

For a custom range, pass p=c_{start}_{end} with the start and end in Unix epoch seconds. p=c_1730498400_1730584800 is one day. The start has to come before the end. The range can’t reach back more than 90 days or end in the future.

Warning: The API doesn’t reject a date range it can’t use. A misspelled range, or a custom range that breaks one of those rules, returns the last 24 hours with no error. Check metadata.startDate in the response to confirm you got the range you asked for.

Your plan’s data retention limits how far back data goes. A 90d request on a plan that keeps 30 days returns those 30 days.

Device filter

Leave device_filter off to include every device. Set it to mobile or desktop to narrow the results. Any other value counts as all devices.

URL grouping

urlGrouping sets what pageUrl holds on the performance by URL endpoint.

Value pageUrl holds
ungrouped the page URL without its query string or hash, so /search?q=shoes and /search?q=hats both count as /search
grouped the URL after automatic grouping and any grouping rules you set in the app. IDs, UUIDs, and long slugs become placeholders, so /orders/4821 and /orders/5102 share one row.
custom the group name your website sets with the urlGroup install option or RM.setUrlGroup. Page views without a group name share one row with an empty pageUrl.

URL Grouping explains how to send custom group names from your website.

Paging

The performance by URL endpoint returns 50 rows at a time unless you set size. Read metadata.totalItems and request each page in turn until you have that many rows. Drive paging from totalItems, because totalPages can count one extra, empty page.

Response fields

Both endpoints return data and metadata. On the overall endpoint, data is one object. On the performance by URL endpoint, data is an array of the same objects, each with a pageUrl.

Field Meaning Unit
pageUrl the URL or group, performance by URL only  
pageLoads page views in the date range count
userCount unique users in the date range count
loadP75 page load time ms
lcp Largest Contentful Paint ms
cls Cumulative Layout Shift none
inp Interaction to Next Paint ms
fcp First Contentful Paint ms
ttfb Time to First Byte ms
rmUrl a link to the same view in the Request Metrics app  

A metric of -1 means there was no data for it in the date range. Leave it out of averages and charts.

userCount counts the IDs your website passes to RM.identify, or anonymous browser IDs if it doesn’t call it. It’s an estimate, so small changes between date ranges don’t mean much.

Rating the numbers

Request Metrics rates each metric against Google’s thresholds. LCP, INP, and CLS are the three Core Web Vitals.

Metric Good Needs improvement Poor
LCP under 2500 ms 2500 to 4000 ms 4000 ms and up
INP under 200 ms 200 to 500 ms 500 ms and up
CLS under 0.1 0.1 to 0.25 0.25 and up
FCP under 1800 ms 1800 to 3000 ms 3000 ms and up
TTFB under 800 ms 800 to 1800 ms 1800 ms and up

Errors and rate limits

Status When
200 success
401 the key is missing or doesn’t match the account
429 more than 100 requests in one minute for this website

The rate limit counts requests per website, by customerId and applicationId, and resets every minute. A 429 has an empty body. Wait for the next minute and try again. For a large export, raise size so you need fewer requests.

A valid key with a website ID that has no data returns 200, with pageLoads of 0 and every metric at -1. If every number is empty, check your IDs before you decide the website had no traffic.

Examples

The last week for the whole website

curl "https://app.requestmetrics.com/api/v1/{customerId}/{applicationId}/performance?p=7d&key={apiKey}"

The slowest pages on mobile

Request performance by URL for 30 days with the mobile filter. Then sort the array by lcp or loadP75, skipping any -1 values.

curl "https://app.requestmetrics.com/api/v1/{customerId}/{applicationId}/performance/pages?p=30d&device_filter=mobile&key={apiKey}"

Mobile against desktop

Make the same request twice, once with device_filter=mobile and once with device_filter=desktop, and compare the results.

Every URL for the last 30 days

This JavaScript reads every page of results. It keeps the API key in an environment variable so the key stays out of your source code.

const customerId = "abcdefg";
const applicationId = "1234567";
const key = process.env.RM_API_KEY;

async function getAllPages() {
  const rows = [];
  let page = 1;
  let totalItems = 1;

  while (rows.length < totalItems) {
    const params = new URLSearchParams({ p: "30d", page, size: 100, key });
    const url = `https://app.requestmetrics.com/api/v1/${customerId}/${applicationId}/performance/pages?${params}`;
    const response = await fetch(url);
    if (!response.ok) {
      throw new Error(`Request Metrics returned ${response.status}`);
    }

    const body = await response.json();
    totalItems = body.metadata.totalItems;
    if (body.data.length === 0) break;
    rows.push(...body.data);
    page++;
  }

  return rows;
}

Ask Claude instead

The Request Metrics Claude Skill teaches Claude to make these requests for you. Ask a question in plain language, and Claude pulls the numbers, pages through long lists of URLs, and rates the results.

What the API doesn’t include

The API covers real user performance for your websites. Analytics, errors, API monitoring, sessions, funnels, Lighthouse results, and Chrome UX Report data are only in the Request Metrics app. If you need more in the API, tell us at hello@requestmetrics.com.

Found a mistake? Let us know!