Skip to content
PubAdHub

OpenRTB 2.5

Publisher API 2.5

PubAdHub accepts OpenRTB 2.5 bid requests from publishers, supply partners, header bidding, and ad servers. Send one HTTP POST for each auction to http://rtb.pubadhub.com/openrtb/{PublisherKey}. When an ad is available, the response is a bid in US dollars plus a click URL. When no ad is available, the response is HTTP 204 with an empty body. The publisher key in the URL is your Publisher Identity. Use POST only. A GET request is not accepted as a bid request.

Base URL http://rtb.pubadhub.com
POST /openrtb/{PublisherKey}
warning

price is earnings per click, not CPM

OpenRTB 2.5 defines bid.price as CPM. This endpoint does not. price is USD earnings per click. Do not multiply or divide by 1000. HTTP 204 with an empty body is a no-bid, not an error.
lock

Authentication

There is no API token and no Authorization header. The {PublisherKey} path segment is your Publisher Identity. Your Account Manager provides it. It may contain letters, numbers, underscores, and hyphens, and it must be 1 to 64 characters. Replace YOUR_PUBLISHER_KEY in examples and do not leave the braces in the live URL. Keep it in your server configuration, and do not publish it on a web page. This path value is not the PublisherKey header used by product search, and it is not an AccessKey.

Headers

Send these request headers. Every response includes x-openrtb-version: 2.5. Read the HTTP status before you read the body. A 204 response has no body and no Content-Type.

Content-Type REQUIRED

application/json

Request header. The body is an OpenRTB 2.5 bid request.

Accept

application/json

Optional request header.

Request fields

Send these OpenRTB fields on the bid request. A valid call needs id, imp, and imp.id, plus an advertiser domain or a keyword. A request with neither a domain nor a keyword is HTTP 204. Deeplink URLs are read from ext.deeplink on the impression, site, app, or bid request, and from imp.native.ext.url. Only the first impression is bid.

{PublisherKey}
string Yes

Location: path

Your Publisher Identity, provided by your Account Manager. Letters, numbers, underscores, and hyphens only. 1 to 64 characters.

Example: YOUR_PUBLISHER_KEY

id
string Yes

Location: body

Your auction id. It is returned on the bid response.

Example: auction-123

imp
array Yes

Location: body

One or more impressions. Only the first is bid on. A single impression object is accepted and is treated as the first impression.

Example: [{"id":"1"}]

imp.id
string Yes

Location: body

Impression id. It is returned as bid.impid.

Example: 1

site.domain or app.domain
string One of these

Location: body

Brand domain, for example brand.com. A full URL is accepted and the host is used. Send a domain or a keyword. Missing both is HTTP 204.

Example: advertiser.example

site.page
string No

Location: body

Page where the ad runs. Not an advertiser domain and not a deeplink. When no deeplink is sent, this page is used as ext.final_url when it is present.

imp.bidfloorcur
string Recommended

Location: body

Floor currency. USD is accepted. Any other currency is HTTP 204. If omitted, USD is used.

Example: USD

site.search or user.keywords
string One of these

Location: body

User search keyword. When a keyword is present, price is the keyword bid. Send a domain or a keyword. Missing both is HTTP 204.

Example: running shoes

device.geo.country
string Recommended

Location: body

Send US or USA. You may place the country in user.geo.country instead. Any other country receives no bid. If the country is omitted, the request is treated as US.

Example: US

device.ua
string Recommended

Location: body

End-user browser user agent.

Example: Mozilla/5.0

device.ip
string Recommended

Location: body

End-user IPv4 address. Send an IPv6 address in device.ipv6. A valid IPv4 address is appended to the click URL as an integer.

Example: 8.8.8.8

device.ipv6
string Recommended

Location: body

End-user IPv6 address. Send this when device.ip is omitted. Both addresses are accepted. IPv6 is not added to the click URL.

Example: 2001:db8::1

imp.bidfloor
number Recommended

Location: body

Your floor, in the same USD earnings-per-click unit as price. A positive floor above the bid is HTTP 204. A bid equal to the floor can be returned.

Example: 0.10

imp.tagid
string Recommended

Location: body

Your placement or traffic-source id. When sent, it is appended to the click URL as subi.

Example: placement-1

site.publisher.id
string Recommended

Location: body

Your own id for this request. When it is present, it is used as clickid on the click URL.

user.id
string Recommended

Location: body

Used as clickid on the click URL only when site.publisher.id is empty or omitted.

Example: click-123

user.buyeruid
string No

Location: body

Your user id. It is appended to the click URL as uid when sent.

Example: user-456

site.ref
string Recommended

Location: body

Referrer URL where the ad opportunity occurred.

Example: https://publisher.example/

ext.deeplink
string No

Location: body

