web.dev API: Check page speed
Tests a web page with Google PageSpeed Insights on mobile or desktop: performance, accessibility, best practices and SEO scores, lab timings, real-user Core Web Vitals when available, and the top suggested fixes.
Unofficial. Not affiliated with or endorsed by web.dev.
Inputs
Values from the run on Oct 31, 2026, shown under Output.
- Device optional
device Device type, such as mobile.
desktop
One of
mobile,desktop. Defaultmobile.- Page URL, required
page_url Address of the page to test, such as example.com.
example.org
Input as JSON
{ "device": "desktop", "page_url": "example.org"}Output
{ "device": "desktop", "seo_score": 80, "lab_results": { "speed_index_seconds": 0.206, "total_blocking_time_ms": 0, "first_contentful_paint_seconds": 0.206, "largest_contentful_paint_seconds": 0.206 }, "report_link": "https://pagespeed.web.dev/analysis/https-example-org/3qxczoum24?form_factor=desktop" , "tested_link": "https://example.org/" , "suggested_fixes": [ { "fix": "Use efficient cache lifetimes", "estimated_saving": "Est savings of 1 KiB" }, { "fix": "Forced reflow", "estimated_saving": null }, { "fix": "Network dependency tree", "estimated_saving": null } ], "performance_score": 100, "real_user_results": { "scope": "URL", "passed": true, "cumulative_layout_shift": 0, "interaction_to_next_paint_ms": 15, "largest_contentful_paint_seconds": 0.579 }, "accessibility_score": 96, "best_practices_score": 100}Code
curl https://api.fous.com/v1/runs \ -H "Authorization: Bearer $FOUS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"method":"pagespeed.web.dev/check_page_speed","input":{"device":"desktop","page_url":"example.org"}}' # Save as fous.py, then run: python3 fous.pyimport json, os, timefrom urllib.error import HTTPErrorfrom urllib.request import Request, urlopenAPI = "https://api.fous.com/v1/runs" KEY = os.environ["FOUS_API_KEY"]HEADERS = { "Authorization": f"Bearer {KEY}", "Content-Type": "application/json" ,}def call(url, body=None): data = json.dumps(body).encode() if body else None request = Request(url, data, HEADERS) try: with urlopen(request, timeout=120) as r: return r.status, json.load(r) except HTTPError as error: message = json.load(error)["error"]["message"] raise RuntimeError(message) from errorstatus, run = call(API, { "method": "pagespeed.web.dev/check_page_speed" , "input": { "device": "desktop", "page_url": "example.org" }})# 202: still going after 30 s. Ask again until it ends.while status == 202: time.sleep(2) status, run = call(f"{API}/{run['id']}")print(json.dumps(run["data"], indent=2))// Save as fous.mjs, then run: node fous.mjsconst api = "https://api.fous.com/v1/runs" ;const headers = { Authorization: `Bearer ${process.env.FOUS_API_KEY}`, "Content-Type": "application/json" ,};let response = await fetch(api, { method: "POST", headers, body: JSON.stringify({ "method": "pagespeed.web.dev/check_page_speed" , "input": { "device": "desktop", "page_url": "example.org" } }), signal: AbortSignal.timeout(120_000),});let run = await response.json();// 202: still going after 30 s. Ask again until it ends.while (response.status === 202) { await new Promise((done) => setTimeout(done, 2_000)); response = await fetch(`${api}/${run.id}`, { headers }); run = await response.json();}if (!response.ok) throw new Error(run.error.message);console.log(run.data);# Connect your agent to Fous once, over MCP (Streamable HTTP):# https://api.fous.com/mcp# Set FOUS_API_KEY first: create a key at https://app.fous.com/keys.# Claude Codeclaude mcp add \ --scope user \ --transport http fous https://api.fous.com/mcp \ --header "Authorization: Bearer ${FOUS_API_KEY:?Set FOUS_API_KEY to your Fous API key}"# Codexcodex mcp add fous \ --url https://api.fous.com/mcp \ --bearer-token-env-var FOUS_API_KEY# Cursor, VS Code, Windsurf, Cline and morenpx -y add-mcp https://api.fous.com/mcp -g -n fous \ --header "Authorization: Bearer ${FOUS_API_KEY:?Set FOUS_API_KEY to your Fous API key}"# Then ask your agent:# "Use Fous to run pagespeed.web.dev/check_page_speed# with {"device":"desktop","page_url":"example.org"}"Over HTTP, the answer’s data holds the output. A run still going after 30 seconds answers 202 with its id: ask GET /v1/runs/{id} until it ends.
Schema
Input schema
{ "type": "object", "required": [ "page_url" ], "properties": { "device": { "enum": [ "mobile", "desktop" ], "type": "string", "default": "mobile", "description": "Device type, such as mobile." }, "page_url": { "type": "string", "description": "Address of the page to test, such as example.com." } }}Output schema
{ "type": "object", "required": [ "tested_link", "device", "performance_score", "accessibility_score", "best_practices_score", "seo_score", "real_user_results", "lab_results", "suggested_fixes", "report_link" ], "properties": { "device": { "type": "string", "description": "Device type tested." }, "seo_score": { "type": [ "number", "null" ], "description": "SEO score out of 100." }, "lab_results": { "type": "object", "properties": { "speed_index_seconds": { "type": [ "number", "null" ], "description": "Lab speed index in seconds." }, "total_blocking_time_ms": { "type": [ "number", "null" ], "description": "Lab total blocking time in milliseconds." }, "first_contentful_paint_seconds": { "type": [ "number", "null" ], "description": "Lab first contentful paint in seconds." }, "largest_contentful_paint_seconds": { "type": [ "number", "null" ], "description": "Lab largest contentful paint in seconds." } }, "description": "Results measured by Lighthouse." }, "report_link": { "type": "string", "description": "Link to the full PageSpeed Insights report." }, "tested_link": { "type": "string", "description": "Final page address tested." }, "suggested_fixes": { "type": "array", "items": { "type": "object", "properties": { "fix": { "type": "string", "description": "Suggested improvement." }, "estimated_saving": { "type": [ "string", "null" ], "description": "Estimated saving shown by PageSpeed, if any." } } }, "description": "Up to five relevant suggested fixes." }, "performance_score": { "type": [ "number", "null" ], "description": "Performance score out of 100." }, "real_user_results": { "type": [ "object", "null" ], "properties": { "scope": { "type": "string", "description": "Whether data describes the URL or its origin." }, "passed": { "type": [ "boolean", "null" ], "description": "Whether Core Web Vitals passed." }, "cumulative_layout_shift": { "type": [ "number", "null" ], "description": "Real-user cumulative layout shift." }, "interaction_to_next_paint_ms": { "type": [ "number", "null" ], "description": "Real-user interaction to next paint in milliseconds." }, "largest_contentful_paint_seconds": { "type": [ "number", "null" ], "description": "Real-user largest contentful paint in seconds." } }, "description": "Real-user experience when available." }, "accessibility_score": { "type": [ "number", "null" ], "description": "Accessibility score out of 100." }, "best_practices_score": { "type": [ "number", "null" ], "description": "Best practices score out of 100." } }}- Price
- 1 credit per completed run (1¢ with pay as you go); failed runs are free.
- Method
pagespeed.web.dev/check_page_speed- Returns
- scores, lab results, real-user results, suggested fixes, tested link, report link
Use it from your agent
Give your agent this line. It reads SKILL.md, gets a Fous API key and connects the Fous MCP server. Its run then takes the method pagespeed.web.dev/check_page_speed with the inputs above.
Ask your agent
- Run a PageSpeed Insights test on https://www.etsy.com/c/jewelry for mobile and tell me the performance and accessibility scores
- How fast does bluebottlecoffee.com load on desktop? I want the LCP, CLS and the biggest fixes to make it quicker
- Use web.dev to check the Core Web Vitals for my portfolio site janedoe.design on a phone
- Can you audit nytimes.com/section/technology on web.dev for desktop and give me the SEO and best practices scores plus a link to the full report?
- Our landing page at shop.greenleafgardens.co.uk feels sluggish on mobile — test it and list the top suggested improvements along with real-user data if there is any
See more
Checks a website's HTTPS setup with SSL Labs: overall grade, per-server grades, certificate issuer and expiry, supported protocols and known weaknesses. Reuses cached reports from the last 72 hours unless a fresh test is requested.
ssllabs.com/check_ssl_certificateGets the Walk, Transit and Bike Scores and neighborhood details for a street address. Unpublished scores are null; unresolved or mismatched addresses are not found.
walkscore.com/get_walk_scoreFind the closest web feature by name and see its global support and support across eight major desktop and mobile browsers. Current browser support follows the versions labeled current by Can I use.
caniuse.com/check_browser_supportGets a website's monthly traffic estimate, rankings, engagement and top countries from Similarweb's free public overview. Traffic-source percentages withheld by the site are null; the site may limit anonymous views.
similarweb.com/get_website_trafficSearches the web privately with DuckDuckGo in a chosen region and returns the ordered organic results without ads, plus DuckDuckGo's instant answer when it shows one.
duckduckgo.com/search_webGets the technologies shown in a website's free BuiltWith profile, grouped in the order BuiltWith displays them. A company name is matched to its official website through a public web search.
builtwith.com/get_website_technologiesFinds Chrome Web Store extensions by keywords in store order, with each listing's developer, users, rating, rating count, short description and store link. Some listings omit developer, users or ratings.
chromewebstore.google.com/search_extensionsSearches public Wall Street Journal headlines and summaries by keyword, newest or most relevant first, optionally within publication dates; podcasts and live-coverage posts are left out.
wsj.com/search_news