Aller au contenu principal
API & Targeting

Google Ad Manager Key-Values:
The Definitive Guide to Limits & API

Key-values are the backbone of custom targeting in Google Ad Manager. An overlong key, a reserved character or a badly entered value is enough to break a targeting setup.

OA
OrbiAds Engineering
Published May 30, 2026 · Updated Sep 30, 2026 · 7 min read

The short answer

A GAM key-value is a key=value pair sent in the ad request (through GPT) and targeted on your line items. Per Google's Help Center: 40 characters maximum per value, 20 per key (the SOAP reference says 10, so keep your keys under 10 characters), 200 active keys and 100,000 active values per key per network. Each targeted pair counts as 1 of the 800 criteria on a line item. Keys and values are not case-sensitive, and a key cannot contain spaces.

Understanding the Types: Predefined vs Dynamic (Free-form)

The console talks about "predefined" and "dynamic" keys; the SOAP API exposes the same choice in CustomTargetingKey.type with the values PREDEFINED and FREEFORM. The choice decides how values are declared and which match types are available:

  • Predefined: you define the values in advance (console or createCustomTargetingValues) and traffickers pick them from a list. Example: gender=female,male,other. Best when the range of values is known and stable. A key with no defined values cannot serve.
  • Dynamic (FREEFORM): you define the key, but values come from the ad tag and are entered at targeting time. Example: pageid=123456. Useful for numerous or changing values. Match types (BROAD, PREFIX…) only apply to dynamic keys, and the API restricts them to Ad Manager 360 networks.

The Limits You Need to Know

Figures come from the Google Ad Manager Help Center article "System maximums and limits". Your network may have exceptions: check Admin > Global settings > Limits.

Names & Values
  • Key: 20 characters max (Help Center). The SOAP reference for CustomTargetingKey.name says 10: stay at 10 or fewer for API-created keys. Value: 40 characters max.
  • Reserved characters: " ' = ! + # * ~ ; ^ ( ) < > [ ] , &. The asterisk and tilde are used for dynamic-key match types.
  • Keys and values are not case-sensitive: Val = val. A key cannot contain spaces or start with a number; a value can contain spaces (wrapped in double quotes in the tag).
  • Values are strings: age>=18 is not evaluated, write age=18-34 instead.
Volume & Targeting
  • 200 active keys per network, 100,000 active values per key, 2,500,000 active values per network.
  • 800 targeting criteria per line item; each key-value pair counts as one. Native style targeting is limited to 20 pairs.
  • 30,000 reportable key-values; 20,000 for custom dimensions (5,000 without Ad Manager 360).
  • API quota: too many requests per second triggers QuotaError.EXCEEDED_QUOTA (see below).

Recommended Naming Convention

The name is what travels in the ad request URL; the displayName is only seen by your traffickers. A stable convention prevents duplicates and typing errors:

  • Short lowercase names, no spaces, snake_case if needed: pos, section, prodcat. Aim for 10 characters or fewer for keys.
  • One dimension per key: do not pack several facts into one value (sports-atf). Two keys give you two targeting criteria you can combine.
  • Put meaning in the display name: key pos, display name "Ad position". Same for values: a short name and a readable display name.
  • Ranges as text: 18-34, no comparison operators. Keep values stable over time, without uppercase or reserved characters.
  • No personal data: Google prohibits passing personally identifiable information (PII); never use a user identifier as a value.
  • Prefix by source when several systems write keys (hb_ for Prebid) so they never collide with your editorial keys.

Recommended Key-Values by Inventory Type

Common starting points by business model. Adapt the names to your convention; all stay under 10 characters.

