A dark relief map of Europe with a loop of orange thread enclosing several countries, held by a single brass pin, representing one request that can be served from anywhere inside a chosen set of locations.
All Posts

Proxy Geo-Targeting by City, ZIP Code, and ASN: Up to 5 Locations per Request

Franklin Uche
Franklin Uche · Community Lead
Open markdown

Residential proxy geo-targeting lets you choose where a request exits: a country, a region, a city, a ZIP code, or a network (ASN). On Massive's residential network, multi-location targeting goes one step further and lets one proxy username name up to five locations. Write country-US,GB,DE and the request goes out through a device in any of those three countries, with traffic spread across them. The same works for subdivisions, cities, ZIP codes, and ASNs, and device type accepts a list too. This spotlight covers single city and ZIP code targeting, the syntax for lists, the four rules that keep lists unambiguous, and how to check which location actually served each request.

Key Takeaways
  • Target one city with country-US-subdivision-NY-city-New%20York, or one ZIP code with country-US-zipcode-10001. A ZIP code overrides city.
  • country, subdivision, city, and zipcode each accept a comma-separated list of up to 5 values. A request is served by any node that matches one of them, and traffic is spread across them (Massive Docs).
  • asn also accepts up to 5 values, and type accepts several device types, such as mobile,tv.
  • Only one parameter per request may hold a list. A list of countries can't be narrowed by region, city, or ZIP code.
  • A second list or more than five values returns HTTP 400. Read the X-Exit-Country and X-Exit-ASN headers to see which value served each request.

How do you target a residential proxy by city or ZIP code?

Add geo keys to the proxy username. country comes first and is required whenever you set any other geo key (Massive Docs). By city:

BASH
curl -x https://network.joinmassive.com:65535 \
     -U '{PROXY_USERNAME}-country-US-subdivision-NY-city-New%20York:{API_KEY}' \
     https://cloudflare.com/cdn-cgi/trace

Adding subdivision matters when a city name exists in more than one region of a country; without it, "the request can be served from any of them." By ZIP code:

BASH
curl -x https://network.joinmassive.com:65535 \
     -U '{PROXY_USERNAME}-country-US-zipcode-10001:{API_KEY}' \
     https://cloudflare.com/cdn-cgi/trace

When you set a ZIP code, the city key is ignored. Some countries accept partial postal codes, such as 5 characters in the United States and 3 in Canada. The docs add a caveat worth keeping in mind: "Geotargeting by country and city is always more robust than by ZIP code" (Massive Docs).

What problem does multi-location targeting solve?

Single-location targeting forces a choice. Either you pin a request to one place and accept that a narrow target may have fewer available devices, or you drop targeting and accept requests from anywhere. Many real jobs sit in between. A price check for the EU market might accept Germany, France, or the Netherlands. An ad check for a U.S. campaign might accept any of its five target metros. A test of how a site treats mobile carriers might accept any of three carrier networks.

Without lists, covering those cases means rotating usernames in your own code. With a list, one username describes the whole acceptable set, and the network picks a matching device. Our test of whether ChatGPT answers differ by country covers when an AI agent needs a location at all. This is the next step: describing the set of locations that count as correct.

How do you target several locations in one request?

Put a comma-separated list in the parameter. Per the geotargeting docs, the request "is then served by any node that matches one of the listed values, and traffic is spread across them." Several countries look like this:

BASH
curl -x https://network.joinmassive.com:65535 \
     -U '{PROXY_USERNAME}-country-US,GB,DE:{API_KEY}' \
     https://cloudflare.com/cdn-cgi/trace

One country, several cities. City names are currently case-sensitive and must be URL-encoded, so New York becomes New%20York:

BASH
curl -x https://network.joinmassive.com:65535 \
     -U '{PROXY_USERNAME}-country-US-city-New%20York,Chicago:{API_KEY}' \
     https://cloudflare.com/cdn-cgi/trace
