Ad Serving API


Prior to implementing the Ad Serving API we recommend speaking with an implementation engineer at BuySellAds. The Ad Serving API makes the most sense when serving ads in email, integrating with an embedded template/user flow, or when you want explicit control over the data exchanged between your users and a 3rd party ad server. The majority of the "custom look and feel" ad design use cases are best served by using the Monetization Framework Custom Template feature.

Getting Started

The base URL for the serving API is HTTPS is supported by default.

The termonology we use for the identification of ad inventory is a zone. When you request ads from the ad server you are requesting them by zone. We provide a unique zone key for each unit of inventory. At the ad server level, we can then group zones into placements for ease of targeting. Most implementations identify a unit of inventory at the zone level like so:

  • Top Sidebar
  • In-content
  • Header Unit

More complicated setups might further divide the zones into specific segments for targeting. You likely do not need to get too creative with a setup like this unless you have more than 10 million pageviews a month.

  • Top Sidebar: JavaScript
  • Top Sidebar: React
  • Top Sidebar: Rust


Get Ads

This is the primary endpoint of the API that allows you to retrieve the ads to serve for the given ad request. When you make a call to this endpoint we record an impression.

For example, here is what you call if the zone key is CVADC53U. This zone key is safe to use for testing.


curl -G \
  -d useragent=Mozilla%2F5.0%20%28Macintosh%3B%20Intel%20Mac%20OS%20X%2010_15_7%29%20AppleWebKit%2F537.36%20%28KHTML%2C%20like%20Gecko%29%20Chrome%2F94.0.4606.71%20Safari%2F537.36 \
  -d forwardedip=

Required parameters

  • Name

    The browser user agent of the client that will see the ad. Make sure to encode the user agent string before you pass it into the parameter.

  • Name

    The IP address of the client that will see the ad. If you are unable to send the full IP address, please speak to a BuySellAds integration engineer for additional options.

Optional parameters

  • Name

    Set it to "yes". It's also known as test mode. You can pass this parameter if you wish to load the production ads while ignoring the impressions.

  • Name

    It allows you to specify the function name and turns it into JSONP request.


The API will return an object that contains a single ads property. The ads property is an array that contains multiple ad units as an object. Every ads property will always return an empty object at the end of the array.

The API will always return at least one object with an array containing the basic information of your zone. It returns ads to display only when the first array index contains the statlink property which is where a click on the ad is supposed to go.

Keep in mind that the properties returned in the example response below may vary depending on the zone you are requesting. Each zone has its own set of creative attributes that are determined by the creative template associated with the zone in your BuySellAds account. Below is an example response from BSA's Native Network.

Response with an ad to display

	"ads": [
			"active": "1",
			"ad_via_link": "\u0026utm_medium=ad_via_link\u0026utm_campaign=in_unit\u0026utm_term=default",
			"backgroundColor": "#000000",
			"backgroundHoverColor": "#000000",
			"bannerid": "439681",
			"callToAction": "Start a Free Trial",
			"company": "Squarespace",
			"companyTagline": "Build a Website",
			"creativeid": "492517",
			"ctaBackgroundColor": "#fafafa",
			"ctaBackgroundHoverColor": "#fafafa",
			"ctaTextColor": "#000000",
			"ctaTextColorHover": "#000000",
			"description": "Squarespace is the all-in-one solution for anyone looking to create a beautiful website.",
			"evenodd": "0",
			"external_id": "115424",
			"height": "0",
			"i": "0",
			"identifier": "219512dadd6af6def8362f5639477255",
			"image": "",
			"logo": "",
			"num_slots": "1",
			"rendering": "default",
			"statimp": "//",
			"statlink": "//",
			"textColor": "#fafafa",
			"textColorHover": "#fafafa",
			"timestamp": "1682545400",
			"width": "0",
			"zoneid": "28387",
			"zonekey": "CVADC53U"

Here is an example of a response that does not contain an ad to display:

Response without an ad to display

"ads": [
      "active": "1",
      "ad_via_link": "",
      "external_id": "9975",
      "height": "0",
      "identifier": "94f08a92522a61d78427fa18bc0db9a9",
      "noincrement": "1",
      "num_slots": "1",
      "rendering": "custom",
      "statimp": "//",
      "timestamp": "1667904860",
      "width": "0",
      "zoneid": "49975",
      "zonekey": "CEAIL27M"



Some campaigns will utilize an attribution or verification pixel. Marketers at larger companies tend to centralize reporting of marketing activity and/or have more nuanced attribution models they use to justify ad spend.

The Ad Serving API will return a the pixel value when the campaign is utilizing 3rd party attribution or verification. When the pixel value is present, it needs to be added to the page. It is possible that a marketer it utilizing more than one pixel. You will want to split the pixel value on the double pipe symbol (||) and also replace the [timestamp] string with a real timestamp like so:

function pixel(pixels, timestamp) {
	let c = ''
	if (pixels)
		pixels.split('||').forEach((pixel, index) => {
			c +=
				'<img src="' +
				pixel.replace('[timestamp]', timestamp) +
				'" style="display:none;" height="0" width="0" />'
	return c