Inventory TypeKey-ValueAPI TypeUsage
Editorial / Media / NewssectionPREDEFINEDTarget by section (e.g. sports, politics, tech).
artidFREEFORMArticle ID: precise exclusions or targeted sponsored content.
E-Commerce / ClassifiedsprodcatPREDEFINEDProduct category (e.g. shoes, laptops).
price_bandPREDEFINEDPrice segment (e.g. low, mid, premium).
Universal / Apps / PositionposPREDEFINEDSlot position (e.g. atf above the fold, btf below the fold).
consentPREDEFINEDConsent state passed by your CMP (e.g. 1 or 0). A state, never a user identifier.
Header Bidding / Programmatichb_pbFREEFORMPrebid price bucket (e.g. 1.20, 4.50) targeted by header bidding line items.
hb_bidderFREEFORMWinning bidder name (e.g. rubicon, appnexus).

Creating Key-Values with the OrbiAds MCP Server

No need to go through the GAM console to create keys and values: the OrbiAds MCP server exposes these writes to your AI agents through the targeting tool. Every write defaults to dry-run: you review the preview, then confirm.

Step 1: Create the targeting key

# In Claude: OrbiAds MCP server (dry_run by default)
targeting(
  action="create_custom_targeting_key",
  params={
    "name": "pos",
    "displayName": "Ad position",
    "keyType": "PREDEFINED",
    "reportableType": "ON",
    "dryRun": True
  }
)

Step 2: Add values to the key (required for a PREDEFINED key):

# The key ID is returned by step 1
targeting(
  action="create_custom_targeting_values",
  params={
    "keyId": "12984572",
    "values": [
      {"name": "atf", "displayName": "Above the fold"},
      {"name": "btf", "displayName": "Below the fold"}
    ],
    "dryRun": True
  }
)

Targeting Explorer: Check What Already Exists

For logged-in users, OrbiAds provides an exploration view of your key-values in the admin area:

Targeting Explorer
Go to tool

Review existing keys and values before creating anything: it prevents duplicates (pos and position) and typos in values.

Integration Code: From the SOAP API to the GPT Tag

Here is how to create a key and its values server-side with the official googleads Python library, then pass those key-values in the browser with Google Publisher Tag (GPT).

1. Creating Key-Values in Python (SOAP API)

from googleads import ad_manager

# Credentials are read from googleads.yaml
client = ad_manager.AdManagerClient.LoadFromStorage()
service = client.GetService('CustomTargetingService', version='v202608')

# Predefined, reportable key (name: 10 characters max)
keys = service.createCustomTargetingKeys([{
    'name': 'pos',
    'displayName': "Ad position",
    'type': 'PREDEFINED',
    'reportableType': 'ON',
}])
key_id = keys[0]['id']

# Values: matchType must be EXACT on a predefined key
values = service.createCustomTargetingValues([
    {'customTargetingKeyId': key_id, 'name': 'atf',
     'displayName': "Above the fold", 'matchType': 'EXACT'},
    {'customTargetingKeyId': key_id, 'name': 'btf',
     'displayName': "Below the fold", 'matchType': 'EXACT'},
])

# Read back: the customTargetingKeyId filter is mandatory
statement = (ad_manager.StatementBuilder(version='v202608')
             .Where('customTargetingKeyId = :keyId')
             .WithBindVariable('keyId', key_id))
response = service.getCustomTargetingValuesByStatement(statement.ToStatement())
for value in response.get('results', []):
    print(value['id'], value['name'])

2. Client-side targeting (JavaScript GPT)

Once the key-values exist, the tag must send them with exactly the same names. Targeting set on a slot overrides page-level targeting. setTargeting() is now deprecated in GPT in favour of setConfig() with the targeting option.

window.googletag = window.googletag || { cmd: [] };
googletag.cmd.push(function () {
  // Page-level targeting (all slots)
  googletag.setConfig({ targeting: { section: 'tech', consent: '1' } });

  // Slot-level targeting (several values possible with an array)
  googletag
    .defineSlot('/1234/site/banner', [300, 250], 'div-gpt-ad')
    .addService(googletag.pubads())
    .setConfig({ targeting: { pos: 'atf' } });

  googletag.enableServices();
  googletag.display('div-gpt-ad');
});

