UULE Generator
Generate the uule parameter from a city name (v1) or GPS coordinates (v2), or decode one, and open Google as if you were there.
Location and query
UULE and search URL
What is UULE
UULE is a parameter in Google search URLs that carries an encoded location. Add &uule= and a
value to a google.com/search URL and Google returns results as if you were searching from that
place. SEOs use it to check local rankings, map packs and “near me” results for cities they are not in.
Developers use it in rank trackers and SERP scrapers.
There are two formats. v1 starts with w+ and holds a place name such as
Austin,Texas,United States. v2 starts with a+ and holds GPS coordinates.
This tool encodes both and decodes either one. Everything runs in your browser.
How to use the generator
- Pick a mode. City name (v1) takes a city, region and country. GPS coordinates (v2) takes a latitude and longitude, with an optional radius and timestamp. Decode reads a UULE back.
- Type a search query. The UULE and a ready Google search URL update as you type.
- Copy the UULE, copy the URL, or press Open in Google.
- Use the OpenStreetMap link to check that the place or point is the one you meant. In Decode mode, Load into generator copies the decoded location into the matching form so you can edit it.
UULE v1: a location name
A v1 value is a small protocol buffer (protobuf) message, base64-encoded, with w+ in front. Here are
the bytes for Austin:
| Bytes | Protobuf meaning |
|---|---|
| 08 02 | Field 1, whole number, value 2 |
| 10 20 | Field 2, whole number, value 32 |
| 22 1a | Field 4, text, 26 bytes long (0x1a = 26) |
| 41 75 73 … | The 26 UTF-8 bytes of Austin,Texas,United States |
Base64 of those bytes is CAIQICIaQXVzdGlu…, and the full value is
w+CAIQICIaQXVzdGluLFRleGFzLFVuaXRlZCBTdGF0ZXM=. The first two fields never change, so every name shorter
than 64 bytes gives a value starting with w+CAIQICI. Some guides call the next character a “secret key”. It is really the name’s
length: for names under 64 bytes it is the base64 letter for that number (a = 26, k = 36).
At 64 bytes and up the prefix itself changes, and names over 127 bytes need a two-byte length. This tool handles
both cases, so you don’t need a lookup table.
Finding Google’s canonical location name
The name is the city, region and country joined with commas and no spaces. When spelling matters, copy it from Google’s geo targets list: the Google Ads API developer site publishes it as a CSV. Its columns are Criteria ID, Name, Canonical Name, Parent ID, Country Code, Target Type and Status. The Canonical Name column holds the exact string to encode.
| City | Region | Country | Canonical |
|---|---|---|---|
| Austin | Texas | United States | Austin,Texas,United States |
| Paris | Ile-de-France | France | Paris,Ile-de-France,France |
| Berlin | Germany | Berlin,Germany |
UULE v2: GPS coordinates
A v2 value is not a binary protobuf. It is a few lines of plain text, base64-encoded, with a+ in
front. The format below comes from SerpApi’s open-source (MIT-licensed) UULE converter. Each line ends with a
newline, including the last one, and nothing is indented. This is the example from SerpApi’s article on
GPS-targeted local results, decoded:
| Line | What it holds |
|---|---|
| role:1 | A fixed value. SerpApi’s notes say 1 means USER_SPECIFIED_FOR_REQUEST. |
| producer:12 | A fixed value. SerpApi’s notes say 12 means LOGGED_IN_USER_SPECIFIED. |
| provenance:0 | SerpApi saw no change in results when they changed it. |
| timestamp:1681216241206112 | Microseconds since 1970-01-01 UTC. This one is 2023-04-11 12:30:41.206112 UTC. |
| latlng{ | Opens the coordinate block. |
| latitude_e7:470484290 | Latitude times 10,000,000, as a whole number: 47.048429°. |
| longitude_e7:94986740 | Longitude times 10,000,000: 9.498674°. |
| } | Closes the block. |
| radius:-1 | SerpApi saw no change from it; -1 and 0 “work for now”. |
The text is encoded with the URL-safe base64 alphabet (- and _ instead of
+ and /), and the trailing = padding is removed. That gives
a+cm9sZToxCnByb2R1Y2VyOjEy…. With the same timestamp, this tool reproduces SerpApi’s value exactly.
The meanings of role and producer come from SerpApi’s notes, not from Google. Google has not published this format. The timestamp defaults to now. Coordinates are rounded to 7 decimal places, about a centimetre. SerpApi’s converter truncates instead of rounding, so the two can differ by 0.0000001° at most.
v1 vs v2
| v1 | v2 | |
|---|---|---|
| Prefix | w+ | a+ |
| Holds | A canonical place name | Latitude and longitude, plus radius and timestamp |
| Inside the base64 | Binary protobuf | Plain text lines |
| Base64 alphabet | Standard, with padding | URL-safe, no padding |
| Length | Grows with the name (26 characters for Tokyo,Japan) | About 165 characters |
| Location detail | Whatever area Google matches to the name | A point, to 7 decimal places |
| Changes over time | No, the same name always gives the same value | Yes, the timestamp is inside |
| Use it when | You know the city or region name | You want to target a specific point by coordinates |
Building a v2 UULE in code
The text is all ASCII, so a few lines of JavaScript are enough. This function returns SerpApi’s example value
exactly when called as uuleV2(47.048429, 9.498674, 1681216241206112):
function uuleV2(lat, lng, timestamp = Date.now() * 1000, radius = -1) {
const text =
`role:1\nproducer:12\nprovenance:0\ntimestamp:${timestamp}\n` +
`latlng{\nlatitude_e7:${Math.round(lat * 1e7)}\nlongitude_e7:${Math.round(lng * 1e7)}\n}\n` +
`radius:${radius}\n`;
return 'a+' + btoa(text).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
} Validate the input before encoding. Latitude must be between -90 and 90 and longitude between -180 and 180, both as finite numbers, and the radius must be a whole number. The form above does these checks for you.
Building a local search URL
The generated URL has two parameters: q for the query and uule for the location. The
UULE is percent-encoded (w+ becomes w%2B), because a bare + in a query
string can be read as a space. For a full local check, also set gl (the two-letter country code)
and hl (the interface language):
https://www.google.com/search?q=pizza&gl=us&hl=en&uule=w%2BCAIQICIaQXVzdGluLFRleGFzLFVuaXRlZCBTdGF0ZXM%3D
The Google Search URL Generator builds URLs with gl, hl, uule,
time filters and result types. It can also take a URL apart. To test a local query with operators like
site: or intitle:, build it in the
Search Query Generator and paste it into the query box here.
How to check that it worked
- Open the search URL in a private window, so your Google account and search history don’t mix in.
- Scroll to the bottom of the results page. Google has typically shown the location it used there. If it shows your real location, it may have ignored the UULE.
- Look at the map pack and local results. They should match the target place.
- Generate a UULE for a second city and compare the two pages side by side.
Google does not document uule and can change how it is handled at any time. Even when it works,
some results can still depend on your IP address, account, language settings or device. Treat a UULE check as a
strong signal, not a guarantee. To cross-check an encoding, decode it here or compare it with a second
implementation, such as Valentin Pletzer’s UULE guide or SerpApi’s converter.
Decoding a UULE
Paste a UULE or a whole Google URL into Decode mode. The tool finds the uule parameter and undoes
percent-encoding (including double-encoded %252B). It accepts both base64 alphabets, with or without
padding. For v1 it shows the location name, its byte length, the header bytes and every protobuf field. For v2 it
shows the decoded text, the coordinates, radius and timestamp as a UTC date, and any extra lines it doesn’t
recognise. Values it can’t read get a specific error message, not a blank result.
Examples
| Location | Query | UULE |
|---|---|---|
| Austin,Texas,United States | pizza | w+CAIQICIaQXVzdGluLFRleGFzLFVuaXRlZCBTdGF0ZXM= |
| Paris,Ile-de-France,France | hotels | w+CAIQICIVUGFyaXMsSWxlLWRlLUZyYW5jZSxGcmFuY2U= |
| Tokyo,Japan | ramen | w+CAIQICILVG9reW8sSmFwYW4= |
| 47.048429, 9.498674 (v2, SerpApi’s example) | any | a+cm9sZToxCnByb2R1Y2VyOjEyCnByb3ZlbmFuY2U6MAp0aW1lc3RhbXA6MTY4MTIxNjI0MTIwNjExMgpsYXRsbmd7CmxhdGl0dWRlX2U3OjQ3MDQ4NDI5MApsb25naXR1ZGVfZTc6OTQ5ODY3NDAKfQpyYWRpdXM6LTEK |
Common uses
- Spot-checking local rankings for a keyword in another city, without a VPN or a trip.
- Auditing multi-location businesses: one v1 UULE per branch city, or one v2 UULE per branch address, to compare map packs across locations.
- Rank-tracking scripts and SERP APIs: SerpApi, for example, accepts a
uuleparameter. It can’t be combined with SerpApi’s ownlocationparameter in the same request. - Reading someone else’s URL: decode the UULE in a link from a report or tool to see which place or point it really targets.
Troubleshooting
- “Unrecognised UULE format”: the value has to start with
w+ora+(orw%2B/a%2Bin a URL). Check that you copied the whole value. - Results look like your own city: try a private window, add
glfor the target country, and check the location name against the geo targets CSV. - Latitude out of range: latitude comes first and must be between -90 and 90. If the numbers look swapped, the tool says so.
- A comma in a coordinate: use a dot for decimals (
47.05, not47,05). To paste both numbers at once, put a space after the comma:47.048429, 9.498674. - Timestamp warning: v2 timestamps are in microseconds (16 digits). A 10-digit value is seconds and a 13-digit value is milliseconds. Leave the field empty to use the current time.
- The v2 value changes every time: that’s the timestamp. Enter a fixed one to get a value that repeats.
Limits
- A v1 UULE names a place, not a point. Two addresses in the same city get the same value.
- Ads and some universal results can still reflect your real location, IP address or ad settings.
- The v1 encoding matches published test vectors, and the v2 encoding matches SerpApi’s converter and blog example. Neither format is officially documented by Google.
Frequently asked questions
What is the uule parameter?
UULE is a Google search URL parameter that carries an encoded location. Adding &uule=... to a google.com/search URL makes Google return results as if you were searching from that place.
How do I use the generated uule?
Enter a city and a search query, then press Open in Google or copy the search URL. The uule value travels in the URL, so the results page opens with your simulated location applied.
What format does the location use?
City, region and country joined with commas and no spaces, e.g. Austin,Texas,United States. That canonical name is what gets encoded. The region can be left out for cities like Berlin,Germany.
What is UULE v2?
A second format that carries GPS coordinates instead of a place name. It is a few lines of plain text (role, producer, provenance, timestamp, latitude_e7, longitude_e7 and radius), base64-encoded with the URL-safe alphabet after an a+ prefix. The field meanings come from SerpApi's notes; Google has not documented the format.
How do I decode a UULE?
Switch to Decode and paste the value or a whole Google URL. The tool reads w+ (v1) and a+ (v2) values, URL-safe or standard base64, and percent-encoded text such as a%2B..., then shows the location name, or the coordinates, radius and timestamp.
Should I use v1 or v2?
Use v1 when you know the name Google uses for the city or region, for example from the Google Ads geo targets list. Use v2 to target a specific point by latitude and longitude. Google documents neither format, so check the results page either way.
How can I verify the location worked in Google?
Open the search URL in a private window and scroll to the bottom of the results page, where Google has typically shown the location it used. Then generate a URL for a second place and compare the local results.
Does the location change every part of the results?
It strongly affects local and location-sensitive results such as maps, local packs and nearby businesses. Some elements like ads, personalization and your real IP-based signals can still differ.
Is anything I type uploaded anywhere?
No. The encoding runs in your browser with JavaScript and nothing is sent to a server. Inputs under 200 KB are kept in your browser's local storage so they are still there when you come back.