# Location Targeting

Source: https://docs.aon.pro/protocol/location-targeting

> Derived from the same AON Docs release as the source page.

AON location targeting is a Partner Offer-side declaration. It uses canonical location ids to express where a supply Offer may be eligible. It is separate from both Location Registry lookup and the public Query v1.0 request.

## Offer-side geographic targeting

A Partner Offer artifact can declare up to ten `targeting[]` rules. Geographic rules use `geo.include` and `geo.exclude`:

```json
{
  "targeting": [
    {
      "geo": {
        "include": [{"location_id": "2840"}],
        "exclude": [{"location_id": "21180"}]
      }
    }
  ]
}
```

Each entry is a closed object containing one numeric-string `location_id`. Every id must exist in the Full Location Catalog pinned by Protocol v1.0; numeric syntax alone is not enough. A location matches itself or a descendant, and `geo.exclude` wins over `geo.include`.

`targeting` is Partner-authored supply configuration. AON evaluates it before ranking and removes it from the public Offer projection returned to a Developer.

## Query v1.0 boundary

The current Query v1.0 request accepts structured intent, category constraints, bounded platform and session context, and response controls. Its `context` object is closed and does not define `user_profile` or another viewer-location field. Do not send `context.user_profile.location_ids`, coordinates, country, or a Location Search result in the Query body.

A `location_ids` chain returned by Location Search or a schema helper is registry ancestry data. It is not a Query v1.0 input. Deployment-owned eligibility context and runtime policy remain outside the portable public Query contract.

## Location Search and registry lookup

Location Search remains a public lookup and normalization API with three routes:

-   `GET /v1/locations/search` searches by name, country, parent, subdivision code, and supported catalog filters.
-   `GET /v1/locations/resolve` normalizes external location signals into AON ids and candidate records.
-   `GET /v1/locations/{location_id}` returns one registry record and its self-to-root ancestry chain.

The default `LEGACY` catalog exposes the compatible `COUNTRY`, `REGION`, and `CITY` levels. Explicit `FULL` search preserves the source target type and verified hierarchy instead of relabeling deeper target types. Use the [Location Search API](https://docs.aon.pro/api/location-search) for complete parameters, response fields, catalog differences, and examples.

## Static Registry

Use the static [AON Location Registry](https://github.com/agentoffernetwork/schema/blob/main/v1.0/locations/aon-location-registry.json) when you need deterministic offline lookup for the compatible three-level catalog.

Each entry contains `location_id`, `name`, `canonical_name`, `country_code`, `target_type`, `aon_level`, and `parent_location_id`. The registry does not publish precomputed ancestor caches; callers derive chains from parent links.

## Migration Helpers

The schema repo includes helpers for registry lookup, ancestry inspection, and migrating legacy Partner Offer targeting:

```js
import {
  buildLocationChain,
  cloudflareHeadersToLocationContext,
  countryCodeToLocationId,
  googleCloudHeadersToLocationContext,
  legacyCountryGeoToLocationGeo,
  subdivisionCodeToLocationId,
} from "@agentoffernetwork/schema/helpers/location-helpers.mjs"
 
countryCodeToLocationId("US")
// "2840"
 
legacyCountryGeoToLocationGeo(["US", "SG"])
// [{ location_id: "2840" }, { location_id: "2702" }]
// Suitable for a Partner Offer targeting[].geo include or exclude list.
 
buildLocationChain("1014221")
// ["1014221", "21137", "2840"]
 
subdivisionCodeToLocationId("US-CA")
// "21137"
 
cloudflareHeadersToLocationContext({
  "cf-ipcountry": "US",
  "cf-region-code": "CA",
  "cf-ipcity": "San Francisco",
}).location_ids
// ["1014221", "21137", "2840"]
 
googleCloudHeadersToLocationContext({
  client_region: "US",
  client_region_subdivision: "USCA",
  client_city: "San Francisco",
}).location_ids
// ["1014221", "21137", "2840"]
```

The header helpers normalize external signals and return lookup data for deployment-owned workflows. Their `location_ids` arrays are not fields to copy into a public Query v1.0 request.

## External Codes

AON accepts external location codes only as lookup aliases. Integrations that already store ISO 3166-2 values such as `US-CA`, Cloudflare `cf-ipcountry` + `cf-region-code`, or Google Cloud `client_region` + `client_region_subdivision` can resolve them before persisting a canonical id or preparing Partner Offer geo targeting.

External codes are not Partner Offer target ids or public Query fields. Resolve them first, then use the returned AON id only in the workflow that owns it.

## Related references

-   [Location Search API](https://docs.aon.pro/api/location-search) for interactive lookup, normalization, and ancestry data.
-   [Partner Offer Schema](https://github.com/agentoffernetwork/protocol/blob/main/v1.0/specs/offer-partner-schema.md) for the supply carrier that owns `targeting`.
-   [Offer Query API](https://docs.aon.pro/api/offer-query) for the current public Query request and its declared fields.
-   [Category Taxonomy](https://docs.aon.pro/protocol/category-taxonomy) for explicit Query category constraints.
-   [Protocol source guide](https://docs.aon.pro/protocol) for canonical source ownership.
