Skip to main content

TMP for Web Publishers

Web publishers typically run an ad server (GAM, Kevel, FreeWheel) that manages line items, targeting rules, and ad selection. TMP integrates with this infrastructure through a Prebid module — it tells the ad server which deals to activate, it does not replace the ad server.

How It Works Today

A publisher running Prebid with AdCP deals has packages defined through create_media_buy. To activate them, the publisher manually creates corresponding line items or PMP deals in their ad server. A vendor-specific RTD module injects targeting signals by sending the full OpenRTB BidRequest to the vendor’s API. This works but requires per-vendor integration and sends unnecessary data. TMP replaces vendor-specific RTD modules with a single Prebid module that speaks a standard protocol. Buyer agents evaluate context and identity separately, and the publisher joins the results locally before passing instructions to GAM.

Context Match

When a page loads, the TMP Prebid module sends a Context Match request to the router. The request includes the page context. No package list is sent — the provider uses its synced package set for this placement.

Context Match Request

{
  "type": "context_match_request",
  "request_id": "ctx-7f2a-oakwood-91b3",
  "property_rid": "01916f3a-9c4e-7000-8000-000000000010",
  "property_id": "oakwood-publishing-main",
  "property_type": "website",
  "placement_id": "article-sidebar-300x250",
  "artifact_refs": [
    { "type": "url", "value": "https://oakwood.example.com/sustainable-kitchen-2026-03" }
  ]
}
Key points:
  • No package list is sent per request. The provider evaluates all eligible packages for this placement using its synced package set from media buy setup. The same packages are evaluated for every user, preventing identity leakage into the context path and enabling response caching.
  • artifact_refs references content by type and value. The buyer agent resolves artifact metadata from its cache — no inline signals needed on the request.

Context Match Response

The router fans out to each buyer agent and merges the responses. Each buyer returns offers for packages whose targeting matched the content context, plus response-level signals that flow through to GAM as key-values.
{
  "type": "context_match_response",
  "request_id": "ctx-7f2a-oakwood-91b3",
  "offers": [
    { "package_id": "pkg-display-0041" },
    { "package_id": "pkg-native-0078" }
  ],
  "signals": {
    "segments": ["sustainability", "home_cooking"],
    "targeting_kvs": [
      { "key": "adcp_seg", "value": "sustainability" },
      { "key": "adcp_seg", "value": "home_cooking" },
      { "key": "adcp_pkg", "value": "pkg-display-0041" },
      { "key": "adcp_pkg", "value": "pkg-native-0078" }
    ]
  }
}
Key points:
  • offers contains one entry per activated package. The provider’s synced set for this placement included three packages — these two matched the kitchen/sustainability context, the third (pkg-display-0103) did not and is absent.
  • For web/GAM activation, offers are simple — just package_id. Richer fields (brand, price, summary, creative_manifest, macros) are available for integrations that need them but are not required.
  • signals.targeting_kvs are the key-value pairs that the Prebid module sets on the GAM ad request. GAM line items are configured to match on these keys.

Identity Match

Separately, the TMP Prebid module sends an Identity Match request with the user’s opaque token. This request carries no page context. The package_ids list includes ALL active packages for the buyer — not just the packages on this page.

Identity Match Request

{
  "type": "identity_match_request",
  "request_id": "id-3k9p-oakwood-d4f1",
  "user_token": "tok_uid2_8f2a3b7c",
  "uid_type": "uid2",
  "package_ids": [
    "pkg-display-0041",
    "pkg-display-0042",
    "pkg-display-0043",
    "pkg-native-0078",
    "pkg-native-0079",
    "pkg-display-0103",
    "pkg-display-0104",
    "pkg-video-0201"
  ]
}
Key points:
  • request_id is unrelated to the context match request_id. The two must not be derivable from each other.
  • package_ids includes ALL active packages for the buyer across the entire site, not just the three that were on this placement’s context match. Sending only the page-specific subset would let the buyer correlate identity with context by comparing package sets.
  • user_token is opaque. It comes from an identity provider (UID2, ID5, LiveRamp) or is publisher-generated. The buyer cannot reverse it to PII.

Identity Match Response

The buyer evaluates the user against all requested packages and returns the IDs of eligible packages, plus a TTL defining how long the router can cache this response.
{
  "type": "identity_match_response",
  "request_id": "id-3k9p-oakwood-d4f1",
  "eligible_package_ids": [
    "pkg-display-0041",
    "pkg-display-0042",
    "pkg-native-0078",
    "pkg-native-0079",
    "pkg-display-0104"
  ],
  "ttl_sec": 60
}
Key points:
  • Only eligible packages are listed. Packages absent from the list (e.g., pkg-display-0043, pkg-display-0103, pkg-video-0201) are ineligible. The buyer computes eligibility from frequency caps, audience membership, purchase history, and any other identity-based signals. The reasons are opaque to the publisher.
  • ttl_sec tells the router how long to cache this response. During that window, the router returns cached eligibility without re-querying the buyer. The publisher uses cached eligibility to allocate across all placements on the page.
  • There is no frequency_capped, audience_match, or recency field. The buyer’s internal reasons stay with the buyer.

