Blog · Protocol

UID2 vs ID5 vs RampID is one OpenRTB array, and the source domain is what tells them apart.

UID2 vs ID5 vs RampID is not three columns on the bid request. OpenRTB carries extended ids in user.eids. The provider is source. A single universal-id field that stores whichever token arrived last throws away the only thing that tells a buyer which system it is.

user.id and buyeruid are the cookie pair, not these products

user.id is the exchange's own id for the user. user.buyeruid is the id that buyer holds, usually from a cookie sync, unless the two parties arranged something else. That pair depends on the match table and on the browser cookie. It is not where UID2, ID5, or a RampID is supposed to sit. Stuffing any of them into buyeruid makes one buyer's slot hold a token the exchange's sync never issued, and it strips the provider name.

user.eids is an array of EID objects. Each groups ids from one source. source is the provider's canonical domain. uids holds the id and atype, the agent type, browser versus an in-app context. Many DSPs need atype before they will resolve the value. An id with no source domain is unmatchable: the buyer cannot tell which system it belongs to. The identity guide is the object. A sample Ramp-style entry on this site uses source liveramp.com. Do not copy that domain onto a UID2 or an ID5 value.

In 2.6 the array is first-class. user.ext.eids is the old path. Buyers who read user.eids miss ids left under ext. Snapshot 2.6-202409 added inserter, matcher, and mm so a buyer can see who placed the id and how it was matched. Those fields do not exist on an older pin. A request that claims 2.6 and still only fills ext has not moved.

One array, three sources, and consent still applies

The format did not grow a field per vendor. UID2, ID5, and RampID fit the same object because each entry names its source. Sending all three means three entries, each with its own source and its own uids. Merging the raw tokens into one id string, or keeping a warehouse column called universal_id and writing that into every source, makes every provider look like the same system. The buyer will try the wrong resolver.

atype is part of the resolution. A browser id and an app id for the same provider are different agents. Omitting atype can leave an otherwise present id unused. Do not default it to 1 because a sample did. Set the agent you actually collected.

None of this overrides privacy. Whether the exchange may send the id depends on regs.gdpr and user.consent, or on regs.gpp and gpp_sid. An eid next to an unresolved consent flag is not a match you can train on. The privacy comparison is which string you owe. This page is which identity object you owe beside it.

Prebid will not copy these ids onto the other paths

A user-id module that writes user.eids on the Prebid request does not run inside TAM or Open Bidding. Those paths have their own identity or none. A RampID present on the Prebid body is not evidence the Google request carried source liveramp.com, and it is not evidence an ID5 entry existed on either. Audit eids per captured request.

buyeruid remains the cookie-sync id for that buyer on that exchange. It can be present next to eids. They answer different questions. Replacing buyeruid with a UID2 token because third-party cookies are going away removes the sync id buyers still match, and it still fails to name the UID2 source. Send the eid properly and leave buyeruid as the sync value when you have one.

Hashing an extended id because a conversion pipeline hashes email destroys the token the provider issued. eids values are already opaque. Send them as received. Do not run them through SHA-256. Do not store one column and stamp every source with it on the way out.

What to store

  • Keep each provider as its own eids entry. source is the domain that provider publishes, not a nickname.
  • Do not write those tokens into user.id or user.buyeruid.
  • Include atype. A missing agent type is how a DSP drops a valid id.
  • On 2.6, use user.eids, not user.ext.eids.
  • Do not reuse a liveramp.com source for a different provider's token.
  • Drop the id when the privacy pair on that request does not allow it.

The source has to be the provider, not the exchange

source is a domain so the buyer can pick a resolver. An exchange hostname in that field means the buyer will look up the wrong system. A missing source means the buyer cannot look up any system. UID2, ID5, and a RampID can all be present on one request only as separate entries. One entry with three ids jammed into a single string is one broken source, not three products.

atype tells the DSP whether the id was collected in a browser or in an app. Copying atype from a web sample onto an in-app request resolves the id in the wrong agent. inserter, matcher, and mm, when the snapshot includes them, say who added the id and how. They do not replace source. Leave them off rather than inventing a match method you did not perform.

Further reading