Free browser signals API
Six static JSON files documenting every signal a website can read from a browser: the exact call, whether it prompts, whether it can be faked, how much it narrows a crowd and where that claim comes from. No key, no rate limit, no sign up, and nothing about the caller is recorded. Version 2.0.0, updated 2026-08-05, published under CC BY 4.0.
Endpoints
Every endpoint is a plain static JSON file with permissive CORS. Fetch it, cache it, ship it. Because the data is served statically, it is fast and there is nothing to throttle.
| Endpoint | What it returns |
|---|---|
| /api/signals.json | All 32 signals: detection API, what happens when a browser withholds it, whether it prompts, whether it can be faked, an entropy estimate with its basis, per-browser behaviour, primary sources and a review date. This is the one worth building on. |
| /api/entropy.json | The 11 row entropy model behind the fingerprint test, with the reasoning per row, the cap, the reason for the cap and an explicit disclaimer field. |
| /api/categories.json | The six categories with their signal counts and how many in each ask permission. |
| /api/capabilities.json | A flatter capability list keyed by API name, kept for anyone already building against version 1. |
| /api/user-agent-tokens.json | A reference of common user agent tokens and their meanings. |
| /api/index.json | Index of the API with version, licence, attribution string and the endpoint list. |
Example: which signals need no permission
fetch("https://readmybrowser.com/api/signals.json")
.then((r) => r.json())
.then(({ signals }) => {
// Which signals a site can read without ever asking you.
const silent = signals.filter((s) => !s.requiresPermission);
console.log(silent.length, "of", signals.length, "need no permission");
});Example response (one signal)
{
"slug": "cpu-cores",
"label": "CPU cores",
"category": "Device",
"url": "https://readmybrowser.com/what-is-my/cpu-cores",
"detectionApi": "navigator.hardwareConcurrency",
"requiresPermission": false,
"entropyBitsEstimate": 1.8,
"spoofable": "Partly",
"sources": [
{
"label": "MDN: Navigator.hardwareConcurrency",
"url": "https://developer.mozilla.org/en-US/docs/Web/API/Navigator/hardwareConcurrency"
}
],
"lastReviewed": "2026-08-05"
}Example response (user agent tokens)
{
"version": "2.0.0",
"updated": "2026-08-05",
"count": 14,
"tokens": [
{ "token": "Chrome/120.0.0.0", "meaning": "Google Chrome, major version 120." },
{ "token": "Edg/120.0.0.0", "meaning": "Microsoft Edge, major version 120." }
]
}About the entropy figures
/api/entropy.json and the entropyBitsEstimate field are ReadMyBrowser's own illustrative estimates, not measured population statistics, and the payload says so in a disclaimer field so the caveat travels with the data wherever it goes. We collect nothing from visitors, so we have no population to measure against. The methodology pageshows every figure and the reasoning behind it. Please do not present these numbers as research findings; if you need measured ones, EFF's Cover Your Tracks and AmIUnique both publish them.
Licence and attribution
All six endpoints are published under CC BY 4.0. Use them commercially, modify them, redistribute them. The one condition is credit, and every payload carries the exact wording in its attribution field so there is no guesswork:
Data from ReadMyBrowser (https://readmybrowser.com), maintained by FusionStudios. Entropy figures are ReadMyBrowser's own estimates, not measured population statistics; see https://readmybrowser.com/methodology.
Every response also carries version and updated. Both are set by hand when the data actually changes, never stamped from a build clock, so a change in either means something really changed.
Using it in your own tool
Pair the signals list with the browser APIs it names and you have the skeleton of a detection dashboard, with the sources already attached. For parsing user agent strings in the browser, the user agent parser shows the same logic you can port to your own code. If you just want to display the values, the embeddable widget does it in one snippet.
Frequently asked questions
Is there a rate limit?
No. The endpoints are static files on a CDN, so fetch them as often as you need. Caching them on your side is still polite and fast.
Does the API see my visitors' data?
No. It only returns reference data. The actual detection happens in each visitor's browser, so no visitor information passes through these endpoints or through us.
Can I trust the entropy numbers?
They are ReadMyBrowser's own illustrative estimates, not measured population statistics, and every payload says so in a disclaimer field. ReadMyBrowsercollects nothing from visitors, so it has no population to measure against. For measured figures, use EFF's Cover Your Tracks or AmIUnique.