Deeplink URL on the impression, site, app, or bid request. imp.native.ext.url is also accepted. Omit it for a homepage bid. When a deeplink is sent and that advertiser has no verified deeplink campaign, the response is HTTP 204.

test
integer No

Location: body

Set to 1 only for an integration test. A bid that still clears the auction is returned with price 0, and the click URL includes tsts=1. A test flag does not turn a no-bid into a fill. Do not send this in live traffic.

Example: 1

API format

API Format
http://rtb.pubadhub.com/openrtb/{PublisherKey}

Request example

POST /openrtb/YOUR_PUBLISHER_KEY HTTP/1.1
Host: rtb.pubadhub.com
Content-Type: application/json

{
  "id": "auction-123",
  "imp": [{
    "id": "1",
    "bidfloor": 0.10,
    "bidfloorcur": "USD",
    "tagid": "placement-1"
  }],
  "site": {
    "domain": "advertiser.example",
    "ref": "https://publisher.example/",
    "search": "running shoes"
  },
  "device": {
    "ua": "Mozilla/5.0",
    "ip": "8.8.8.8",
    "ipv6": "2001:db8::1",
    "geo": { "country": "US" }
  },
  "user": {
    "id": "click-123",
    "buyeruid": "user-456"
  }
}

Response

Content-Type is application/json. x-openrtb-version is 2.5. The body is one BidResponse for the first impression only. id matches the request id. impid matches imp[0].id. bidid and bid.id are the same id. Sample seat, price, hosts, ENCRYPTED, BRAND-ID, and the UUID are placeholders. Each live response uses a new UUID. adomain, advertiser_name, and final_url can be empty. altered is false unless the request set imp.native.ext.alt. lurl is omitted because this endpoint does not send it. If HTTP 200 is not valid JSON, or id does not match the request, discard the response. This endpoint does not return a partial bid object.

JSON
{
    "id": "auction-123",
    "bidid": "7c1e4b2a-9f08-4d6e-a1b3-2e5f8c0d4a61",
    "cur": "USD",
    "seatbid": [
        {
            "seat": "YOUR_SEAT_OR_PUBLISHER_KEY",
            "bid": [
                {
                    "id": "7c1e4b2a-9f08-4d6e-a1b3-2e5f8c0d4a61",
                    "impid": "1",
                    "price": 0.2,
                    "adomain": [
                        "advertiser.example"
                    ],
                    "adm": "{\"native\":{\"link\":{\"url\":\"https://click.example/track?encyp=ENCRYPTED&rtuli=9f3c2a1b0e8d7c6a5b4f3e2d1c0b9a87&clickid=click-123\"}}}",
                    "ext": {
                        "altered": false,
                        "final_url": "https://advertiser.example/",
                        "advertiser_name": "advertiser.example",
                        "advertiser_id": "BRAND-ID"
                    }
                }
            ]
        }
    ]
}

adm is a string, not an object. Parse that string as JSON. Every fill uses this shape, including when the bid request did not contain imp.native. There is no native version and there are no assets. native.link.url is the click redirect. The host in this example is a placeholder. The live URL is the click tracker configured for the integration.

JSON
{
    "native": {
        "link": {
            "url": "https://click.example/track?encyp=ENCRYPTED&rtuli=9f3c2a1b0e8d7c6a5b4f3e2d1c0b9a87&clickid=click-123"
        }
    }
}

Empty body. x-openrtb-version is 2.5. There is no Content-Type and there is no JSON. Do not parse a body. This endpoint does not use HTTP 200 with an empty body, an empty seatbid array, or a no-bid reason field. HTTP 204 is returned when the country is not the United States (US and USA are accepted; an omitted country is treated as US); the request has no advertiser domain and no keyword; the Publisher Identity is not enabled for this endpoint; no advertiser matches the domain or keyword; the advertiser is blocked for this publisher or country; no homepage or deeplink campaign is available; a cap is already met, or the current hour is outside the allowed hours; a deeplink was sent and that advertiser has no verified deeplink campaign; or imp.bidfloorcur is not USD, or the bid is below a positive imp.bidfloor. HTTP 204 is a normal result. It is not an error. Do not retry the same auction in a loop.

The Publisher Identity is missing, contains characters other than letters, numbers, underscores, and hyphens, or is longer than 64 characters. The JSON error is "Invalid publisher key". Fix the request before you retry. Do not treat HTTP 400 as a no-bid.

JSON
{
    "error": "Invalid publisher key"
}

The body is not JSON, id is missing or blank, or the first impression has no id. A single impression object is accepted and is treated as the first impression. Fix the request before you retry. Do not treat HTTP 400 as a no-bid.

JSON
{
    "error": "Invalid OpenRTB bid request"
}

Response fields