One username, up to five acceptable locations.

How do you target a proxy by ASN or device type?

Add asn to the username. ASN (the number that identifies a network, such as a mobile carrier or ISP) accepts up to five values. This request is served by a U.S. node on either of two networks (Massive Docs):

BASH
curl -x https://network.joinmassive.com:65535 \
     -U '{PROXY_USERNAME}-country-US-asn-7018,7922:{API_KEY}' \
     https://cloudflare.com/cdn-cgi/trace

Device type accepts a list that matches any of the named types. The values are mobile, common (any non-mobile device), and tv, and an unrecognized value returns HTTP 400. This request goes to a mobile or TV device in the U.S. (Massive Docs):

BASH
curl -x https://network.joinmassive.com:65535 \
     -U '{PROXY_USERNAME}-type-mobile,tv-country-US:{API_KEY}' \
     https://cloudflare.com/cdn-cgi/trace

What are the rules for lists?

Four rules keep a list from turning into an ambiguous request. All four come from the geotargeting docs:

Rule Example that works Example that fails
One list per request country-US-city-Boston,Chicago country-US,CA-city-Boston,Toronto
A list of countries can't be narrowed country-US,GB,DE country-US,GB-city-London
country is still required country-US-zipcode-10001,60601 zipcode-10001,60601
Up to 5 values country-US,GB,DE,FR,ES Six or more countries

The second rule exists because "the same region or city name can exist in more than one country." There is one exception to it: a single asn can still be combined with several countries. A list of ASNs, on the other hand, needs every other parameter to be single-valued, because only one parameter may hold a list.

Two smaller details: duplicate and empty values are ignored, so US,US counts as one value. And a second list, more than five values, a missing country, or an unrecognized type returns HTTP 400, so you find out at the first request, not after a silent fallback to some other location.

A 407 can hide a targeting mistake

We checked how the network reports a bad username without spending any traffic. On October 10, 2026, we sent six usernames to the residential endpoint with a deliberately invalid API key. Four broke a documented rule: six countries, two lists in one request, a city with no country, and an unknown device type.

TEXT
probe-country-US,GB,DE
probe-country-US,GB,DE,FR,ES,IT
probe-country-US,CA-city-Boston,Toronto
probe-city-Boston
probe-type-mobile,tv-country-US
probe-type-watch-country-US

Every one of the six came back 407 Proxy Authentication Required, not 400. You can repeat the test with any placeholder username and key.

So the network checks credentials before it checks targeting. That ordering matters when you debug. A 407 tells you nothing about whether your targeting is valid, so fix the credentials first. Once authentication passes, a 400 points at the targeting itself.

Validate a multi-location username before you send it

You can catch these mistakes before a request leaves your code. This small builder enforces the documented rules and URL-encodes city names:

PYTHON
from urllib.parse import quote
GEO = ("country", "subdivision", "city", "zipcode")
LISTABLE = GEO + ("asn",)
ORDER = ("type",) + LISTABLE
DEVICE_TYPES = {"mobile", "common", "tv"}
def massive_username(base, **params):
    """Build a residential proxy username and enforce the documented list rules."""
    unknown = set(params) - set(ORDER)
    if unknown:
        raise ValueError(f"unsupported keys: {sorted(unknown)}")
    vals = {}
    for key in ORDER:
        value = params.get(key)
        if value is None or value == "" or (
            isinstance(value, (list, tuple)) and not value
        ):
            continue
        items = value if isinstance(value, (list, tuple)) else [value]
        # The network ignores duplicate and empty values; drop them here too.
        items = list(dict.fromkeys(str(v).strip() for v in items if str(v).strip()))
        if key in LISTABLE and len(items) > 5:
            raise ValueError(f"{key}: up to 5 values")
        if key == "type" and not set(items) <= DEVICE_TYPES:
            raise ValueError(f"type must be one of {sorted(DEVICE_TYPES)}")
        vals[key] = items
    if any(k in vals for k in GEO) and "country" not in vals:
        raise ValueError("country is required with any geo key")
    lists = [k for k in LISTABLE if len(vals.get(k, [])) > 1]
    if len(lists) > 1:
        raise ValueError(f"only one list per request, got {lists}")
    if len(vals.get("country", [])) > 1 and any(k in vals for k in GEO[1:]):
        raise ValueError("a list of countries can't be narrowed")
    return "-".join([base] + [f"{k}-{','.join(quote(v) for v in vals[k])}" for k in vals])
