RTB Architecture
Prebid.js Guide: Events, Bidder Adapters, Releases and Debugging
Published · Last updated
Next scheduled review:
Prebid.js is the open-source JavaScript library that runs header bidding auctions in the browser. Release 11.47.0, published on 4 November 2026, contains 535 bid adapters that you compile in as modules (GitHub). This guide covers the parts engineers touch every week: the event API, how bidder adapters are built, the release cycle, and debugging.
Key terms on this page: Prebid.js · header bidding · bidder adapter · Prebid Server · ad server · timeout · TCF
Contents
Key facts
- Current release. Prebid.js 11.47.0 shipped on 4 November 2026; major version 11.0.0 shipped on 12 March 2026 and 10.0.0 on 1 July 2025 (GitHub releases, accessed 9 November 2026).
- It ships constantly. The repository published 59 releases between 1 January and 9 November 2026, including patches to the 10.x line such as 10.29.2 on 6 October 2026 (GitHub releases).
- Hundreds of modules. At tag 11.47.0 the
modulesfolder holds 535 bid adapters (56 of them in TypeScript), 67 analytics adapters, 67 user ID modules and 71 real-time data providers, by our count (Prebid.js 11.47.0 modules). - Thirty events.
src/constants.tsat 11.47.0 defines 30 event names that pages and modules can listen to (constants.ts). - Builds need a current Node.js. The 11.47.0
package.jsonrequires Node.js 24.14.1 or newer (package.json).
Definition
Prebid.js: a modular, Apache-2.0 JavaScript library, maintained by Prebid.org, that requests bids from several demand partners in parallel inside a web page. It passes the results to the publisher's ad server, or renders the winner itself (Prebid.org, getting started, accessed 9 November 2026).
How header bidding works, why wrappers exist, and how to set timeouts are covered in header bidding explained. This page assumes that background and goes into the engineering surface of the library.
Where the Prebid.js documentation lives
Prebid's documentation is large and spread across sections. This map points each common task to the right page.
9 of 9 rows
First integration | |
Every | |
Bidder codes and parameters | |
Build a custom file | Download builder or |
Write a bid adapter | |
Write an analytics adapter | |
Connect to Prebid Server | |
Upgrade to 11.x | |
Fix a broken page |
First integration
- Official page
Every pbjs.* function
- Official page
Bidder codes and parameters
- Official page
Build a custom file
- Official page
Download builder or
gulp build --modules=...
Write a bid adapter
- Official page
Write an analytics adapter
- Official page
Connect to Prebid Server
- Official page
Upgrade to 11.x
- Official page
Fix a broken page
- Official page
Table by AdSovereign, CC BY 4.0.
Two caveats. Prebid's "Important Prebid.js Releases" page stops at version 8.0, so use the per-version release notes and GitHub instead. And the source code is the final word: event names, for example, are defined in src/constants.ts.
Prebid.js events: the full list
Prebid.js emits an event at each step of an auction. Pages and modules subscribe with pbjs.onEvent(eventType, handler, id) and unsubscribe with pbjs.offEvent. Calling pbjs.getEvents() returns a copy of every event since page load, each with eventType, args, id and elapsedTime (onEvent docs; getEvents docs, both accessed 9 November 2026).
25 of 25 rows
Start |
|
|
Start |
| Bids are about to be requested; handlers can adjust the ad units |
Start |
| The auction has started |
Bidding |
| A bid request was created for one bidder |
Bidding |
| A bidder's network request is about to be sent |
Bidding |
| Defined in |
Bidding |
| A bid passed checks and is about to join the auction (removed in 11.0, restored in 11.7) |
Bidding |
| A bid's price was adjusted |
Bidding |
| A bid response was added to the auction |
Bidding |
| A bid was rejected |
Bidding |
| A bidder returned no bid (used in Prebid's own logging example) |
Bidding |
| A bidder's request failed; carries |
Bidding |
| A bidder signalled it has finished responding |
Close |
| The auction hit its timeout; fires before |
Close |
| Lists the bids that timed out |
Close |
| The auction has ended |
Close |
| Ad server targeting was set |
Render |
| A Prebid bid won; the only event that accepts an |
Render |
| The render call raised no error; it does not prove tracking fired |
Render |
| Rendering failed; carries |
Render |
| The browser intervened in a creative, for example a heavy-ad unload |
Server side |
| Prebid Server returned extra analytics data such as seat non-bids |
Privacy |
| TCF enforcement blocked storage, bidders or analytics |
Diagnostics |
| An error was logged to the console |
Other names in |
| Emitted by specific modules or features; see each module's page |
Start
- Event
requestBids- Fires when
pbjs.requestBids()was called; carries the ad units and codes
Start
- Event
beforeRequestBids- Fires when
Bids are about to be requested; handlers can adjust the ad units
Start
- Event
auctionInit- Fires when
The auction has started
Bidding
- Event
bidRequested- Fires when
A bid request was created for one bidder
Bidding
- Event
beforeBidderHttp- Fires when
A bidder's network request is about to be sent
Bidding
- Event
beforePBSHttp- Fires when
Defined in
constants.ts; description n/d in the events table
Bidding
- Event
bidAccepted- Fires when
A bid passed checks and is about to join the auction (removed in 11.0, restored in 11.7)
Bidding
- Event
bidAdjustment- Fires when
A bid's price was adjusted
Bidding
- Event
bidResponse- Fires when
A bid response was added to the auction
Bidding
- Event
bidRejected- Fires when
A bid was rejected
Bidding
- Event
noBid- Fires when
A bidder returned no bid (used in Prebid's own logging example)
Bidding
- Event
bidderError- Fires when
A bidder's request failed; carries
{ error, bidderRequest }
Bidding
- Event
bidderDone- Fires when
A bidder signalled it has finished responding
Close
- Event
auctionTimeout- Fires when
The auction hit its timeout; fires before
bidTimeoutandauctionEnd
Close
- Event
bidTimeout- Fires when
Lists the bids that timed out
Close
- Event
auctionEnd- Fires when
The auction has ended
Close
- Event
setTargeting- Fires when
Ad server targeting was set
Render
- Event
bidWon- Fires when
A Prebid bid won; the only event that accepts an
id(the ad unit code)
Render
- Event
adRenderSucceeded- Fires when
The render call raised no error; it does not prove tracking fired
Render
- Event
adRenderFailed- Fires when
Rendering failed; carries
reasonandmessage
Render
- Event
browserIntervention- Fires when
The browser intervened in a creative, for example a heavy-ad unload
Server side
- Event
pbsAnalytics- Fires when
Prebid Server returned extra analytics data such as seat non-bids
Privacy
- Event
tcf2Enforcement- Fires when
TCF enforcement blocked storage, bidders or analytics
Diagnostics
- Event
auctionDebug- Fires when
An error was logged to the console
Other names in constants.ts
- Event
bidViewable,staleRender,expiredRender,billableEvent,browsiInit,browsiData- Fires when
Emitted by specific modules or features; see each module's page
Table by AdSovereign, CC BY 4.0.
Sources: getEvents, onEvent, Prebid's troubleshooting guide for noBid, and constants.ts at 11.47.0. Version 11.0 removed addAdUnits and seatNonBid; listeners on those names now never fire (Prebid.js 11.0 notes).
Using pbjs.onEvent: three snippets
Register handlers inside pbjs.que so they run once Prebid.js has loaded, and before requestBids, so no event is missed. The property names below, such as timeToRespond, bidderCode and auctionId, are the ones Prebid's own troubleshooting examples use.
Log each bidder's latency and outcome:
window.pbjs = window.pbjs || { que: [] };
pbjs.que.push(function () {
pbjs.onEvent('bidResponse', function (bid) {
console.log('[bid]', bid.bidderCode, bid.adUnitCode, bid.cpm, bid.timeToRespond + 'ms');
});
pbjs.onEvent('noBid', function (bid) {
console.log('[no bid]', bid.bidder, bid.adUnitCode);
});
pbjs.onEvent('bidTimeout', function (timedOut) {
const bidders = Array.from(new Set(timedOut.map(function (b) { return b.bidder; })));
console.log('[timeout]', bidders.join(', '));
});
});Act once on a single ad unit, then stop listening. The id argument limits a bidWon handler to one ad unit code (offEvent docs).
window.pbjs = window.pbjs || { que: [] };
const TOP_SLOT = 'div-gpt-top';
function onTopSlotWin(bid) {
console.log('Top slot won by', bid.bidderCode, 'at', bid.cpm);
pbjs.offEvent('bidWon', onTopSlotWin, TOP_SLOT);
}
pbjs.que.push(function () {
pbjs.onEvent('bidWon', onTopSlotWin, TOP_SLOT);
});Send render failures to your own endpoint, which Prebid lists as a use for adRenderFailed and auctionDebug. The URL is a placeholder.
window.pbjs = window.pbjs || { que: [] };
pbjs.que.push(function () {
pbjs.onEvent('adRenderFailed', function (data) {
navigator.sendBeacon('https://logs.example.com/prebid', JSON.stringify({
type: 'adRenderFailed',
reason: data.reason,
message: data.message
}));
});
});For production analytics, prefer an analytics adapter over hand-written listeners. Adapters register through pbjs.enableAnalytics, can sample with options.sampling, and can include or exclude events by name (enableAnalytics docs). Server-side outcomes reach the browser through the pbsAnalytics event; the server half is covered in Prebid Server analytics and debugging.
Prebid.js bidders: the list and how to choose
The Prebid.js bidders page lists every bidder code with its parameters and declared features. Prebid's downloadable data marks 733 entries as client-side adapters, including aliases (bidder-data.csv, last modified 3 November 2026). The repository counts files instead: 535 *BidAdapter files at tag 11.47.0 and 537 on the master branch on 7 November 2026. Some files serve several bidder codes as aliases, so a code you need may live in another company's file; the README tells you to search the repository when that happens (Prebid.js README).
You compile in only the adapters you use. From a clone, after npm ci, run gulp build --modules=openxBidAdapter,rubiconBidAdapter,sovrnBidAdapter, or pass a JSON file with the list. The README also shows npm install prebid.js with ES module imports for teams that bundle Prebid.js into their own build (README).
[
"rubiconBidAdapter",
"ixBidAdapter",
"pubmaticBidAdapter",
"prebidServerBidAdapter",
"consentManagementTcf",
"priceFloors"
]Save that list as modules.json and build with gulp build --modules=modules.json. Each bidder you add is another network call from the reader's browser. Moving some bidders to Prebid Server trades those calls for user matching, as explained in header bidding vs server-side bidding and Prebid Server cookie sync.
How a Prebid.js bidder adapter is built
A bid adapter is a module that registers a spec object with registerBidder. Prebid's guide lists the functions the spec provides (bidder adaptor guide, accessed 9 November 2026).
5 of 5 rows
| Yes | Reject ad units with missing or bad parameters |
| Yes | Return the server requests for Prebid.js to send |
| Yes | Turn the response into bid objects |
| No | Register image or iframe syncs |
| No | Callbacks for those moments |
isBidRequestValid(bid)
- Required
Yes
- Job
Reject ad units with missing or bad parameters
buildRequests(validBidRequests, bidderRequest)
- Required
Yes
- Job
Return the server requests for Prebid.js to send
interpretResponse(serverResponse, request)
- Required
Yes
- Job
Turn the response into bid objects
getUserSyncs(syncOptions, serverResponses, gdprConsent, uspConsent, gppConsent)
- Required
No
- Job
Register image or iframe syncs
onTimeout, onBidWon, onBidBillable, onSetTargeting, onBidderError
- Required
No
- Job
Callbacks for those moments
Table by AdSovereign, CC BY 4.0.
Here is a minimal adapter for an imaginary bidder, written as an ES module. It sends one POST per auction and maps OpenRTB-style bids back.
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { BANNER } from '../src/mediaTypes.js';
const ENDPOINT = 'https://bid.example.com/prebid';
export const spec = {
code: 'examplebidder',
gvlid: 9999,
supportedMediaTypes: [BANNER],
isBidRequestValid: (bid) => Boolean(bid.params && bid.params.placementId),
buildRequests: (validBidRequests, bidderRequest) => ({
method: 'POST',
url: ENDPOINT,
data: {
id: bidderRequest.bidderRequestId,
imps: validBidRequests.map((b) => ({ id: b.bidId, placementId: b.params.placementId, sizes: b.mediaTypes.banner.sizes }))
}
}),
interpretResponse: (serverResponse) => ((serverResponse.body && serverResponse.body.bids) || []).map((b) => ({
requestId: b.impId,
cpm: b.price,
currency: 'USD',
width: b.w,
height: b.h,
ad: b.adm,
ttl: 300,
creativeId: b.crid,
netRevenue: true,
meta: { advertiserDomains: b.adomain || [] }
}))
};
registerBidder(spec);The rules matter as much as the code. Adapters may not load external code, may not fire network requests or pixels outside buildRequests and getUserSyncs, and may not touch ad slots directly. Each submission needs the adapter file, a markdown file with a maintainer email and test parameters, unit tests, and a docs pull request (bidder adaptor guide). Since 11.0, Prebid prefers TypeScript for new modules (Prebid.js 11.0 notes). For OpenRTB back ends, Prebid's ORTB converter library implements most of buildRequests and interpretResponse for you.
A Prebid.js adapter does not run in Prebid Server. The server needs its own adapter, built in Go first, as described in Prebid Server bidder adapters.
Prebid.js releases and upgrades
9 of 9 rows
9.0.0 | 13 Jun 2024 | Previous major line |
10.0.0 | 1 Jul 2025 | Major release; the 10.x line still receives patches |
10.29.2 | 6 Oct 2026 | Patch on the 10.x line |
11.0.0 | 12 Mar 2026 | Removed PAAPI, adpod and several modules; stricter media types; strict |
11.7.0 | 20 Apr 2026 | Restored the |
11.9.0 | 29 Apr 2026 | User syncs stop in Firefox and Chrome on iOS, as in Safari |
11.20.0 | 24 Jun 2026 | The Prebid Server adapter also skips |
11.29.0 | 6 Aug 2026 | Debug mode also loads the DevTools MCP module |
11.47.0 | 4 Nov 2026 | Latest release on 9 November 2026 |
9.0.0
- Date
13 Jun 2024
- What to know
Previous major line
10.0.0
- Date
1 Jul 2025
- What to know
Major release; the 10.x line still receives patches
10.29.2
- Date
6 Oct 2026
- What to know
Patch on the 10.x line
11.0.0
- Date
12 Mar 2026
- What to know
Removed PAAPI, adpod and several modules; stricter media types; strict
storageControl
11.7.0
- Date
20 Apr 2026
- What to know
Restored the
bidAcceptedevent
11.9.0
- Date
29 Apr 2026
- What to know
User syncs stop in Firefox and Chrome on iOS, as in Safari
11.20.0
- Date
24 Jun 2026
- What to know
The Prebid Server adapter also skips
cookie_syncin those browsers
11.29.0
- Date
6 Aug 2026
- What to know
Debug mode also loads the DevTools MCP module
11.47.0
- Date
4 Nov 2026
- What to know
Latest release on 9 November 2026
Table by AdSovereign, CC BY 4.0.
Sources: GitHub releases for dates, Prebid.js 11.0 notes, setConfig user sync docs and the troubleshooting guide, all accessed 9 November 2026.
Upgrading within a major line is usually routine, but read the notes for the adapters you use, because almost every release changes some of them. A major upgrade needs a test plan. Version 11.0 rejects bids whose media type is not in the ad unit, unless you set auctionOptions.rejectInvalidMediaTypes to false. It also makes the storageControl module fail undisclosed storage use instead of warning, and it removes the customSlotMatching argument of setTargetingForGPTAsync (Prebid.js 11.0 notes).
Pin what you ship. In September 2025, GitHub published an advisory that the Prebid.js npm package had been briefly compromised in version 10.9.2, fixed in 10.10.0 (GHSA-jwq7-6j4r-2f92). Build from a locked dependency tree, review version bumps, and host the built file yourself.
How to debug Prebid.js
Add pbjs_debug=true to the page URL. Prebid.js then stops hiding its JavaScript errors and logs each step, such as "Calling bidder" and "Set key value for placement", to the console (troubleshooting guide). The same effect comes from pbjs.setConfig({ debug: true }). When the page also uses Prebid Server, debug mode makes the server adapter send ext.prebid.debug: true, so the server response carries its own debug data (Prebid Server troubleshooting).
Then work through the console:
pbjs.versionto confirm the release you think you shipped.pbjs.installedModulesto confirm which modules the build contains.pbjs.getConfig()to check timeouts, price granularity, consent ands2sConfig.pbjs.getEvents()to replay the event history, includingbidTimeoutandbidderError.pbjs.getBidResponses()to see each bid by ad unit, withtimeToRespond.pbjs.getAdserverTargeting()to see the key-values sent to the ad server.pbjs.getAllWinningBids()to see which Prebid bids rendered.
To test line items without waiting for real demand, the debugging module can intercept bids and return fixed responses.
pbjs.setConfig({
debugging: {
enabled: true,
intercept: [
{
when: { adUnitCode: 'div-gpt-top', bidder: 'rubicon' },
then: { cpm: 10 }
}
]
}
});This setting persists in the browser's session storage, so turn it off with enabled: false when you finish (debugging module docs). The same module can ask Prebid Server for a stored auction response by ID; Prebid notes that this path currently works only with the Java build of Prebid Server.
Common mistakes
- Registering handlers after
requestBids. Early events such asauctionInitare already gone. Usepbjs.queand register first. - Listening for removed events.
addAdUnitsandseatNonBidno longer fire in 11.x; useauctionInitandpbsAnalytics. - Treating
adRenderSucceededas an impression. Prebid says it only means the render call raised no error. - Shipping the full build. The standard build contains every module. Build with
--modulesso readers download only what you use. - Leaving the debugging module on. Its session-storage setting outlives the page you tested.
- Expecting user syncs in Safari. Since 11.9 and 11.20, Prebid.js fires no syncs, including Prebid Server's, in Safari or in Firefox and Chrome on iOS.
- Floating dependency versions. The 10.9.2 incident shows why a lockfile and a reviewed upgrade matter.
Where to go next
- Prebid vs Open Bidding vs Amazon TAM: how the three demand paths differ.
- Managed wrappers built on Prebid: PubMatic OpenWrap and Magnite Prebid Server.
- The server leg: the Prebid Server self-hosting guide, Prebid Server stored requests, the AWS and Docker reference setup and Prebid Server Go vs Java.
- Running the server yourself instead of renting it: the self-hosted Prebid Server profile.
- Why owning the stack matters: the publisher independence hub.
FAQ
What is Prebid.js?
What are Prebid.js events?
auctionInit, bidResponse, bidTimeout and bidWon. You listen with pbjs.onEvent, stop with pbjs.offEvent and read the history with pbjs.getEvents (getEvents docs).How many bidders does Prebid.js support?
Where is the Prebid.js documentation?
How often is Prebid.js released?
How do I debug Prebid.js?
?pbjs_debug=true to the page URL, then use pbjs.getEvents(), pbjs.getBidResponses() and pbjs.getAdserverTargeting() in the console. Use the debugging module to inject test bids (troubleshooting guide).How this works on owned infrastructure
Prebid.js already runs in your reader's browser; the open question is where its events, bids and server-side calls end up. If the s2sConfig endpoint and the analytics endpoint belong to a vendor, the event stream described above becomes the vendor's data. AdSovereign gives those calls a destination you operate: the Prebid Server endpoint, the event collector and the store behind them run in your own environment, so bidWon, bidTimeout and pbsAnalytics records feed your reporting directly. The use cases page shows how publishers use that data, and the pilot page describes pointing an existing Prebid.js setup at it.
Sources
- GitHub, prebid/Prebid.js releases, including 9.0.0 (13 June 2024), 10.0.0 (1 July 2025), 11.0.0 (12 March 2026), 11.7.0, 11.9.0, 11.20.0, 11.29.0, 10.29.2 and 11.47.0 (4 November 2026). https://github.com/prebid/Prebid.js/releases
- GitHub, prebid/Prebid.js at tag 11.47.0:
src/constants.ts,package.json,modules/(accessed 9 November 2026). https://github.com/prebid/Prebid.js/tree/11.47.0 - GitHub, prebid/Prebid.js README (master, accessed 9 November 2026). https://github.com/prebid/Prebid.js
- Prebid.org, "pbjs.onEvent", "pbjs.offEvent", "pbjs.getEvents", "pbjs.enableAnalytics" (accessed 9 November 2026). https://docs.prebid.org/dev-docs/publisher-api-reference/getEvents.html
- Prebid.org, "How to Add a New Prebid.js Bidder Adapter" (accessed 9 November 2026). https://docs.prebid.org/dev-docs/bidder-adaptor.html
- Prebid.org, "Prebid.js 11.0 Release Notes and Publisher API Changes" (accessed 9 November 2026). https://docs.prebid.org/dev-docs/pb11-notes.html
- Prebid.org, "Troubleshooting Prebid.js" (accessed 9 November 2026). https://docs.prebid.org/troubleshooting/troubleshooting-guide.html
- Prebid.org, "Module: Debugging" (accessed 9 November 2026). https://docs.prebid.org/dev-docs/modules/debugging.html
- Prebid.org, "pbjs.setConfig: Configure User Syncing" (accessed 9 November 2026). https://docs.prebid.org/dev-docs/publisher-api-reference/setConfig.html
- Prebid.org, "Prebid.js Bidders" and "bidder-data.csv" (CSV last modified 3 November 2026). https://docs.prebid.org/dev-docs/bidders.html
More sources (2)
- Prebid.org, "Prebid Server Troubleshooting" (accessed 9 November 2026). https://docs.prebid.org/troubleshooting/pbs-troubleshooting.html
- GitHub Security Advisory GHSA-jwq7-6j4r-2f92 (CVE-2025-59038), "Prebid.js NPM package briefly compromised in v10.9.2" (9 September 2025). https://github.com/prebid/Prebid.js/security/advisories/GHSA-jwq7-6j4r-2f92