> ## Documentation Index
> Fetch the complete documentation index at: https://docs.2extract.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Geo Verification

> Check what your site, your search results, or your ads actually look like from another country - with an agent that resolves the targeting for you.

Your site behaves differently depending on where the visitor is: currency, language, legal banners, available plans, which ads render. You cannot check any of that from your own desk.

***

## What this covers

Three jobs that are the same job underneath - look at something from somewhere else:

* **Localisation QA.** Does the German site actually show euros, and does the cookie banner appear where it must?
* **Search and marketplace results.** What ranks in Brazil, what your competitors' listings look like there.
* **Ad verification.** Which creatives run in which market, and whether your placements appear at all.

***

## The setup

> I need to check how our site renders in Germany, Brazil and Japan.

```text icon="terminal" theme={null}
listGeoCountries      ⌐ DE · BR · JP
createProxyResource   ⌐ geo_qa
                        "Localisation QA across DE, BR and JP"
setProxyLimits        ⌐ 5 GB per month

DE  2xt-customer-K3nP7qLm2Xv-proxy-geo_qa-country-de:s7Kd92mQ@proxy.2extract.net:5555
BR  2xt-customer-K3nP7qLm2Xv-proxy-geo_qa-country-br:s7Kd92mQ@proxy.2extract.net:5555
JP  2xt-customer-K3nP7qLm2Xv-proxy-geo_qa-country-jp:s7Kd92mQ@proxy.2extract.net:5555
```

Verification traffic is light - you are loading pages, not harvesting a catalogue - so a small cap is realistic.

***

## Hold the IP for the whole check

This is the one case where a sticky session is not optional. A localisation check is a sequence: land on the page, accept the banner, switch a filter, look at checkout. If the exit IP changes halfway, the site may re-detect the location and reset everything you just did.

```
...-proxy-geo_qa-country-de-session-qa_de_run1-time-30:...
```

A 30-minute TTL comfortably covers a manual pass. See [Session Control](/proxy-products/configuration/session).

<Warning>
  Use a different session ID per country. Reusing one ID across markets means reusing one IP, and the second check reports the first country's results.
</Warning>

***

## In a headless browser

Most verification is visual, so a browser beats an HTTP client:

```javascript verify.js icon="js" theme={null}
import { chromium } from "playwright";

const BASE = "2xt-customer-K3nP7qLm2Xv-proxy-geo_qa";
const PASSWORD = "s7Kd92mQ";

async function checkMarket(country) {
  const browser = await chromium.launch({
    proxy: {
      server: "http://proxy.2extract.net:5555",
      username: `${BASE}-country-${country}-session-qa_${country}-time-30`,
      password: PASSWORD,
    },
  });

  const page = await browser.newPage();
  await page.goto("https://example.com");
  await page.screenshot({ path: `market-${country}.png`, fullPage: true });
  await browser.close();
}

for (const country of ["de", "br", "jp"]) {
  await checkMarket(country);
}
```

Three screenshots, three markets, one proxy. Full setup notes in the [Playwright guide](/integrations/frameworks/node-playwright).

***

## Going city-level

Ad targeting and delivery promises are often set below the country. Ask the agent to resolve it:

> Same check, but from São Paulo.

```text icon="terminal" theme={null}
searchGeoCities  country_code: "BR", search: "Sao Paulo"
  ⌐ Sao Paulo · sao_paulo

...-proxy-geo_qa-country-br-city-sao_paulo-session-qa_br_sp-time-30:...
```

Region and ZIP targeting work the same way. Which countries support which level is listed under [Geo Reference](/data/cities).

***

## Reading the result honestly

Two things trip people up.

**IP geolocation databases disagree.** Two "where am I" services can report different cities for the same IP. What matters is what your target site concludes, not what a checker says - see [My IP location is incorrect](/help/common-problems/ip-location-incorrect).

**The IP is not the only signal.** Sites also read `Accept-Language`, the timezone your browser reports, and any stored preference. If a page still renders in English through a German IP, check the browser locale before blaming the proxy.

<Tip>
  Set the browser locale and timezone to match the market. In Playwright: `chromium.launch({ ... })` then `browser.newContext({ locale: "de-DE", timezoneId: "Europe/Berlin" })`.
</Tip>

***

## Next steps

<CardGroup cols={2}>
  <Card title="Price Monitoring" icon="tag" href="/ai/use-cases/price-monitoring">
    The same geo mechanics, run on a schedule.
  </Card>

  <Card title="Agent Web Access" icon="globe" href="/ai/use-cases/agent-web-access">
    Giving an agent general reading access to the web.
  </Card>
</CardGroup>
