What is the OpenRTB transaction ID, and how do buyers use it?
Part of Supply path transparency

The short answer
The OpenRTB transaction ID, sent in source.tid, is a value that the 2.6 specification says must be common across all participants in a bid request, potentially including several exchanges. When one impression is offered through different paths, the copies can carry the same ID, so a buyer can group them, count the paths and pick the one to bid through.
Key takeaways
- source.tid is recommended, not required, in OpenRTB 2.6, and it is meant to stay the same for one opportunity across each exchange that offers it.
- The request id is different: the exchange assigns it and may use different values for different recipients, so it cannot link copies of one impression.
- A community extension adds imp.ext.tid so one request with several impressions can carry one transaction ID per impression.
- Recent Prebid.js releases changed how header bidding passes these IDs, so a missing or bidder specific tid can be a publisher setting, not a sign of trouble.
What is a transaction ID in OpenRTB?
In OpenRTB 2.6 (opens in a new tab) the transaction ID lives in the Source object, which describes the entity upstream of the exchange that is the source of the bid request. The tid attribute is a recommended string defined as a transaction ID that must be common across all participants in this bid request, with potentially multiple exchanges given as the example. The Source object itself arrived in OpenRTB 2.5, according to the 2.6 change log.
Definition
- Transaction ID (source.tid)
- An identifier for one ad opportunity that stays the same as the opportunity is offered to different exchanges and bidders, so the copies can be recognized as one transaction.
OpenRTB 3.0 (opens in a new tab) states the same idea more broadly: tid must be common across all participants throughout the entire supply chain of the transaction, and this also applies across all participating exchanges in a header bidding or similar publisher centric broadcast. The 2.x line keeps the shorter wording.
| Field | Who assigns it, per the spec | What it identifies |
|---|---|---|
| id (BidRequest) | The exchange; it may use different values for different recipients | One request from one exchange, for tracking that exchange's responses |
| imp.id | The sender; unique within the request, typically starting with 1 | One impression inside one request, so bids can reference it |
| source.tid | Not named; it must be common across all participants | The opportunity itself, across exchanges |
| imp.ext.tid (community extension) | The seller, per impression | One impression's transaction when a request carries several |
Who sets the transaction ID?
The specification defines what the value must do, not which software creates it. The Source object's purpose is described as defining post auction or upstream decisioning when the exchange itself does not control the final decision, and the spec names header bidding, another RTB exchange, a mediation platform or an ad server as examples. In practice, the value has to be created upstream of the exchanges, by whatever sends the same opportunity to several of them, or it cannot be common across them.
Prebid, the open source header bidding project, documents its own mapping in its Prebid.js 8.0 release notes (opens in a new tab). There, source.tid carries the auction ID and differs for each auction, while imp.ext.tid carries the ad unit's transaction ID and differs for each slot, and either can be set by the publisher to stay in sync with other header bidding libraries on the page. The same notes say Prebid understood from buyer platform members that source.tid is losing utility in favor of imp.ext.tid.
Why do the same impressions arrive through several paths?
One ad slot can reach a buyer more than once because the page offers it to several sellers at the same time and some of those sellers pass it on. The IAB Tech Lab Sustainability Playbook (opens in a new tab), released in June 2023, describes the result on the sell side: multiple requests for the same ad slot, and integrations that produce redundant bid requests to a given exchange for a single opportunity. It advises publishers to pick a single preferred integration path per exchange.
Each copy is legitimate on its own terms. Exchange A and Exchange B are both authorized in the site's ads.txt, and a reseller may be too. What the buyer cannot see from any single request is that the other copies exist. Without a shared identifier, a demand platform can bid against itself for one impression across three paths, and the impression it wins may carry the longest chain of fees. The supply chain object shows the hops in one copy; the transaction ID connects the copies to each other.
How does the transaction ID help buyers?
Grouped by transaction ID, bid logs answer a question no single request can: through which routes did this impression reach us, and which route did we win on? The steps below assume the buyer or its trading desk can export request level logs that include source.tid, imp.ext.tid where present, and the schain.
Find several paths to one impression from bid logs
- Pick the right key. Use imp.ext.tid for an impression when it is present, and source.tid otherwise, as the extension directs.
- Group requests by that key within a short time window. Copies of one opportunity arrive within the same auction, so a window of seconds keeps unrelated reuse of a value apart.
- List the path for each copy. Record the exchange, site.publisher.id and the schain nodes, and note DIRECT or RESELLER from the site's ads.txt.
- Mark which copy was bid on and which won. Join the group to win notices so the report shows the path the money took.
- Compare paths, not just prices. A copy with a complete chain that starts at the site owner is a different purchase from one with extra resellers, even at the same price.
- Feed the result into deal and exchange choices. Paths that repeat as the costlier copy are candidates to drop from open buying or to replace with a direct deal.
The transaction ID does not prove two requests are the same impression on its own. A value can be missing, can be bidder specific, or can cover several impressions in one request. Placement level identifiers such as the Global Placement ID answer a different question, which slot on the page, and work best read alongside the transaction ID rather than in its place.
What changed about transaction IDs in recent specs and libraries?
The OpenRTB core definition of source.tid has not moved. The openrtb2.x release history (opens in a new tab) lists nine 2.6 releases from November 2022 to OpenRTB v2.6-202606, published June 11, 2026, and none of their release notes mention tid. The changes have come from extensions and from the software that creates the value.
| Change | Source | Effect on what a buyer sees |
|---|---|---|
| Source object and tid added | OpenRTB 2.5, per the 2.6 change log | source.tid becomes the standard place for the value |
| Per impression transaction IDs | IAB Tech Lab community extension | imp.ext.tid can differ for each impression in one request |
| Transaction IDs made opt in | Prebid.js 8.0 release notes | Publishers must enable them with enableTIDs; otherwise the fields can be null |
| IDs unique for each bidder | Prebid.js setConfig docs, versions 10.9.0 to 10.13.0 | IDs cannot correlate requests from different sources, even with enableTIDs set |
| Shared IDs available again | Prebid.js setConfig docs, version 10.14.0 and later | With enableTIDs and consistentTIDs set, IDs are shared across bidders as before 10.9.0 |
Prebid's setConfig reference (opens in a new tab) explains the reasoning: these IDs let demand platforms correlate requests from different sources, which is useful but also a potential privacy concern. For a buyer, the practical result is that whether a site's copies share a transaction ID depends on the publisher's library version and settings.
What does a transaction ID review look like on a real plan?
Fictional example
A minor league baseball team reviews its ticket campaign paths
An unnamed minor league baseball team selling season and group tickets in Des Moines and Omaha runs display ads on local news, sports and family events sites in English. Its trading desk exports two weeks of bid logs for the campaign's 40 sites.
On one local sports site, requests grouped by imp.ext.tid show each slot arriving through two exchanges directly and once more through a reseller. The reseller copy is won in a share of the groups, and its schain carries an extra node. The desk keeps both direct paths and asks the reseller's exchange whether a deal could shorten the route.
On a family events site, no request carries any transaction ID, and on a news site the IDs differ for each exchange. The desk does not treat either as a problem. It asks both publishers which header bidding setup they run, notes the answers, and falls back to the domain, slot size and timestamps for those two sites.
What should buyers ask partners about transaction IDs?
Transaction ID questions for exchanges, desks and publishers
- Does the exchange pass source.tid and imp.ext.tid through unchanged, or does it generate its own?
- Does the demand platform's log export include both fields, alongside the request id and the schain?
- For header bidding sites, has the publisher enabled transaction IDs, and are they shared across bidders or unique to each?
- When a request carries several impressions, is a transaction ID sent for each one?
- Can win and loss reports be joined to requests by transaction ID?
- Is there a written policy on how long logs keeping these IDs are retained?
How does PlacementGraph help choose sites before path analysis begins?
Frequently asked questions
Is a bid request without a transaction ID invalid?
No. OpenRTB 2.6 marks source.tid as recommended, not required, and the per impression version is a community extension. A request can be valid without either. Absence does limit what a buyer can learn, since the copies of that impression cannot be grouped by ID and have to be matched by other fields.
Does the transaction ID identify the person who sees the ad?
No. The spec defines it as an identifier for the transaction. Prebid's documentation still treats sharing it as a potential privacy concern, because it lets platforms correlate requests from different sources, and data attached to those requests can then be combined downstream. That is why its sharing became a publisher choice.
Can two different impressions share a transaction ID?
Yes, within one request. Without the extension, the 2.x spec allows one transaction ID per request, so a request offering several slots carries one source.tid for all of them. The imp.ext.tid extension exists to separate them, which is why buyers should prefer it when present.
Is the transaction ID the same as a deal ID?
No. A deal ID, in the Pmp object's Deal, names what the spec calls a specific deal that was struck between a buyer and a seller, and the same deal can apply to impressions across a campaign. A transaction ID names one opportunity at one moment. A single impression can carry both: the transaction ID for the auction and the deal ID for the terms it is offered under.
Sources
- OpenRTB 2.6 specification, section 3.2.2 Source and appendix change log (opens in a new tab)IAB Tech Lab
- Per-Impression Transactions IDs for Multi-Impression Bid Requests (community extension) (opens in a new tab)IAB Tech Lab
- OpenRTB 3.0 specification, Source object (opens in a new tab)IAB Tech Lab
- openrtb2.x releases (OpenRTB v2.6-202606, June 11, 2026) (opens in a new tab)IAB Tech Lab on GitHub
- The Sustainability Playbook: Starter Guide for a Sustainable Programmatic Marketplace (June 2023) (opens in a new tab)IAB Tech Lab
- Prebid.js 8.0 release notes: transaction identifiers (opens in a new tab)Prebid.org
- pbjs.setConfig reference: enableTIDs and consistentTIDs (opens in a new tab)Prebid.org
Researched and written by PlacementGraph Research. Read how we research, source and update these pages. Corrections: diana@placementgraph.com.