print(massive_username("{PROXY_USERNAME}", country="US", city=["New York", "Chicago"]))
# {PROXY_USERNAME}-country-US-city-New%20York,Chicago

We ran it against 13 cases on October 10, 2026. The valid inputs built the expected usernames, and six countries, two lists, a narrowed country list, a city without a country, and an unknown device type each raised an error. It covers the rules the docs state. The docs don't say whether a device-type list counts toward the one-list limit, so the builder doesn't enforce that.

Lists versus strict targeting

Lists widen targeting. Stacking several single-value parameters narrows it. The docs warn that "the more strict geotargeting narrows the range of appropriate nodes," and the knowledge base advises starting broad and narrowing as needed (Massive Docs).

Lists give you a middle setting. If a single small city returns 471 No Route Match, which means no available node matched your parameters (Massive Docs), a list of nearby cities in the same country is often a better fix than dropping to country level. You keep the results local while giving the network more devices to choose from.

How do you know which location served the request?

Read the exit node headers, the network's own record of where the exit IP sits. For HTTPS traffic, the response to the proxy's CONNECT request includes X-Exit-IP and, when the data is available, X-Exit-Country, X-Exit-Timezone, and X-Exit-ASN (Massive Docs). Run curl with -v to see them:

TEXT
< HTTP/1.1 200 OK
< X-Exit-IP: 203.0.113.42
< X-Exit-Country: US
< X-Exit-Timezone: America/New_York
< X-Exit-ASN: 7922

When a request can be served from any of five places, log which one served it. Store the exit country and ASN next to each result. If one market's numbers look off later, you can split your data by the location that served it instead of guessing. The same location parameters work on the AI chat endpoint when the thing you're checking is an LLM answer rather than a page.

Four jobs where multi-location targeting helps

  • Regional price and stock checks. Name the countries or cities that make up a market, and let the network spread requests across them. For an EU price check, country-DE,FR,NL covers three markets with one username and no rotation code.
  • Ad verification. List a campaign's target ZIP codes, such as country-US-zipcode-10001,60601,94103.
  • Carrier and device testing. List the carrier networks or device types you care about, such as type-mobile,tv, without writing rotation logic.
  • Resilient localized fetching. Swap a narrow target that sometimes returns 471 for a short list of equivalent ones.

The bottom line

  • With proxy geo-targeting lists, one proxy username can describe up to five acceptable countries, subdivisions, cities, ZIP codes, or ASNs, plus several device types.
  • Keep to one list per request, keep country in every geo request, and don't narrow a list of countries.
  • Log the exit country and ASN.

Sources

Frequently Asked Questions

Can I get a residential proxy by city or ZIP code?+

Yes. Add country plus city (and subdivision if the city name repeats within the country), or country plus zipcode, to the proxy username. Each key also accepts a list of up to 5 values.

How many locations can one Massive proxy request target?+

Up to five values in one parameter, such as five countries or five cities in one country. More than five returns HTTP 400.

Can I list several countries and several cities at once?+

No. Only one parameter per request may hold a list, and a list of countries can't be combined with subdivision, city, or zipcode.

Can I combine an ASN with several countries?+

Yes. A single asn can be combined with a list of countries. A list of ASNs needs country and every other parameter to be single-valued.

How do I see which country served my request?+

Read the X-Exit-Country header in the CONNECT response for HTTPS traffic. X-Exit-ASN shows the network.