# Localization

> Search Google as a user in a specific country, language and city with country, language, location, uule and ll, including code tables for common countries and languages.

Google's results depend heavily on where the searcher is and which language they use. SerpKite exposes the same levers Google uses, with plain names.

| Parameter | Controls | Example |
| --- | --- | --- |
| `country` | Country the search runs from | `de` |
| `language` | Interface language | `de` |
| `location` | City or region, as free text | `"Munich, Bavaria, Germany"` |
| `uule` | A pre-encoded Google location | `w+CAIQICI...` |
| `ll` | Exact map viewport ([/v1/maps](https://serpkite.com/docs/endpoints/maps) only) | `"@48.137,11.575,14z"` |

Defaults are `country: "us"` and `language: "en"`. The normalised values come back in `request.country` and `request.language` on every response. Without `location`, results are country-level.

## Country and language

`country` is a two-letter ISO 3166-1 alpha-2 country code (case-insensitive). `language` is a language code (`en`, `de`) or a language plus region (`pt-BR`, `zh-TW`). They are independent: `country: "ch"` with `language: "fr"` is a French-speaking user in Switzerland.

cURL:

```bash
curl https://api.serpkite.com/v1/search \
  -H "Authorization: Bearer $SERPKITE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"q":"beste Kaffeemühle","country":"de","language":"de"}'
```

TypeScript:

```ts
import { SerpKite } from "serpkite";

const sk = new SerpKite(); // reads SERPKITE_API_KEY
const res = await sk.search({ q: "beste Kaffeemühle", country: "de", language: "de" });
console.log(res.results[0].title, res.meta.credits_used);
```

Python:

```python
from serpkite import SerpKite

sk = SerpKite()  # reads SERPKITE_API_KEY
res = sk.search("beste Kaffeemühle", country="de", language="de")
print(res.results[0].title, res.meta.credits_used)
```

Go:

```go
package main

import (
	"context"
	"fmt"
	"log"

	serpkite "github.com/serpkite/serpkite-go"
)

func main() {
	ctx := context.Background()
	c := serpkite.NewClient() // reads SERPKITE_API_KEY
	res, err := c.Search(ctx, serpkite.SearchParams{Q: "beste Kaffeemühle", Country: "de", Language: "de"})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(res.Results[0].Title, res.Meta.CreditsUsed)
}
```

Set both to match your target market. Mixing them (German query, `country: "us"`) is valid but returns what an American user searching in German sees, which is rarely what you want for rank tracking.

Invalid codes return `400 invalid_request` ("country must be a country code", "language must be a language code") and are not billed.

## City-level location

`location` is a free-text place name up to 256 characters. Use the canonical form "City, Region, Country", e.g. `"Austin, Texas, United States"`. It matters most for queries with local intent ("dentist", "coffee near me"), for [/v1/maps](https://serpkite.com/docs/endpoints/maps), [/v1/places](https://serpkite.com/docs/endpoints/places) and [/v1/shopping](https://serpkite.com/docs/endpoints/shopping), and for local packs inside [/v1/search](https://serpkite.com/docs/endpoints/search).

cURL:

```bash
curl https://api.serpkite.com/v1/places \
  -H "Authorization: Bearer $SERPKITE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"q":"dentist","location":"Austin, Texas, United States","country":"us"}'
```

TypeScript:

```ts
import { SerpKite } from "serpkite";

const sk = new SerpKite(); // reads SERPKITE_API_KEY
const res = await sk.places({ q: "dentist", location: "Austin, Texas, United States", country: "us" });
console.log(res.results[0].title, res.meta.credits_used);
```

Python:

```python
from serpkite import SerpKite

sk = SerpKite()  # reads SERPKITE_API_KEY
res = sk.places("dentist", location="Austin, Texas, United States", country="us")
print(res.results[0].title, res.meta.credits_used)
```

Go:

```go
package main

import (
	"context"
	"fmt"
	"log"

	serpkite "github.com/serpkite/serpkite-go"
)

func main() {
	ctx := context.Background()
	c := serpkite.NewClient() // reads SERPKITE_API_KEY
	res, err := c.Places(ctx, serpkite.SearchParams{Q: "dentist", Location: "Austin, Texas, United States", Country: "us"})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(res.Results[0].Title, res.Meta.CreditsUsed)
}
```

`location` overrides `country` for geography. Keep `country` set to the same country anyway, so the Google domain and language defaults line up.

## uule

`uule` is Google's own encoded location string. If you already store locations in that form (many rank trackers do), pass it directly; it overrides `location`. Maximum length is 512 characters. Most users should use `location` and let SerpKite handle the encoding.

## Map viewport (ll)

On [/v1/maps](https://serpkite.com/docs/endpoints/maps), `ll` pins the search to an exact viewport: `@latitude,longitude,zoomz`. Higher zoom means a smaller area.

cURL:

```bash
curl https://api.serpkite.com/v1/maps \
  -H "Authorization: Bearer $SERPKITE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"q":"coffee roasters","ll":"@52.52,13.405,14z"}'
```

TypeScript:

```ts
import { SerpKite } from "serpkite";

const sk = new SerpKite(); // reads SERPKITE_API_KEY
const res = await sk.maps({ q: "coffee roasters", ll: "@52.52,13.405,14z" });
console.log(res.results[0].title, res.meta.credits_used);
```

Python:

```python
from serpkite import SerpKite

sk = SerpKite()  # reads SERPKITE_API_KEY
res = sk.maps("coffee roasters", ll="@52.52,13.405,14z")
print(res.results[0].title, res.meta.credits_used)
```

Go:

```go
package main

import (
	"context"
	"fmt"
	"log"

	serpkite "github.com/serpkite/serpkite-go"
)

func main() {
	ctx := context.Background()
	c := serpkite.NewClient() // reads SERPKITE_API_KEY
	res, err := c.Maps(ctx, serpkite.SearchParams{Q: "coffee roasters", LL: "@52.52,13.405,14z"})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(res.Results[0].Title, res.Meta.CreditsUsed)
}
```

## Country codes

Common values of `country`. Any valid ISO 3166-1 alpha-2 code works, not only the ones listed.

| `country` | Country |
| --- | --- |
| `us` | United States |
| `gb` | United Kingdom |
| `ca` | Canada |
| `au` | Australia |
| `in` | India |
| `de` | Germany |
| `fr` | France |
| `es` | Spain |
| `it` | Italy |
| `nl` | Netherlands |
| `be` | Belgium |
| `ch` | Switzerland |
| `at` | Austria |
| `se` | Sweden |
| `no` | Norway |
| `dk` | Denmark |
| `fi` | Finland |
| `pl` | Poland |
| `cz` | Czechia |
| `pt` | Portugal |
| `ie` | Ireland |
| `br` | Brazil |
| `mx` | Mexico |
| `ar` | Argentina |
| `co` | Colombia |
| `cl` | Chile |
| `jp` | Japan |
| `kr` | South Korea |
| `sg` | Singapore |
| `id` | Indonesia |
| `my` | Malaysia |
| `ph` | Philippines |
| `th` | Thailand |
| `vn` | Vietnam |
| `tr` | Türkiye |
| `ae` | United Arab Emirates |
| `sa` | Saudi Arabia |
| `za` | South Africa |
| `ng` | Nigeria |
| `nz` | New Zealand |

## Language codes

Common values of `language`. Other language codes Google supports work too.

| `language` | Language |
| --- | --- |
| `en` | English |
| `de` | German |
| `fr` | French |
| `es` | Spanish |
| `it` | Italian |
| `pt` | Portuguese |
| `pt-BR` | Portuguese (Brazil) |
| `nl` | Dutch |
| `sv` | Swedish |
| `da` | Danish |
| `no` | Norwegian |
| `fi` | Finnish |
| `pl` | Polish |
| `cs` | Czech |
| `tr` | Turkish |
| `ja` | Japanese |
| `ko` | Korean |
| `zh-CN` | Chinese (Simplified) |
| `zh-TW` | Chinese (Traditional) |
| `hi` | Hindi |
| `id` | Indonesian |
| `th` | Thai |
| `vi` | Vietnamese |
| `ar` | Arabic |

## Tips

- For rank tracking, fix `country`, `language`, `location` and `device` per keyword and never change them between runs, or positions stop being comparable. See [Rank tracking](https://serpkite.com/docs/guides/rank-tracking).
- Mobile and desktop layouts differ; set `device: "mobile"` if your users are on phones. See [Common parameters](https://serpkite.com/docs/parameters).
- Localized results are cached per location, so [`max_age`](https://serpkite.com/docs/caching) hits only when all of these parameters match.