A fill is HTTP 200 for imp[0] only. The tables in the PDF separate the OpenRTB 2.5 rule from what this endpoint sends. Extension fields are specific to this integration. This response does not send nbr, custom data, a response-level ext, seatbid[].group, lurl, campaign id, creative id, width, height, or deal id. price is USD earnings per click, rounded to 4 decimal places. JSON numbers drop trailing zeros, so 0.2000 is returned as 0.2. When the request includes a keyword, price is the keyword bid. A test request that still clears the floor is returned with price 0.

id string

Copied from the bid request id. OpenRTB requires it. Use it to match the response to your auction.

Example: auction-123

bidid string

A new UUID for this response. The same value is sent as seatbid[0].bid[0].id. OpenRTB marks bidid optional.

Example: 7c1e4b2a-9f08-4d6e-a1b3-2e5f8c0d4a61

cur string

Always USD. OpenRTB treats cur as optional and uses USD when it is omitted.

Example: USD

seatbid array

One seat object. That seat contains one bid. OpenRTB requires seatbid when a bid is made.

Example: [{...}]

seatbid[].bid array

One bid, for imp[0] only. Additional impressions in the same request are not bid on. OpenRTB requires this array.

Example: [{...}]

seatbid[].seat string

Buyer seat id. When a seat id has been assigned, that value is sent. Otherwise your Publisher Identity from the URL is sent. OpenRTB marks seat optional.

Example: YOUR_SEAT_OR_PUBLISHER_KEY

seatbid[].bid[].id string

Bidder-generated bid id. Same UUID as the top-level bidid. OpenRTB requires it.

Example: 7c1e4b2a-9f08-4d6e-a1b3-2e5f8c0d4a61

seatbid[].bid[].impid string

The imp.id of the impression that received the bid. This endpoint bids on imp[0]. OpenRTB requires it.

Example: 1

seatbid[].bid[].price float

Earnings per click in USD, not CPM. Do not multiply or divide by 1000. Rounded to 4 decimal places. imp.bidfloor is compared in this same unit. A positive floor above the bid is HTTP 204. A bid equal to the floor can be returned. A non-USD imp.bidfloorcur is HTTP 204. If bidfloorcur is omitted, USD is used.

Example: 0.2

seatbid[].bid[].adm string

Always sent on a fill. Ad markup as a JSON string. Parse it, then use native.link.url on a real user click. Do not call that URL from the bid server. OpenRTB marks adm optional.

Example: {"native":{"link":{"url":"https://click.example/track?encyp=ENCRYPTED&rtuli=9f3c2a1b0e8d7c6a5b4f3e2d1c0b9a87&clickid=click-123"}}}

seatbid[].bid[].adomain array of strings

Advertiser host from site.domain or app.domain. One host, or an empty array when the advertiser was chosen from a keyword and no domain was sent. OpenRTB marks adomain optional.

Example: ["advertiser.example"]

seatbid[].bid[].lurl string

Optional loss-notice URL in OpenRTB 2.5. This endpoint does not send lurl.

Example: Not sent

seatbid[].bid[].ext.final_url string

Extension, sent on every fill. Absolute URL. A deeplink is used when one was sent. Otherwise site.page is used when it was sent. Otherwise the advertiser domain is used. A value without http:// or https:// is prefixed with https:// and a trailing slash. The string can be empty.

Example: https://advertiser.example/

seatbid[].bid[].ext.altered boolean

Extension, sent on every fill. true only when imp.native.ext.alt is 1 or true, in any letter case. Otherwise false, including when imp.native is absent. This echoes the request flag. It does not mean the bidder changed the landing URL.

Example: false

seatbid[].bid[].ext.advertiser_name string

Extension, sent on every fill. Advertiser host. Same host as the single adomain entry. Empty string when no domain was on the request.

Example: advertiser.example

seatbid[].bid[].ext.advertiser_id string

Extension, sent on every fill. Internal advertiser id for the brand that was bid.

Example: BRAND-ID

Click URL

The click URL is native.link.url inside the adm string. It is an absolute URL on the click tracker for this integration. Redirect the end user to that URL when the ad is clicked. Do not prefetch it, and do not call it from your bid server. Opening it outside a real user click can record a click. You may store the bid for the life of that auction only. Do not reuse a click URL on a later auction. Nothing on this URL is an OpenRTB macro, and nothing is substituted after the response is sent. The OpenRTB request id and the bid id are not query parameters. rtuli ties the click to the logged bid.

native.link.url

native.link.url
https://click.example/track?encyp=ENCRYPTED&rtuli=9f3c2a1b0e8d7c6a5b4f3e2d1c0b9a87&clickid=click-123

Redirect URL parameters

Values are appended only when they exist. The sample answers a request that sent user.id click-123 and no site.publisher.id, so clickid is user.id.