QA Checklist Before You Push Line Items

  • Key name: 10 characters or fewer, no spaces, no reserved characters, does not start with a number.
  • Values: 40 characters max, ranges written as text (18-34), no personal data.
  • Type chosen up front: predefined if you know the values, dynamic otherwise. In OrbiAds, a key's type cannot be changed after creation.
  • Values defined for every predefined key: a key with no values cannot serve.
  • Reporting decided before launch: a key only shows in reports from the moment it becomes reportable.
  • Tag verified: the names sent by GPT exactly match those in GAM; the name appears in the ad request URL, so you can check it there.
  • Criteria budget: fewer than 800 criteria per line item, each key-value pair counting as one.
  • Dry-run reviewed through MCP before confirming, and a first test on a low-traffic order.

Common Mistakes

  • Overlong key or value, reserved character: the API returns CustomTargetingError.KEY_NAME_INVALID_LENGTH or VALUE_NAME_INVALID_LENGTH, and KEY_NAME_INVALID_CHARS or VALUE_NAME_INVALID_CHARS for disallowed characters.
  • Non-exact match type: values of a predefined key must be EXACT, and only Ad Manager 360 networks accept another matchType (VALUE_MATCH_TYPE_NOT_ALLOWED, VALUE_MATCH_TYPE_NOT_EXACT_FOR_PREDEFINED_KEY). SUFFIX and CONTAINS are rejected in line item targeting.
  • Confusing name and display name: the name is what travels in the tag. Typing the display name into an advanced expression matches nothing.
  • Turning reporting on too late: reports covering dates before activation show nothing for that key.
  • API quota: on QuotaError.EXCEEDED_QUOTA, Google recommends waiting about 5 seconds before retrying (and increasing the wait if it keeps failing), or limiting requests to 2 per second (8 on Ad Manager 360).

Frequently asked questions about GAM key-values

What is the character limit for Google Ad Manager key-values?

The Help Center lists 20 characters per key and 40 per value. The SOAP reference for CustomTargetingKey.name says 10 characters though, so for keys created through the API stay at 10 or fewer. Keys and values are not case-sensitive, and the characters " ' = ! + # * ~ ; ^ ( ) < > [ ] , & are reserved.

How many key-values can a line item target?

Each key-value pair counts as one targeting criterion, and a line item supports up to 800 criteria (inventory, geography, day/time and key-values combined). The 20 pairs you may have read about apply only to native style targeting.

What is the difference between predefined and dynamic (FREEFORM in the API) key-values?

Predefined keys have values you define in advance and traffickers pick from a list. Dynamic keys take values sent by the ad tag, with no prior definition. In the SOAP API the field CustomTargetingKey.type is PREDEFINED or FREEFORM. Match types (BROAD, PREFIX and so on) only apply to dynamic keys.

Do key-values show up in reports?

Only keys marked reportable (reportableType ON or CUSTOM_DIMENSION) are included, and only from the moment they become reportable: reports covering earlier dates show nothing. Undefined values do not appear even if the key is reportable. Limits: 30,000 reportable key-values, 20,000 for custom dimensions (Ad Manager 360).

Can I create GAM key-values from an AI agent or script?

Yes. With the OrbiAds MCP server, an agent calls the targeting tool with the action create_custom_targeting_key to declare a key, then create_custom_targeting_values to add values. Writes default to dry-run, so you review the preview before anything executes. In a script, use createCustomTargetingKeys and createCustomTargetingValues from the SOAP API.

Sources

Google Ad Manager Help Center: "System maximums and limits", "Valid key-value entry", "Predefined and dynamic key-values", "Names versus display names". SOAP API reference CustomTargetingService (v202608), types CustomTargetingKey and CustomTargetingValue. Google Publisher Tag reference: setConfig and the targeting option.

Automate Your Targeting Setup

The OrbiAds MCP server lets an AI agent audit your existing keys and create new ones with a preview before anything is written.