Training
Learning path
Implement finance and operations apps - Training
Plan and design your project methodology to successfully implement finance and operations apps with FastTrack services, data management and more.
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
This page describes how to integrate a bidder with Xandr. It begins with an overview of the different "layers" of the integration, and ends with a worked example (using actual API calls) of a simple integration that will get you up and running quickly in our testing environment. It also provides links to more detailed information elsewhere on our Wiki.
Note
Bidding Protocol
Xandr currently supports the OpenRTB 2.4 bidding protocol. For more info check out our Bidding Protocol page.
At a high level, there are two "layers" of the system we need to be concerned with during bidder setup:
Real-Time Layer (RTB): This is the heart of the action, where your bidder will participate in the real-time auction.
Our server receives a bid request from a webpage (or SSP partner), and format it to prepare to send to our bidders.
Using the settings in the bidder instance (and your bidder object), we send the request along to your servers.
Configuration Layer (API): This is where you will configure your bidder's "business logic" so it can bid on impressions; in other words, filtering out unwanted impressions, and setting up users, adding the creatives your members want to serve, etc.
It is important to understand how our platform objects relate to one another. Below is an outline of our object hierarchy.
Traditionally, bidders can act on behalf of themselves, or they can have several 3rd-party members.
Members must have at least one user, regardless of whether the member acts on behalf of a third party (for more details, see the User Service).
The bidder, as a technology provider, also has at least one user.
The users for bidders adjust the bidder profile, add bidder instances, etc.
Member users upload creatives for that member, etc.
Even if the bidder is the same corporation as a member, and the bidder only acts on behalf of itself, the bidder is logically distinct from the member in the same fashion.
In this section we'll walk through the entire process of setting up a bidder on the platform. We'll begin by making the API calls necessary to hook up the pipes.
Tip
APIs
Most client testing is done in our production APIs. We also have a testing environment API which allows for testing of your object creation and updating workflows.
Most of the examples calls below are done in the production API environment.
Before we can do anything else, we have to log in. Below is an example of the authentication json you can use. The authentication process for our production and testing environment is the same. The only difference is the endpoint.
Tip
For more detailed information about authenticating via our API, see the Authentication Service.
$ cat auth.json
{
"auth":
{
"username" : "rloveland",
"password" : "AppNexus1!"
}
}
Post to the production API to authenticate:
$ export IB="https://api.adnxs.com";
$ curl -b cookies -c cookies -X POST -d @auth.json $IB/auth
{ response": { "status": "OK", ... } }
Similarly, post to the test environment to authenticate:
$ export IB_TESTING="https://api-test.adnxs.com";
$ curl -b cookies -c cookies -X POST -d @auth.json $IB_TESTING/auth
{ response": { "status": "OK", ... } }
The bidder object represents your bidder in our system. As such, it has a lot of fields that you can use to configure how your bidder interacts with our platform. Think of it as the central "hook" on which you'll hang much of the rest of your configuration. A bidder object should already have been created for you by your Xandr representative.
In the example below, we make a GET
call to view the bidder object, but we don't explain any of its details. For more detailed information about the bidder object, see the Bidder Service.
$ export IB="https://api.adnxs.com";
$ curl -b cookies $IB/bidder/123
{
"response": {
"bidder": {
"active": true,
"always_send_owned_segments": true,
"audit_notify_uri": null,
"bid_percent": 100,
"bid_uri": "/xandr/bid",
"child_profiles": null,
"click_uri": null,
"daily_budget": null,
"daily_budget_imps": null,
"default_currency": "USD",
"default_member": {
"id": 9876,
"name": "Example Bidder's Default Member Name"
},
"dongle": null,
"exclude_unowned": false,
"id": 123,
"last_activity": "2021-02-03 19:47:25",
"lifetime_budget": null,
"lifetime_budget_imps": null,
"max_allowed_profiles": 5,
"max_seats": 10000,
"name": "ExampleBidder",
"notify_full_auction": false,
"notify_uri": null,
"num_conns": 3,
"object_limit_notify_email": null,
"parent_profile_id": null,
"pixel_uri": null,
"protocol_id": 10,
"protocol_name": "openrtb2",
"ready_uri": "/status/ready",
"send_class_2": true,
"send_class_3": true,
"send_owned_blocklist": false,
"send_public_deals": false,
"send_unaudited": true,
"setuid_function": null,
"short_name": "examplebidder",
"supports_deal_buyers": "seats",
"userdata_entity_id": null,
"userdata_javascript": null,
"vendor_id": null
},
"count": 1,
"dbg": {
"output_term": "bidder",
"version": "1.0.5",
"warnings": [
]
},
"num_elements": 100,
"start_element": 0,
"status": "OK"
}
}
For the following fields of the "Bidder" object, IP Address/Hostname should not be included preceding the path.
IP Address will be configured separately on the "Bidder Instance" object(s) in the next step of the integration process.
Field | Required | Description |
---|---|---|
bid_uri | the path/filename that specifies the destination for Bid Requests (e.g. "/bidder") | |
ready_uri | the path/filename that specifies the destination for Ready Requests (e.g. "/ready") | |
notify_uri | the path/filename that specifies the destination for Notify Requests (e.g. "/notify") | |
pixel_uri | optional | the path/filename that specifies the destination |
click_uri | optional | the path/filename that specifies the destination for Click Requests |
audit_notify_uri | optional | the path/filename that specifies the destination for Audit Notify Requests (For example, "https://examplebidder.com/audit_notify_endpoint") |
You need to have at least one member that buys through your bidder. You should have had a member created for you by your Xandr representative as part of the onboarding process. The member is where you will configure much of the "business logic" such as user segments, creatives, etc.
Tip
In the example below, we make a GET
call to view the member object, but we don't explain any of its details. Some of the fields which are displayed to you may be deprecated. For more detailed information about the member object, including which fields are currently supporting, see the Member Service.
$ export IB="https://api.adnxs.com";
$ curl -b $IB/member/1234
{
"response": {
"count": 1,
"dbg": {
"output_term": "member",
"version": "1.18.1651",
"warnings": [
]
},
"member": {
"account_owner_user": {
"first_name": "Peter",
"id": 123456,
"last_name": "Driver"
},
"active": true,
"active_contract": null,
"age_segment_id": null,
"agent_id": null,
"allow_ad_profile_override": true,
"allow_priority_audit": false,
"audit_notify_email": null,
"bidder_id": 1234,
"billing_address_1": null,
"billing_address_2": null,
"billing_city": null,
"billing_country": null,
"billing_name": "ExampleMemberName",
"billing_postal_code": null,
"billing_region": null,
"buyer_clearing_fee_pct": null,
"buyer_credit_limit": 2500,
"code": null,
"contact_email": null,
"contact_info": null,
"contracts": null,
"curation_deductions_allowed": false,
"daily_imps_self_audited": null,
"daily_imps_unaudited": null,
"daily_imps_verified": null,
"deal_visibility_profile_id": null,
"default_accept_data_provider_usersync": true,
"default_accept_demand_partner_usersync": true,
"default_accept_supply_partner_usersync": true,
"default_ad_profile_id": null,
"default_buyer_group_id": null,
"default_content_retrieval_timeout_ms": 0,
"default_creatives": null,
"default_enable_for_mediation": false,
"default_external_audit": false,
"default_tag_id": null,
"description": null,
"developer_id": null,
"domain_blocklist_email": null,
"dongle": null,
"email_code": null,
"enable_click_and_imp_trackers": false,
"enable_facebook": false,
"expose_eap_ecp_placement_settings": false,
"gender_segment_id": null,
"id": 1234,
"is_iash_compliant": false,
"last_activity": "2020-03-19 06:00:39",
"max_hosted_video_size": null,
"native_custom_keys": null,
"platform_exposure": "public",
"plugins_enabled": false,
"pops_enabled_UI": false,
"price_buckets": null,
"prioritize_margin": false,
"reporting_decimal_type": "decimal",
"seller_member_groups": null,
"seller_revshare_pct": null,
"serving_domain": null,
"sherlock_notify_email": null,
"short_name": null,
"tax_region_id": null,
"thirdparty_pixels": null,
"timezone": "EST5EDT",
"vendor_id": null,
"visibility_profile_id": null,
"xd_coop": false
},
"num_elements": 100,
"start_element": 0,
"status": "OK"
}
}
In this step, we'll go through the options in the bidder profile that helps shape the traffic you receive. The bidder profile can be updated using both the API and our bidder UI. The main documentation for these are found here:
In the example below, the targeting breaks down like this:
$ cat create-bidder-profile-json
{
"bidder_profile": {
"active": true,
"bidder_id": 1234,
"description": "Example Bidder Profile",
"targeting": {
"ad_types": {
"audio": {
"action": "exclude"
},
"banner": {
"action": "include",
"sizes": [
]
},
"native": {
"action": "exclude"
},
"video": {
"action": "exclude"
}
},
"countries": {
"action": "include",
"targets": [
{
"active": true,
"code": "US",
"id": 233,
"name": "United States"
}
]
},
"exchanges": {
"action": "exclude",
"targets": [
{
"id": 2,
"name": "Connect"
},
{
"id": 3,
"name": "Network"
}
]
},
"supply_types": {
"action": "include",
"targets": [
"web"
]
}
},
"unknown_users_action": "include"
}
}
In this step, we'll add a creative. After we upload this creative, you will need to set up your bidder to respond to a Bid Request with a properly formatted Bid Response. The bid response should include this creative, either in the "crid"
field, corresponding to your internal ID for the creative, or the "adid"
, which is the Xandr ID for the creative. This will test that your integration is working as expected.
Tip
For more detailed information about the many types of creative configurations, see the Creative Service.
For some tips on getting your creative set up, see our Quick Start Creative Buying Guide.
Note
Statuses
"allow_audit"
and "allow_ssl_audit"
fields have each been set to true
."allow_audit"
field submits the creative for our platform human audit."allow_ssl_audit"
submits the creative for our automated scan to determine if the creative can serve on secure inventory.$ cat add-creative.json
{
"creative": {
"width": 682,
"height": 488,
"landing_page_url": "https://en.wikipedia.org/wiki/Car",
"content": "document.write('<a href=\\\"https://en.wikipedia.org/wiki/Car\\\" target=\\\"_blank\\\">\\r\\n <img src=\\\"https://upload.wikimedia.org/wikipedia/commons/3/3e/SteamMachineOfVerbiestIn1678.jpg\\\" />\\r\\n</a>')",
"content_secure": "document.write('<a href=\\\"https://en.wikipedia.org/wiki/Car\\\" target=\\\"_blank\\\">\\r\\n <img src=\\\"https://upload.wikimedia.org/wikipedia/commons/3/3e/SteamMachineOfVerbiestIn1678.jpg\\\" />\\r\\n</a>')",
"template": {
"id": 6
},
"original_content": "<a href=\"https://en.wikipedia.org/wiki/Car\" target=\"_blank\">\r\n <img src=\"https://upload.wikimedia.org/wikipedia/commons/3/3e/SteamMachineOfVerbiestIn1678.jpg\" />\r\n</a>",
"original_content_secure": "<a href=\"https://en.wikipedia.org/wiki/Car\" target=\"_blank\">\r\n <img src=\"https://upload.wikimedia.org/wikipedia/commons/3/3e/SteamMachineOfVerbiestIn1678.jpg\" />\r\n</a>",
"click_action": "click-to-web",
"click_target": "https://en.wikipedia.org/wiki/Car",
"click_url": "https://en.wikipedia.org/wiki/Car",
"allow_ssl_audit": true,
"allow_audit": true
}
}
$ export IB="https://api.adnxs.com";
$ curl -b cookies -X POST -d @add-creative.json $IB/creative/1234
{
"response": {
"count": 1,
"creative": {
"active": true,
"added_by_bidder": null,
"adservers": null,
"adx_audit": null,
"allow_audit": true,
"allow_ssl_audit": true,
"audit_feedback": null,
"audit_status": "pending",
"backup_upload_status": nul
"brand": {
"category_id": 0,
"id": 1,
"name": "Unknown"
},
"brand_id": 1,
"campaign": null,
"categories": null,
"click_action": "click-to-web",
"click_target": "https://en.wikipedia.org/wiki/Car",
"click_url": "https://en.wikipedia.org/wiki/Car",
"code": null,
"code2": null,
"content": "document.write('<a href=\\\"https://en.wikipedia.org/wiki/Car\\\" target=\\\"_blank\\\">\\r\\n <img src=\\\"https://upload.wikimedia.org/wikipedia/commons/3/3e/SteamMachineOfVerbiestIn1678.jpg\\\" />\\r\\n</a>')",
"content_secure": "document.write('<a href=\\\"https://en.wikipedia.org/wiki/Car\\\" target=\\\"_blank\\\">\\r\\n <img src=\\\"https://upload.wikimedia.org/wikipedia/commons/3/3e/SteamMachineOfVerbiestIn1678.jpg\\\" />\\r\\n</a>')",
"content_source": "standard",
"created_on": "2021-02-05 21:56:47",
"custom_request_template": null,
"description": null,
"facebook_audit_feedback": null,
"facebook_audit_status": null,
"file_name": null,
"flash_backup_url": null,
"flash_backup_url_secure": null,
"flash_click_variable": null,
"height": 488,
"id": 271833576,
"ios_ssl_audit": null,
"is_blanking": null,
"is_expired": false,
"is_hosted": false,
"is_prohibited": false,
"is_rotating": null,
"is_self_audited": false,
"is_suspicious": false,
"landing_page_url": "https://en.wikipedia.org/wiki/Car",
"language": {
"id": 1,
"name": "English"
},
"last_activity": "2021-02-05 21:56:47",
"last_checked": null,
"media_assets": null,
"media_url": null,
"media_url_secure": null,
"member_id": 1234,
"mobile": null,
"native_attribute": null,
"no_adservers": false,
"not_found": 0,
"original_content": "<a href=\"https://en.wikipedia.org/wiki/Car\" target=\"_blank\">\r\n <img src=\"https://upload.wikimedia.org/wikipedia/commons/3/3e/SteamMachineOfVerbiestIn1678.jpg\" />\r\n</a>",
"original_content_secure": "<a href=\"https://en.wikipedia.org/wiki/Car\" target=\"_blank\">\r\n <img src=\"https://upload.wikimedia.org/wikipedia/commons/3/3e/SteamMachineOfVerbiestIn1678.jpg\" />\r\n</a>",
"passed_sherlock_audit": true,
"pixels": null,
"placement": null,
"political": null,
"segments": null,
"size_in_bytes": 0,
"sla": "0",
"sla_eta": "2021-02-08 15:58:47",
"ssl_status": "pending",
"status": {
"hosted_assets_association_complete": null,
"user_ready": true
},
"suspicious_activity_timestamp": null,
"technical_attributes": [
{
"id": 1,
"name": "Image"
}
],
"template": {
"id": 6
},
"text_description": null,
"text_display_url": null,
"text_title": null,
"thirdparty_campaign_id": null,
"thirdparty_creative_id": null,
"thirdparty_page": null,
"thirdparty_pixels": null,
"thirdparty_viewability_providers": null,
"vendors": null,
"video_attribute": null,
"width": 682
},
"dbg": {
"output_term": "creative",
"version": "1.18",
"warnings": []
},
"id": "271833576",
"num_elements": 100,
"start_element": 0,
"status": "OK"
}
}
The bidder instance object represents a particular bidder server running in the data center. This information stored in this object determines where we send traffic. In this example, we set the data center ID to (NYM).
Warning
This step assumes that you already have a bidder up and running that can respond to bid requests, ready requests, etc., as detailed in the System Overview.
Tip
For more information about configuring a bidder instance, see the Bidder Instance Service
In this example we set an IP address and port to which traffic should be sent.
https://[hostname or IP]:[port][bidder.bid_uri]
bidder.bid_uri
is set in your bidder object.$ cat create-bidder-instance.json
{
"instance": {
"bidder_id": 123,
"active": true,
"datacenter_id": 6,
"ip_address": "10.3.64.215",
"port": 80
"qps_limit": 10000,
}
}
$ export IB="https://api.adnxs.com";
$ curl -b cookies -X POST -d @create-bidder-instance.json $IB/bidder-instance/123
{
"response": {
"status": "OK",
"count": 1,
"start_element": null,
"num_elements": null,
"id": 1543,
"instance": {
"id": 1543,
"bidder_id": 123,
"active": true,
"datacenter_id": 6,
"ip_address": "10.3.64.215",
"port": 80,
"hostname": null,
"qps_limit": 10000,
"dns_interval": null,
"min_conns": 1,
"max_conns": null,
"receive_type_id": 0
},
"count": 1,
"dbg": {
"output_term": "bidder",
"version": "1.0.5",
"warnings": [
]
},
"num_elements": 100,
"start_element": 0,
"status": "OK"
}
}
The bid response should be formatted correctly in order for your bidder to submit bids properly. The required fields can be found here.
Note
Since you are integrating with buyer seat ID, the seatbid.seat field should be your own internal IDs.
If you require an example of a bid request to use, your Xandr representative should be able to provide you with one. The supported bid request fields with examples can be found here.
/getuid
. More information on this service can be found here: Synchronize Your User IDs.bidder.ready_uri
is set in your bidder object."1"
somewhere in the body.Note
We recommend you log the Xandr creative IDs on your system.
audit_status
: this field indicates if the creative has passed the human audit that confirms the creative renders and clicks properly.ssl_status
: this field indicates if the creative has passed our automates SSL scanner.is_prohibited
: this field indicates if the creative has violated one of our policies.If you are still not seeing the bid requests you expect, double-check your configuration against the instructions on this page. Contact your Xandr representative if the problem persists.
The Client Testing environment provides a version of the Impbus and Impbus API that you can use to test your workflows and API implementations. The Client Testing environment's codebase and data are now updated every month. This means your testing environment will never be more than 30 days (and often less) behind the version of Xandr code that is running in Production. In addition, all Production data will also automatically be copied over to the Client Testing environment (including your member accounts and credentials) each month. This will allow far more robust testing against the latest features.
For reference, here are the endpoints for the Production and Client Testing environments.
Update these fields to ensure our ready requests and bid requests, respectively, are sent to the right endpoints.
$ cat update-uris.json
{
"bidder": {
"ready_uri": "/example_ready_endpoint",
"bid_uri": "/example_bid_endpoint"
}
}
$ export IB="https://api.adnxs.com";
$ curl -b cookies -X PUT -d @update-uris.json $IB/bidder/1234?fields=active,bid_uri,id,ready_uri
{
"response": {
"bidder": {
"active": true,
"bid_uri": "/example_bid_endpoint",
"id": 1234,
"ready_uri": "/ready/",
},
"count": 1,
"dbg": {
"output_term": "bidder",
"version": "1.0.5",
"warnings": []
},
"id": "1234",
"num_elements": 100,
"start_element": 0,
"status": "OK"
}
}
Update these fields to ensure you receive notifications for creatives you upload to our system.
$ cat update-email.json
{
"member": {
"audit_notify_email": "your_email@email.com"
}
}
$ export IB="https://api.adnxs.com";
$ curl -b cookies -X PUT -d @update-email.json $IB/member/5678?fields=active,audit_notify_email,id
{
"response": {
"member": {
"active": true,
"audit_notify_email": "your_email@email.com",
"id": 5678,
},
"count": 1,
"dbg": {
"output_term": "member",
"version": "1.0.5",
"warnings": []
},
"id": "5678",
"num_elements": 100,
"start_element": 0,
"status": "OK"
}
}
Training
Learning path
Implement finance and operations apps - Training
Plan and design your project methodology to successfully implement finance and operations apps with FastTrack services, data management and more.