encyp
Always

Opaque encrypted value. It contains the Publisher Identity, advertiser id, bid amount, and a typo id of 0.

Example: ENCRYPTED

rtuli
Always

Internal request id for this auction. The click tracker uses it to associate the click with the logged bid. It is not the OpenRTB request id and it is not bid.id.

Example: 9f3c2a1b0e8d7c6a5b4f3e2d1c0b9a87

clickid
When site.publisher.id or user.id was sent

site.publisher.id when that value is present. Otherwise user.id.

Example: click-123

uid
When user.buyeruid was sent

Your user id.

Example: user-456

dl
When the bid is a deeplink

The deeplink URL from the bid request.

subi
When imp.tagid was sent

Your placement id.

Example: placement-1

ip
When device.ip is a valid IPv4 address

That address as an integer.

pli
When the campaign has a platform id

Platform id for the campaign.

cc
Always on a fill

Country used for the auction. This endpoint bids US only.

Example: US

tsts
When test is 1

Marks the click URL as a test. The value is 1.

Example: 1

Errors

Invalid Publisher Identity

Invalid publisher key

JSON
{
    "error": "Invalid publisher key"
}

Invalid bid request

Invalid OpenRTB bid request

JSON
{
    "error": "Invalid OpenRTB bid request"
}

Notes

info
Build one OpenRTB 2.5 bid request for one impression and POST it to http://rtb.pubadhub.com/openrtb/YOUR_PUBLISHER_KEY with Content-Type: application/json. PubAdHub validates the Publisher Identity, id, and imp, runs the auction, and returns HTTP 200 or HTTP 204.
info
On HTTP 200, match id to your request and impid to imp[0].id. Read price as USD earnings per click. Parse adm and use native.link.url only on a real user click. On HTTP 204, continue with your normal no-fill handling and do not parse JSON. On HTTP 400, log the error and do not retry the same call unchanged.
info
Ads are available for the United States only. Send device.geo.country as US or USA. user.geo.country is used when the device country is empty. GB, GBR, and every other country receive HTTP 204. If you omit the country, PubAdHub treats the request as US.
info
cur is USD. price and imp.bidfloor are earnings-per-click amounts in USD, not CPM. A non-USD floor currency is HTTP 204. A bid below a positive floor is HTTP 204. The below-floor amount is not included in a BidResponse.
info
Add "test": 1 only while you are integrating. The flag is applied only after the bid has passed the floor and the rest of the auction. price is then 0, and the click URL includes tsts=1. If the auction would have been a no-bid, the test flag does not create a fill. Remove test before you send live traffic.
info
Response checks for this endpoint: id is copied from the bid request; impid copies imp[0].id; cur is USD and price is EPC rounded to 4 decimal places; adm parses to native.link.url; rtuli is always on the click URL; clickid is site.publisher.id when that value was sent, otherwise user.id; ext.final_url, ext.altered, ext.advertiser_name, and ext.advertiser_id are always present and can be empty where noted; altered is true only when imp.native.ext.alt is 1 or true; lurl is not sent; id, bidid, impid, cur, seat, adm, and the extension strings are strings; price is a number; altered is a boolean; adomain is an array of strings; seatbid and bid are arrays.
info
tmax is not read. Timeout handling is not verified in this endpoint. Agree the time limit with your integration contact.
info
Before you go live: Publisher Identity received from your Account Manager; POST URL set to http://rtb.pubadhub.com/openrtb/YOUR_PUBLISHER_KEY; Content-Type: application/json is sent; the body includes id, imp.id, and an advertiser domain or a keyword; device.ua, device.ip or device.ipv6, device.geo.country, imp.tagid, site.publisher.id or user.id, and site.ref are populated with live values; HTTP 200 parsing reads id, impid, price, cur, adm, and ext, then parses native.link.url; price is handled as USD EPC, not CPM; HTTP 204 is handled as no-fill with no JSON parse; HTTP 400 is logged and is not retried unchanged; the end user is redirected to native.link.url only on a real click; a deeplink is sent in ext.deeplink or imp.native.ext.url only when you have a landing URL; the seat value you expect is confirmed (assigned seat id, or your Publisher Identity); test is omitted from production requests; a live test covered one fill, one no-bid, and one invalid request.
info
Questions about your Publisher Identity, enabled brands, or floors should be sent to your PubAdHub Account Manager.

Original PDF

This page is sourced from the official API PDF. The original file remains available.

PubAdHub OpenRTB 2.5 Publisher Integration.pdf

Related documentation

play_circle

Try it out

Fill the fields below, copy the generated cURL, or send a live request.

POST http://rtb.pubadhub.com/openrtb/{PublisherKey}
cURL

        
Response Status: