---
title: "What Is a User Agent? How to Check and Change It"
description: "A user agent is the identity line your browser sends with every request. How to read it, change it in Chrome and on Android, and what Client Hints changed."
url: https://proxynet.io/blog/what-is-user-agent
date: 2026-09-19
author: "Acar Diveroli"
category: "Proxies, Tutorial"
lang: en
---

# What Is a User Agent? How to Check and Change It

When you open the download page of a program, the site suggests the right file for your operating system on its own. Some sites send a separate mobile page to visitors on a phone. The site does this without asking you, because your browser sends a one-line text that introduces itself with every request. That line is called the User-Agent.

The first half of this article is for everyone: how to read a User-Agent string piece by piece, how to see your own, and how to change it in Chrome, on Windows 11 and on Android. The second half is more technical: Chrome's User-Agent reduction, the Client Hints headers that replaced the lost detail, what changing the User-Agent does not change, and how a script you wrote yourself should identify itself.

> **Note: Short answer**
>
> The User-Agent is the identity line a browser or program sends with every HTTP request, stating its name, version and operating system. You can see your own value by typing `navigator.userAgent` into the browser console. In Chrome you change it under DevTools > More tools > Network conditions, and on Android with the "Desktop site" option. The line does not carry your IP address or location, and changing it does not change the rest of the traces your browser leaves.

## What is a User-Agent?

When your browser requests a page, it does not send only the address. On top of the request go short lines of information called headers: which languages you prefer, which file types you accept, and which software is sending the request. The last one is the `User-Agent` header.

The HTTP standard [RFC 9110 defines this header](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent) as the field that carries information about the software originating the request. Servers use it for three jobs: working out which browser an interoperability problem appears in, tailoring the response to the client's limitations, and keeping statistics on browser and operating system use. The standard recommends that a client send this header with every request.

The phrase "user agent" is actually the name of the software, not of the header: any program that sends requests on your behalf is a user agent. A browser, a search engine bot, a phone app, the `curl` command and a Python script all fit the definition, and each of them has a User-Agent value.

Two common mistakes are worth correcting at the start. The User-Agent **does not contain your IP address or your location.** The IP address is read from the connection itself; we explain how that changes in [our guide to changing your IP address](/blog/how-to-change-ip-address). The User-Agent is not **authentication** either: it is the client's own statement, and a server cannot test whether that statement is true by looking at the header.

## How do you read a User-Agent string?

A current Chrome on Windows sends this value (the example is from [MDN's User-Agent page](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/User-Agent)):

```text
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36
```

Next to Chrome, the line also names Mozilla, AppleWebKit, Gecko and Safari. The reason is historical. For years sites wrote rules such as "if the User-Agent contains this name, send the advanced page". Every new browser added the older names to its own line so that it would not miss out on that page. In MDN's words, `Mozilla/5.0` is a general token saying the browser is Mozilla-compatible, and for historical reasons almost every browser sends it today.

| Part | What does it say? |
|---|---|
| `Mozilla/5.0` | A compatibility leftover; it does not tell browsers apart |
| `(Windows NT 10.0; Win64; x64)` | Operating system and processor architecture |
| `AppleWebKit/537.36 (KHTML, like Gecko)` | Engine names, again added for compatibility |
| `Chrome/143.0.0.0` | The actual browser and its major version |
| `Safari/537.36` | A name added for sites written with Safari in mind |

The practical reading rule is this: the operating system sits inside the first parentheses, and the real name of the browser is usually close to the end of the line. Edge appends `Edg/` to the end, Firefox ends with `Firefox/`. On phones the word `Mobile` enters the line; sites that pick a mobile page based on the User-Agent look for that word.

One more detail: even if you run Windows 11, the parentheses say `Windows NT 10.0`. Microsoft states plainly [in its own documentation](https://learn.microsoft.com/en-us/microsoft-edge/web-platform/how-to-detect-win11) that User-Agent strings will not be updated to tell Windows 10 and 11 apart. You will see why in the User-Agent reduction section below.

## How do you find your own User-Agent?

You do not need to install anything. The browser's own tools are enough:

1. On any page in Chrome or Edge, press `F12` (or use the three dots at the top right > More tools > Developer tools).
2. In the panel that opens, switch to the **Console** tab.
3. Type `navigator.userAgent` and press Enter. The line returned in quotes is the User-Agent your browser reports to JavaScript.
4. To see what really goes to the server, switch to the **Network** tab, reload the page, click the first request in the list and find the `User-Agent` line under "Request Headers".

Steps three and four are expected to show the same value. If they differ, an extension or a setting is changing only one of the two.

If you would rather not use the console, a page that simply writes back the request headers it received does the job too. Open `https://httpbin.org/headers` in your browser and you will see every header the server received from you; we use the same address in the code section of this article.

## How do you change the User-Agent?

First, know what you are changing: the User-Agent is a setting of **each browser**, not of the operating system. Neither Windows 11 nor Android has a single User-Agent setting that applies to all programs.

### Chrome and Edge (Windows 11, Windows 10, macOS)

Chrome's official route is [the Network conditions tab in DevTools](https://developer.chrome.com/docs/devtools/device-mode/override-user-agent). Edge is built on Chromium as well, so it carries the same tools.

1. Open DevTools with `F12`.
2. Follow the three dots at the top right of the panel > **More tools** > **Network conditions**. If you cannot find it in the menu, open the Command menu with `Ctrl+Shift+P` and type "Network conditions".
3. Under the **User agent** heading, clear the "Use browser default" checkbox.
4. Pick a ready-made browser and device from the list, or choose "Custom..." and type your own string.
5. Reload the page.

The "User agent client hints" area in the same section lets you edit the Client Hints values described further down. This change is not a permanent browser setting; it applies for the duration of the test, in the tab where DevTools is open.

### Android phone

Android has no built-in way to type a User-Agent by hand, but the change people want most often is a single tap. In Chrome, tap the three dots at the top right and tick the **Desktop site** box; Chrome then visits that site with a desktop identity and the wide layout arrives. To make this the default for every site, [the path in Chrome Help](https://support.google.com/chrome/answer/13514529?hl=en&co=GENIE.Platform%3DAndroid) is: Settings > Site settings > Desktop site.

### What is a User-Agent switcher?

Extensions listed in browser stores as "User-Agent switcher" do the same job without opening DevTools, and permanently: you pick an identity from a list and the extension replaces the `User-Agent` header of outgoing requests with it. Look at the permission it asks for before you install one. To be able to rewrite headers, the extension needs access to your traffic on every site you visit; give that permission only to an extension whose source you trust, and turn it off when you are done.

### Why would you change the User-Agent?

Every legitimate reason is some kind of test:

- **Trying the mobile view from a computer.** Seeing which page your own site sends to a phone.
- **Debugging a compatibility problem.** Finding out whether an old corporate page that says "your browser is not supported" really fails to work.
- **Seeing what your own site shows to bots.** Catching a configuration error that returns different content to search engine bots.
- **Reproducing a bug.** Examining a problem that appears only in one browser when you do not have that browser at hand.

RFC 9110 anticipates this case too: if a client presents itself as a different client, the server may assume the user wants to see the response prepared for that client, even if the response does not work well in the real browser. The responsibility lies with whoever made the change.

## What is User-Agent reduction?

Older User-Agent strings were far more talkative than today's: the browser's full four-part version, the patch level of the operating system, and on Android the model of the phone. Put together, these details were a ready-made piece of the [browser fingerprint](/blog/browser-fingerprinting) used to recognise a user without cookies. RFC 9110 gives the same warning: overly detailed User-Agent values increase the risk of a user being identified against their wishes.

That is why Chrome simplified the string in stages. According to [the Chromium project's timeline](https://www.chromium.org/updates/ua-reduction/), minor version numbers were frozen in Chrome 101, desktop operating system information in Chrome 107, and the Android version and device model in Chrome 110. In the string Chrome sends today, these parts are not real but fixed:

| Part | Without reduction (example) | Today |
|---|---|---|
| Browser version | `Chrome/143.0.12.45` | `Chrome/143.0.0.0` (only the major version is real) |
| Windows | Real version | Always `Windows NT 10.0; Win64; x64` |
| macOS | Real version | Always `Intel Mac OS X 10_15_7` |
| Android | `Android 16; Pixel 9` | Always `Android 10; K` |

This is why you see `NT 10.0` on Windows 11, and "Android 10" with a model called "K" on a brand-new phone. The conclusion is clear as well: a statistics tool that tries to read the operating system version or the phone model from a current Chrome User-Agent produces wrong results.

## What are Client Hints?

Some sites really need the information that disappeared with the reduction: those that want to suggest the correct installer, or to know which version a bug appears in. Chrome did not delete this information, it made it **opt-in**. The mechanism is called User-Agent Client Hints, and as [MDN's Client Hints guide](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Client_hints) describes, it works like this:

1. With the first request, alongside the reduced `User-Agent`, the browser sends three short headers: `Sec-CH-UA` (browser brand and major version), `Sec-CH-UA-Mobile` (mobile or not) and `Sec-CH-UA-Platform` (operating system name).
2. A server that wants more lists the hints it would like in the `Accept-CH` header of its response.
3. The browser adds the hints it allows to subsequent requests to that site.
4. If a hint is essential on the very first request, the server uses the `Critical-CH` header; the browser re-sends the request with that hint included.

The three default headers look like this in a Chrome request:

```text
Sec-CH-UA: "Google Chrome";v="143", "Chromium";v="143", "Not A(Brand";v="24"
Sec-CH-UA-Mobile: ?0
Sec-CH-UA-Platform: "Windows"
```

"Not A(Brand" in the list is not an error. According to MDN, browsers deliberately add a fake brand to the list; the aim is to stop servers from getting into the habit of rejecting a request when they see a name they do not recognise. It is a precaution against a repeat of the `Mozilla/5.0` story.

| Hint type | Headers | When is it sent? |
|---|---|---|
| Low entropy | `Sec-CH-UA`, `Sec-CH-UA-Mobile`, `Sec-CH-UA-Platform` | With every request, by default (HTTPS only) |
| High entropy | `Sec-CH-UA-Platform-Version`, `Sec-CH-UA-Full-Version-List`, `Sec-CH-UA-Model`, `Sec-CH-UA-Arch` | Only if the server asks with `Accept-CH` |

The same information is available to JavaScript through `navigator.userAgentData`. Paste the lines below into the Chrome console to see your own values:

```js
console.log(navigator.userAgent);

if (navigator.userAgentData) {
  const details = await navigator.userAgentData.getHighEntropyValues([
    "platformVersion",
    "model",
    "fullVersionList",
  ]);
  console.log(details);
}
```

On Windows 11 this code returns a major version of 13 or higher for `platformVersion`; this is the method Microsoft's documentation shows for telling Windows 10 and 11 apart. On the Windows 11 machine we tried, the `User-Agent` still said `Windows NT 10.0` while `platformVersion` came back as `19.0.0`.

Know the limit too. Client Hints exist today only in Chromium-based browsers (Chrome, Edge, Opera). In MDN's compatibility data, Firefox and Safari do not send these headers, and the `navigator.userAgentData` object is undefined in them. That is why the `if` check in the code above is needed.

## What does changing the User-Agent not change?

The User-Agent is a label, and changing the label does not change what is in the box. When you set the line to "Safari on iPhone", the following stay where they are:

- **Client Hints headers.** If you used a tool that changes only the `User-Agent` header, Chrome keeps sending `Sec-CH-UA-Platform: "Windows"`. Safari does not send these headers at all, so your request both claims to be Safari and carries headers that only Chromium sends.
- **What JavaScript sees.** Screen size, installed fonts, graphics card, touch screen support. We list these signals in [What Is Browser Fingerprinting?](/blog/browser-fingerprinting).
- **The connection itself.** The first packet a browser sends while setting up an encrypted connection has a different layout in each browser family, and it travels before the headers. The details are in [our article on TLS fingerprinting and JA3](/blog/tls-fingerprinting).
- **The IP address.** The request still leaves through your connection, with your IP address.

So changing the User-Agent is a testing tool, not an invisibility tool. Bot protection systems do not look at a single header but at whether the signals are consistent with one another; we describe the whole picture from the site owner's side in [our article on how bot detection works](/blog/how-bot-detection-works). Software that takes on the job of building one consistent identity set per profile is a separate category: [What Is an Antidetect Browser and How Does It Work?](/blog/what-is-antidetect-browser).

## User-Agent in code: defaults and an honest bot identity

Every client outside the browser has a User-Agent too, and unless you set it, it is the library's own name. We measured the values below on our own machine for this article; the version number will differ on yours:

| Client | Default User-Agent |
|---|---|
| `curl` | `curl/8.21.0` |
| Python Requests | `python-requests/2.34.2` |
| Node.js (built-in `fetch`) | `node` |

These values are not wrong, they are honest. What they lack is this: they do not tell the site administrator **who you are and how to reach you.** An administrator who sees thousands of `python-requests` lines in the logs has only one option, which is to block them.

For a data collection script that runs regularly, the established good practice is to write an identity that follows RFC 9110's "product/version (comment)" form and carries the bot's name and a way to get in touch. Search engine bots do the same; Googlebot's value has the form `Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)`. With `curl` it is a single line:

```bash
# See the default identity
curl -s https://httpbin.org/headers

# Write your own identity with -A
curl -s -A "ExamplePriceBot/1.0 (+https://example.com/bot-info)" https://httpbin.org/headers
```

In Python, set the identity on the session, not on individual requests. That way every request goes out with the same identity and the proxy setting lives in one place too:

```python
import requests

URL = "https://httpbin.org/headers"
BOT_UA = "ExamplePriceBot/1.0 (+https://example.com/bot-info; bot@example.com)"

# 1) With nothing set: the library's own identity
print(requests.get(URL, timeout=20).json()["headers"]["User-Agent"])

# 2) A fixed, self-identifying identity and a proxy for the whole session
session = requests.Session()
session.headers["User-Agent"] = BOT_UA
proxy = "http://user:pass@pr.proxynet.io:8000"
session.proxies = {"http": proxy, "https": proxy}

for _ in range(3):
    print(session.get(URL, timeout=20).json()["headers"]["User-Agent"])
```

The first line prints `python-requests/2.x`, the next three print the identity you wrote. In Node.js the same job is done with the `headers` field of the `fetch` call:

```js
const url = "https://httpbin.org/headers";

// 1) Default identity
let res = await fetch(url);
console.log((await res.json()).headers["User-Agent"]);

// 2) The identity you wrote yourself
res = await fetch(url, {
  headers: { "User-Agent": "ExamplePriceBot/1.0 (+https://example.com/bot-info; bot@example.com)" },
});
console.log((await res.json()).headers["User-Agent"]);
```

Save the file with the `.mjs` extension; the first line of the output will be `node`. Defining a proxy in Node.js is a separate topic, and [Using a Proxy in Node.js](/blog/nodejs-proxy) has tested examples. All the proxy flags on the `curl` side are in [How to Use cURL with Proxy?](/blog/curl-proxy).

### Why does a random User-Agent on every request not work?

Most scraping guides on the internet suggest downloading a "current User-Agent list" and picking a random entry for every request. You saw the mechanism in the previous section: only the label changes. When the same IP address, the same cookie and the same connection trace claim to be Chrome on Windows in one request and Safari on iPhone in the next, the result is traffic that resembles no real user. A single, fixed, self-identifying identity is consistent and also gives the site administrator someone to talk to. We cover consistency examples in the "Headers and a consistent client identity" section of [How to Scrape Websites Without Getting Blocked](/blog/web-scraping-without-getting-blocked).

### Why is posing as Googlebot a bad idea?

Some guides suggest writing Googlebot's value into the User-Agent. Do not, for two reasons. First, it does not work: Google advises sites to [verify its bot with a reverse DNS lookup or against the IP ranges it publishes](https://developers.google.com/crawling/docs/crawlers-fetchers/verify-google-requests). An IP address that claims to be Googlebot but does not resolve under `googlebot.com`, `google.com` or `googleusercontent.com` in a reverse DNS lookup gets blocked faster than an ordinary bot. Second, using another organisation's identity steps outside the permission the site has given you. The only legitimate use is the test mentioned above: seeing what **your own** site returns to this identity.

An honest bot name has one more benefit. The `User-agent:` line in a robots.txt file uses the same word but is a separate thing: it is the line where the site owner states which bot a rule is written for. If your bot's name is known, the site owner can write a rule specifically for you, and you follow that rule. How the file is read is covered in [What Is a robots.txt File and How Do You Read It?](/blog/robots-txt).

## Proxy and User-Agent: the proxy changes the IP, you change the identity

Proxies and the User-Agent are often confused, because both are part of the question "how does the site see me". The division of labour is clear: a proxy changes which IP address and which country the request leaves from. It does not touch the User-Agent. On an HTTPS connection it cannot: the proxy only sets up the encrypted tunnel and cannot see the headers inside it. In the Python example above, the User-Agent the site sees is the same with and without the proxy.

The rule that follows is that the two should **tell the same story.** If you are testing your own mobile site or your app's back end through the eyes of a phone user in Türkiye, a mobile User-Agent goes with an IP that leaves from a mobile carrier network; that is what [Mobile Proxy](https://proxynet.io/mobile-proxy) is for. If you are verifying the price or the ad a home user sees, a desktop browser identity with [Residential Proxy](https://proxynet.io/residential-proxy) is a consistent pair. A "phone" arriving from a data centre IP, or a request that comes from a German IP and sends `Accept-Language: tr`, is contradictory however carefully the User-Agent was chosen.

## Use cases

- **Comparative testing of mobile and desktop versions.** Opening the same page with two identities and the target country's IP to see the differences: [app testing solution](/app-testing).
- **Regular data collection under your own name.** A fixed bot identity, robots.txt compliance and a rate limit work together: [data scraping solution](/data-scraping).
- **Site crawling and link checking.** If you are writing your own crawler, the identity line is the first configuration item: [web crawler solution](/web-crawler).
- **Tracking the mobile and desktop difference in search results.** Rankings change with device type and location: [SEO proxy solution](/seo-proxy).
- **Browser automation.** In Playwright the User-Agent is given when the context is created and applies to every page of that context: [What Is Playwright and How to Use It With a Proxy](/blog/playwright-proxy).

## Common mistakes

- **Assuming that changing the User-Agent also hides the IP.** They are separate layers; the User-Agent holds no IP information.
- **Changing only the header and forgetting Client Hints.** Chrome keeps stating the real operating system through `Sec-CH-UA-Platform`.
- **Reading the operating system version from the User-Agent.** In current Chrome these fields are fixed; Windows 11 and new Android versions do not show up in the string.
- **Using an old "User-Agent list" found on the internet.** A request naming a Chrome version from years ago does not resemble real browser traffic, and some sites send an incomplete page to old versions.
- **Picking a random identity or posing as Googlebot.** The first is an inconsistency signal alongside the same IP and cookie, the second does not pass reverse DNS verification.
- **Installing a switcher extension without checking its permissions.** An extension that rewrites headers can see all your traffic.
- **Leaving the change on after the test.** When "Desktop site" or the extension stays on, sites start to look broken and nobody remembers why.

## Decision guide

| Need | Recommendation |
|---|---|
| I want to see my own User-Agent | `navigator.userAgent` in the console, or `httpbin.org/headers` |
| I will try the mobile view on a computer | DevTools > More tools > Network conditions |
| I will open the desktop page on a phone | "Desktop site" in the Chrome menu |
| I need to know whether a visitor runs Windows 11 | `Sec-CH-UA-Platform-Version` or `getHighEntropyValues` |
| I am writing a scraper that runs regularly | One fixed bot identity with a name and a contact address |
| I will test how I look from another country and device | A User-Agent that fits the device together with a proxy IP of the same type |
| I want to see what my site shows to bots | Test with a bot identity on your own site only |
| I want to get past a site's bot protection with the User-Agent | This route does not work; use the official API or ask the site owner for permission |

## Frequently asked questions

### What does User-Agent mean?

Literally, the "agent of the user": the software that sends requests to the internet on your behalf. In everyday use it means the text in the `User-Agent` header, which that software sends with every request to state its name, version and operating system.

### Does the User-Agent show my IP address or location?

No. The string holds only software and operating system information. The site learns your IP address from the connection itself, and your approximate location from that IP address. Changing the User-Agent affects neither.

### Is changing the User-Agent legal?

Changing a header that your own browser sends is not a prohibited act in itself; browsers ship a ready-made menu for it in their developer tools. What matters is what you do after changing it. Acting as another organisation's bot or getting around a site's terms of use causes trouble regardless of how you set the header. We cover the legal framework of data collection in [Is Data & Web Scraping Legal?](/blog/is-data-web-scraping-legal).

### Why does the User-Agent say Windows 10 on Windows 11?

Chromium-based browsers have frozen the operating system field at `Windows NT 10.0`. The real version is read from the `Sec-CH-UA-Platform-Version` header; a major version of 13 or higher means Windows 11.

### Have Client Hints replaced the User-Agent?

Not yet. The `User-Agent` header is still sent by every browser; Chrome only simplified its content. Client Hints are an additional mechanism that gives the detail to sites that ask for it, through a permission-based route, and for now they exist only in Chromium-based browsers. For Firefox and Safari users, sites still look at the `User-Agent` string.

### Does the User-Agent change when I use a proxy?

It does not. A proxy changes the IP address the request leaves from; the headers you send stay the same. Plan the two together: the User-Agent states the device type, the proxy states the location and the network type.

## Summary

The User-Agent is the one-line statement in which the software sending a request introduces itself. Starting with `Mozilla/5.0` is a historical compatibility leftover; the real information is inside the parentheses and at the end of the line. Chrome simplified this line and moved the detail into Client Hints headers, which is why Windows 11 appears as `NT 10.0` and new phones as `Android 10; K`. Changing it is easy (the Network conditions tab, the "Desktop site" box, `curl -A`), but only the label changes: Client Hints, JavaScript signals, the connection trace and the IP address stay in place. In your own script, use a single identity that carries your name and contact address instead of random identities, and do not pose as another bot. For IP addresses that are consistent with the device and location you are testing, take a look at [our proxy services](/proxy).