Activation: Joining Context and Identity

The publisher joins context match and identity match locally. This is where the two halves come together — the router never sees both at the same time.

Step 1: Intersect

Take the offers from context match and filter by identity match eligibility.
PackageContext MatchIdentity MatchResult
pkg-display-0041OfferedEligibleActivate
pkg-native-0078OfferedEligibleActivate
pkg-display-0103Not offeredNot eligibleSkip
Only two packages survive: pkg-display-0041 and pkg-native-0078.

Step 2: Set GAM Targeting

The Prebid module takes the context match signals.targeting_kvs and sets them on the GAM ad request as key-value pairs:
adcp_seg = sustainability, home_cooking
adcp_pkg = pkg-display-0041, pkg-native-0078
GAM line items are pre-configured to target on adcp_pkg values. When the ad request arrives with adcp_pkg=pkg-display-0041, GAM matches it to the corresponding line item and serves the creative.

Step 3: GAM Selects

GAM applies its own priority rules, competitive exclusions, and pacing logic across all eligible line items — including both TMP-activated deals and other demand sources. TMP does not override GAM’s ad selection; it provides the inputs.

GAM Line Item Configuration

For each active package, the publisher creates a GAM line item targeting adcp_pkg = <package_id>. This is the link between TMP activation and GAM ad selection.
  • Line item type. Sponsorship or Standard, depending on deal terms from create_media_buy. Guaranteed deals use Sponsorship; non-guaranteed deals use Standard.
  • Priority. Set based on deal type. Guaranteed deals at priority 4-8, non-guaranteed at priority 12-16. This determines how TMP demand competes with other line items in GAM’s selection logic.
  • Creative assignment. Reference pre-synced creatives from sync_creatives, or use the creative manifest from the Context Match response if the buyer provides one.
  • Lifecycle. When a media buy ends or is cancelled, deactivate the corresponding line item. The router stops including the package in Identity Match within 1 hour.
  • Automation. Publishers can automate line item creation by listening for new create_media_buy completions and mapping package details to GAM API calls. The package ID, deal type, priority, and creative references are all available from the media buy response.

Prebid Integration

The TMP Prebid module is a Real-Time Data (RTD) module that replaces vendor-specific RTD modules. It is defined by the TMP Prebid proposal and follows the standard Prebid RTD module interface. It handles the full flow:
  1. On auction init: Send Context Match request to the TMP router for each placement on the page.
  2. On context match response: Store offers and targeting signals.
  3. After temporal delay (100-2000ms, randomized): Send Identity Match request with the user’s opaque token and ALL active package IDs for each buyer.
  4. On identity match response: Join with context match results. Set targeting key-values on the ad unit.
  5. On bid request: GAM receives the enriched ad request with TMP targeting keys and selects line items as normal.
The temporal delay between context and identity requests is a privacy measure. It prevents timing-based correlation of the two request types.

Sequence Diagram

Page Load
  |
  |-- Prebid TMP Module ---> TMP Router (Context)
  |                              |-- fan out --> Buyer Agent A
  |                              |-- fan out --> Buyer Agent B
  |                              |<- merge <--- offers + signals
  |<--- Context Match Response --
  |
  |   (100-2000ms random delay)
  |
  |-- Prebid TMP Module ---> TMP Router (Identity)
  |                              |-- fan out --> Buyer Agent A
  |                              |-- fan out --> Buyer Agent B
  |                              |<- merge <--- eligibility
  |<--- Identity Match Response --
  |
  |-- Join locally: intersect offers with eligibility
  |-- Set targeting KVs on GAM ad request
  |-- GAM selects and serves ad

Coexistence with OpenRTB

Most publishers run TMP alongside Prebid header bidding, which sources demand via OpenRTB. The two systems are complementary.
  • TMP as additional demand. TMP packages appear as line items in GAM, competing with Prebid line items on priority and price. GAM handles the yield decision — TMP does not replace Prebid, it adds pre-negotiated demand.
  • Competitive exclusion. Configure GAM competitive exclusion rules to prevent conflicting brands from appearing together across TMP and Prebid demand sources.
  • Revenue attribution. TMP-activated impressions are tracked via get_media_buy_delivery, while Prebid impressions flow through existing SSP reporting. Publishers reconcile in their BI layer.
  • Timeout independence. TMP and Prebid requests run in parallel. TMP timeout (50ms) is typically faster than Prebid timeout (1000-1500ms), so TMP results are ready before GAM needs them.

Privacy Constraints for Web

These constraints apply to all surfaces but are worth restating for the web case:
  • Context match carries no user data. No cookies, no user tokens, no IP addresses. The provider evaluates the same synced package set for every user on a placement.
  • Identity match carries no page data. No URLs, no content signals, no placement IDs. The package_ids list includes all active packages for the buyer, not just the ones on this page.
  • The publisher joins locally. The router never sees both context and identity for the same impression. Only the publisher, who already has both the page context and the user identity, performs the intersection.
  • Temporal decorrelation. A random delay between the two requests prevents timing-based correlation at the network level.