Browser fingerprint API for developers: Examples
What is a browser fingerprint API for developers? It reads canvas, WebGL and audio signals in a real browser and returns a visitor ID. Get the code and limits.
- browser fingerprinting
- fingerprint api
- playwright
- cdp
- gdpr
On this page
- Which browser fingerprint API for developers do you need?
- Which browser signals does a fingerprint API collect, and where?
- The request contract of a browser fingerprint API for developers
- How does a browser fingerprint API see a Playwright session?
- What can browser fingerprint signals not tell you?
- Is browser fingerprinting legal under GDPR and ePrivacy?
- Frequently asked questions
- What is a browser fingerprint API?
- Can a fingerprint API identify me in private mode?
- Can I get a browser fingerprint from a plain HTTP request?
- Does Wayfern let me edit individual fingerprint values?
- Next steps with a browser fingerprint API for developers
- Sources
A browser fingerprint API for developers works in two directions: an identification API reads signals in the page and returns a visitor ID to the site’s backend, while a hosted browser sets what those signals say when you automate. The result is probabilistic. Consistency across cookies, storage, exit IP and viewport counts as much as any single signal.
Your Playwright script gets a challenge page even though the site renders normally. Or your signup flow needs a visitor ID, and the docs show only one half of the integration. Both problems put you on one side of the same signals: the site that reads fingerprints, or the developer whose browser gets read.
This browser fingerprint API for developers guide shows the request and response contract and the Web API behind each signal. It also covers a CDP connection, the limits and the legal texts that apply.
Key Takeaways
- Canvas, WebGL, audio and screen values need a real browser, and the server adds network data from the request.
- On Wayfern,
widthandheighton the /ws URL resize the real window, with no emulation, per Wayfern’s API reference.- An unknown exit location is refused with close code 4007, not replaced by a fallback.
- Wayfern has no named profiles or per-vector switches; for those, see profile managers like Multilogin.
Which browser fingerprint API for developers do you need?
A browser fingerprint API for developers is a service that reads browser and device attributes, turns them into a visitor identifier and exposes it to your backend over HTTP. Identification APIs read fingerprints for site owners, and hosted browsers apply one browser identity to your automation.
The two kinds of browser fingerprint API for developers sit on opposite sides of the same signals. Pick the identification API if you run the site; pick the hosted browser if your code drives the browser being read.
The open-source half is easy to check yourself. The FingerprintJS README describes “an open-source, client-side, browser fingerprinting library that queries browser attributes and computes a hashed visitor identifier from them.”
Open its demo page, note your visitor identifier, then load the same page in a private window. The README says the identifier stays the same.
A Playwright or Puppeteer session is read the same way, from real browser values plus the network data of its request.
Three different tools get called a “fingerprint API” or “anti-detect”:
| Identification API | Desktop profile manager | Hosted programmable browser | |
|---|---|---|---|
| Example | FingerprintJS, Fingerprint | Multilogin | Wayfern |
| Operator | The site’s backend | A person | Your code, over CDP |
| What it does | Reads signals, returns a visitor ID | Per-vector control over many long-lived profiles | Applies one identity inside the browser build |
| Named persistent profiles | Not applicable | Yes | No |
| Engines | Runs in the visitor’s browser | Varies by product | Chromium family only |
On Wayfern, the hosted browser runs headed on a virtual display in Wayfern containers, and nothing is injected into your pages. Save and restore cookies in your own code between runs.
No named profiles, no cookie import or export, no per-vector fingerprint switches.” If a person hand-manages many long-lived profiles, Multilogin is the better fit.
Which browser signals does a fingerprint API collect, and where?
A browser fingerprint API collects signals in two places: in the page, where JavaScript calls browser APIs, and on the server, which sees the network request itself.
The page produces four groups of values:
- Canvas: a script draws text and shapes, then reads the pixels back with
HTMLCanvasElement.toDataURL()orCanvasRenderingContext2D.getImageData(). Fonts, drivers and the graphics stack change the rendered pixels, so two machines can return different data. - WebGL:
WebGLRenderingContext.getParameter(), together with theWEBGL_debug_renderer_infoextension, returns the GPU vendor and renderer strings. - Audio: the Web Audio API renders a short signal through
AudioContextorOfflineAudioContext, and the processed samples become the value. - Screen and hardware:
screendimensions,navigator.hardwareConcurrency(logical CPU cores) andnavigator.webdriver(whether automation controls the browser).
BrowserCheak’s API page puts the limit plainly: “Canvas, WebGL and screen signals must be collected in an actual browser. An HTTP request alone cannot reveal a visitor’s complete fingerprint to the server.”
Each value is the output of code running on a real display, GPU or audio stack. A client like curl or Python requests runs no such code, so it has nothing to report.
The server adds the IP address and the request headers of every call. IPCheckHQ’s developer page describes binding “browser observations to the network request that collected them”, which lets a backend compare what the page claimed with what the connection shows.
Libraries such as FingerprintJS hash the attributes into one identifier. IPCheckHQ’s response goes further and returns “component hashes for canvas, WebGL, audio and other signals”, so each signal can be inspected separately.
For your automation, the target reads values from the browser you drive and the exit IP it connects through. A Playwright session in a real browser produces genuine canvas, WebGL and audio output. Those values also have to agree with the exit IP, the viewport and the storage across every page of the flow.
The request contract of a browser fingerprint API for developers
A browser fingerprint API contract has two halves: the page calls the vendor’s agent and receives an event ID, then your backend trades that ID for the full event using a secret key. Fingerprint’s agent covers the page half and its Server API covers the backend half.
- Collect in the page. Install the agent, start it with your public key and call
get(). Send only the returned event ID to your backend.
import * as Fingerprint from '@fingerprint/agent';
const fp = Fingerprint.start({ apiKey: 'PUBLIC_API_KEY' });
const { event_id } = await fp.get();
await fetch('/api/signup', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ event_id }),
}); Authenticate on the server. Fingerprint’s Server API docs say that API is “designed for use only from server-side environments”, “never directly from client-facing surfaces such as browsers or mobile devices.” Read the secret key and the regional base URL from environment variables, and never inline them.
Retrieve the event. Send
GET /v4/events/{event_id}with anAuthorization: Bearerheader. The JSON that comes back holds the event, including the Smart Signals results your plan returns.Handle failures. Retry only 429 and 503, with exponential backoff and a hard cap. Treat any other 4xx or 5xx as a failed lookup.
const BASE = process.env.FPJS_API_BASE;
const KEY = process.env.FPJS_SECRET_KEY;
async function getEvent(eventId, attempt = 0) {
const res = await fetch(`${BASE}/v4/events/${encodeURIComponent(eventId)}`, {
headers: { Authorization: `Bearer ${KEY}` },
});
if (res.ok) return res.json();
if ((res.status === 429 || res.status === 503) && attempt < 4) {
await new Promise((r) => setTimeout(r, 2 ** attempt * 500));
return getEvent(eventId, attempt + 1);
}
throw new Error(`event lookup failed: ${res.status}`);
} When your signup route gets a 429, the function waits 500 ms and retries, then 1 s, then 2 s, doubling until the attempt cap. If the event still can’t be fetched, or comes back as a 404, mark the check as failed and send the signup to review. A missing event must never count as a pass.
Trust the event ID, not a visitor ID the browser reports. A client can send any string, but only an ID your backend resolves through the authenticated call is evidence.
Two dates matter if you adopt this browser fingerprint API for developers. Fingerprint’s reference states: “Server API v3 is deprecated as of October 31, 2026, and stops working on October 31, 2027 .” Build against v4 now.
The same reference says “Server API requests are not billed and do not count towards your monthly allowance,” so retrieval calls don’t use up your quota.
How does a browser fingerprint API see a Playwright session?
A browser fingerprint API sees a Playwright session as one bundle of in-page values plus the network data from the request, and it checks whether that bundle stays the same from page to page. The fingerprint is one signal among several.
If the cookie jar, local storage, exit IP or viewport shifts between page one and page four, the mismatch is itself evidence. On a hosted browser, a fixed exit, a fixed window size and one reused context keep those pieces aligned.
- Keep the link token on your server. Read it from an environment variable such as
LINK_TOKEN, and never ship it to client code. - Pick the exit once per flow. Set
country(ISO-3166), then narrow withregion,cityorisp. Add a stickysessionid and reuse it for every step, because a cookie issued to one IP and replayed from another is, in Wayfern’s anti-detect session guide, “an easy signal for a site to read.” - Set the window on the URL.
widthandheightare whole CSS pixels. Don’t resize with a script afterward, since the real window is already the size you asked for. - Wrap the connect in try/catch. Opening the socket starts the session, so a refused connection is the only failure signal you get.
- Reuse the first context. Call
browser.contexts()[0].newPage()for every page in the flow, so cookies and storage stay live while the socket is open. Save and restore state in your own code between runs, as in our guide to authenticated scraping.
import { chromium } from "playwright";
const url =
"wss://api.wayfern.com/ws?token=" + process.env.LINK_TOKEN +
"&country=US®ion=CA&session=run42&width=1366&height=768";
let browser;
try {
browser = await chromium.connectOverCDP(url);
} catch (err) {
console.error("connect failed:", err.message);
process.exit(1);
}
const page = await browser.contexts()[0].newPage();
await page.goto("https://example.com/login"); Wayfern’s API reference describes the viewport behavior this way: “The real browser window is resized, nothing is emulated and no script runs in your pages, so layout, media queries, outerWidth/outerHeight and screen.* stay consistent.” Phone sizes aren’t offered, and the browser presents a desktop device.
The code above asks for a residential exit in California. If you change region to a code that isn’t in the location catalog, the connection is refused with close code 4007.
Wayfern says an unknown location is refused “instead of falling back to the wrong place,” so your catch block runs and the script never browses from the wrong country.
To try it, mint a link token and run the snippet against one page you’re allowed to test.
What can browser fingerprint signals not tell you?
A browser fingerprint signal tells you that a browser probably matches one seen before, and it says nothing about who is using it or why. Each side of the API has its own limits.
For a site that reads fingerprints, a high-confidence match describes a browser. A shared office PC, a family laptop and a QA test machine can return the same identifier, and a real customer can return a new one after an update. Intent needs other evidence, such as account history and behavior.
Client-side values can be altered. IPCheckHQ’s developer page says “A client-side fingerprint alone is easy to copy into a request and difficult to interpret.” Verify each event on your backend with your secret key before you act on it.
Cross-checks are evidence to weigh. A user agent that says Windows while navigator.platform says Linux, or a GPU string that doesn’t fit the claimed OS, raises a question.
A virtual machine, a browser update or a privacy extension can produce the same mismatch, so combine it with other signals before you decide anything. IPCheckHQ’s response includes confidence and randomized-signal fields that “help you distinguish stable observations from values a privacy browser is deliberately changing.”
For a developer whose browser is being read, clearing data is a weak lever. The FingerprintJS README says “Unlike cookies and local storage, a fingerprint stays the same in incognito/private mode and even when browser data is purged.”
Private mode or cleared cookies may change nothing useful, and they give no guarantee of a different identifier. The result depends on the whole bundle: in-page values, storage, exit IP and window size across every page of your flow.
Test your own targets against any browser fingerprint API for developers instead of trusting a published rate. Run your session through the exact flow you care about, and compare what page one and page four see. Our guide to anti-detect browser sessions over CDP covers the controls that keep those values consistent.
Is browser fingerprinting legal under GDPR and ePrivacy?
Browser fingerprinting can fall under both the GDPR and the ePrivacy Directive, and which rules apply depends on what a site reads, why it reads it, and where the user is. National rules differ, and counsel in your jurisdiction decides how the texts apply to a given system.
The ePrivacy rule comes first. Article 5(3) of Directive 2002/58/EC says “the storing of information, or the gaining of access to information already stored, in the terminal equipment of a subscriber or user is only allowed on condition that the subscriber or user concerned has given his or her consent”.
The rule covers access as well as storage, so its reach goes beyond cookies. The same article exempts access “strictly necessary in order to provide an information society service explicitly requested by the subscriber or user”.
The EDPB’s Guidelines 2/2023 on the technical scope of Article 5(3) are the regulator text to read for how fingerprinting-type access is treated.
The GDPR applies on top. Article 4(1) of the GDPR defines personal data as “any information relating to an identified or identifiable natural person”. A visitor ID that a site links to an account or session can meet that definition. Article 6(1) lists the lawful bases for processing.
Two principles in Article 5(1) shape the engineering. Data must be “adequate, relevant and limited to what is necessary in relation to the purposes for which they are processed”, and kept identifiable “for no longer than is necessary”.
For a team that reads fingerprints, those principles map to three engineering artifacts: a stated purpose, a signal list limited to that purpose, and a deletion schedule.
Fraud prevention, security, testing, research and monitoring are purposes that are easier to document than open-ended profiling. If you automate a browser, you are the one being read, and your own obligations follow from what you collect and where.
Frequently asked questions
What is a browser fingerprint API?
A browser fingerprint API collects browser and device signals in the page, such as canvas, WebGL, audio and screen values, sends them to a server, and returns a stable identifier with risk signals. The identifier is a probabilistic match, not proof of identity or intent, and client-side values can be spoofed.
Can a fingerprint API identify me in private mode?
It can, because private mode does not guarantee a new identifier. The FingerprintJS README says a fingerprint “stays the same in incognito/private mode and even when browser data is purged.” Which signals a vendor reads decides whether your ID changes.
Can I get a browser fingerprint from a plain HTTP request?
You can’t get a complete one. An HTTP request exposes only network-level data and headers, while canvas, WebGL, audio and screen values need a real browser running JavaScript.
Does Wayfern let me edit individual fingerprint values?
Wayfern has no per-vector fingerprint switches. For hand-set values, a desktop profile manager such as Multilogin fits better.
Next steps with a browser fingerprint API for developers
Start by deciding which side you’re on: the site that reads fingerprints, or the developer whose browser is read. If code drives your browser and you’re choosing a product, Wayfern’s anti-detect browser comparison sets profile managers against hosted browsers.
If you read fingerprints, build the collect-then-verify flow this week: collect in the page, then fetch the event from your backend with a secret key. If your browser is read, run your own targets through a hosted session and note where each one fails.
After that, keep the cookie jar, exit and viewport consistent across every flow, since a change by page four can undo a clean result on page one.
Start a Wayfern session against your own targets, then check credit rates on the pricing page to size your usage. Results vary by site, so measure before you commit.
Sources
GitHub - fingerprintjs/fingerprintjs: The most advanced… · Browser Fingerprint API for Developers | IP Checker · Browser Fingerprint API & Developer Tools | BrowserCheak · API Reference - CDP, Web Data & Search | Wayfern · Best Anti-Detect Browsers for Automation, Compared · Server API - Fingerprint Docs · Anti-detect browser sessions over CDP · Regulation (EU) 2016/679 (GDPR). Every other source is linked where the article cites it.
See us more often in Google
One click marks Wayfern as a preferred source in Google, so our posts can show up more often in your Top Stories, AI Mode and AI Overviews.