Our API enables you to retrieve the same ad fill you'd see in our traditional widgets but in a much more customizable format.
NOTE: API usage requires full Advertising Disclosure.
API REQUESTS
- Content type:
application/json or text/xml
- Endpoint:
GET http://trends.revcontent.com/api/v2/
Parameter | Type | Default | Description |
api_key |
string | none | Your account's API key |
pub_id |
integer | none | Your account ID |
widget_id |
integer | none | The ID of the widget associated with the request |
domain |
string | none | The URL encoded domain name associated with the widget |
Sample Request:
https://trends.revcontent.com/api/v2/?api_key={Insert_Your_API_Key}&pub_id={Insert_Your_Account_ID}&widget_id={Insert_Your_Widgets_ID}&domain={Insert_Your_Widgets_Domain}
Parameter | Type | Default | Description |
user_ip |
string | request IP | End user's IP address. Responses are tailored to end user's location. If an IP is not provided, the request IP is used. If you're calling the API with client-side code such as Javascript, we can detect the user's IP. Otherwise you'll need to pass it. |
user_agent |
string | request UA | End user's user agent (UA). Used to segment stats by device type. If a UA is not provided, the request UA is used. If you're calling the API with client-side code such as Javascript, we can detect the user's UA. Otherwise you'll need to pass it. This value must be URL-encoded into valid ASCII format |
referrer |
string | none | End user's encoded page URL the request is being made from |
width |
integer | 1280 | End user's screen width |
img_w |
integer | 400 |
Creative image width. Options are:
If a different width outside of these four options is specified, the closest will automatically be applied |
img_h |
integer | 315 |
Creative image height. Options are:
If a different height outside of these four options is specified, the closest will automatically be applied |
format |
string | JSON | Request response format |
sponsored_count |
integer | 25 | Number of sponsored creatives you'd like returned in the response |
sponsored_offset |
integer | 0 | Position you'd like the sponsored creative response to start from |
internal_count |
integer | 5 | Number of internal creatives you'd like returned in the response |
internal_offset |
integer | 0 | Position you'd like the internal creative response to start from |
send_view |
string | none | Used to register widget and creative views. Pass "send_view=true" to return view hashes. See the "Tracking Views" section below for detailed setup instructions |
tracking |
string | auto |
Used to manually register all impressions. By default "tracking=auto" is passed and impressions are automatically registered. If "tracking=manual" is passed, an impression will not be registered until the impression string is posted back to http://trends.revcontent.com/api/v2/track.php as the "d" value: |
✴️ pick_one |
string | 1 | If "tracking=manual" is being used and you’d like to only register impressions on certain creatives, the “pick_one” parameter can be passed. By passing “pick_one=1”, each creative will have an “impression” hash. You’re able to use this as an impression tracking pixel when calling http://trends.revcontent.com/api/v2/track.php. Each creative and subsequent click link would be “position=1”. |
✴️ tracking_method |
string | none | If "tracking=manual" is being used and you’d like an impression GET URL instead of a POST URL you can pass "tracking_method=get" |
us_privacy |
string | none | Used to pass IAB CCPA URL-encoded URL-encoded US Privacy string |
gdpr |
string | none | Used to indicate current impressions is a GDPR regulated impressions. `0` GDPR does not apply; `1` GDPR applies. |
gdpr_consent |
string | none | Used to pass the URL-safe base64-encoded IAB GDPR Transparency & Consent string. Only meaningful if gdpr=1 |
gpp |
string | none | Used to pass url-safe base64-encoded IAB GPP consent string |
gpp_sid |
string | none |
Used to pass GPP section ID(s) in force for the current transaction. In most cases, this field should have a single section ID. In rare occasions where such a single section ID can not be determined, the field may contain up to 2 values, separated by a comma. |
revsub[]= |
string | none |
Used to pass subIDs in order to achieve customized reporting. &revsub[taco]=truck |
✴️ only applicable if "tracking=manual" is being used
API RESPONSES
Parameter |
Description |
headline |
Creative headline |
url |
Creative click URL |
image |
Creative image URL |
brand |
Creative provider |
content_type |
Creative content type - article or video |
type |
Creative type - sponsored or internal |
uid |
Creative type and unique identifier (type_uid) |
target_url |
Creative destination URL |
view |
Request to be made once the creative enters a user's viewport. See the "Tracking Views" section below for detailed instructions |
impression |
Encoded impression string. Only returned if "tracking=manual" and "pick_one=1" are being passed into the request |
Sample Response
{"content":[{"headline":"Sample Headline","url":"https:\/\/trends.revcontent.com\/click.php?d=FGEvEC23O7thB%2Bc%2FbvyqPZRuPR%2BkEr4UOIDs0NqONIC5NzY13LWWNnbW4XYf%2F2HUblhFr63pVKst6%2F1rBDoNCwDkSkhJcgx3wJgy6AB%2FrugEW6QGB3PMJxBUPxgXWZEXIDfwwbMFbl6BxJc2GDHHtsy3anBb7XKDT3jkC3Ekut8Q5ev5oOovH1WEjCLYRqqV2B7Caqz5rl%2FKuTBCBtkd6qN4Ie2jmU8OmzVoRTpo2Xp09u645olzuzrWIxFeob8my9Qs9CKLCY%2Bt3CeiFJVCq9wP8rHglUEY5G9y%2BnjKHxOcUlcumprWWWDbiqUwYqGLxHWDLlz%2BnooR2RMgvTaoKcV8B9oz0UqxCseZsMdcL6bQyvd0VPHsyuaJlMoanG27EBWry6QYLOHd%2FlQV3aaBvSaR00J2FNBMF8zAdmBEvUs1dejPrT15oynoDZNUYu%2F9%2FIbmKDT5owLdrAPVoXEQKzKT9RAFwJiiOsCPNDwQv4CiKPyg4Uk%2Bv1UKsTD%2FXjJ597exjZr%2FYIs7OqPZlg%2Bl%2Fxm%2FK5qXKYY%2B9UCmKgXv0dScAK4XSi8HK7Zk6Yb7QYbYAtHx%2Bn5FXp3Fa1CAcNH7DHcM4%2FfkMn3zUmT5n08TG5roBsekEHFmB%2FMn%2Fqr9f5lKSYWbKhxTak3Vz%2BGAzpooZv5sH4p65C9ov%2BenOAg0KlXwguJ0RfIEwRtqZkoK5FQ3SUWq1Aeb57sfds5MrvqBMPRDvRuCneybbohbqFpiudL4v59DmgqixQ%2BWdAtANk5yHo2OxsjasZLBBfSzdTuGGaJ3tKvgdOBRCQeTXXim29ihMzIQl6HK9AIr1Ioxa2dlU1hwozTVvN20gxcEPfuoWmuE7ISpJz38uju1Mwys%2BSNMMP1lZ391pGyMgGWFQCK1fhrkqOLsrz5fh%2FVBMBf0EWunHp1PfOLGa5QmlBRevdLCpo1NUWY%2Fnx5CHIiLWqz4BurfDs6daqjv3gsdQVwmIHcUD5d6R9gj2ped7szkXq6ckfYF4LonQRqbNNALF6a8wr3BWaLJfGbEGM89BoTh3IzHiigfRGUjaseLaATtet1Wex8o7FUgsEX1XNBbWlyWtujNJwRCPfN57%2FJT%2FGv97qAj90haJhFhtMvAP%2FypIWCqnu7NH6NX8irQM4exWJta&s2s=1","image":"https:\/\/images.revcontent.com\/revcontent\/image\/fetch\/f_auto,h_315,w_420,c_fill,g_face\/pg_1\/https:\/\/revcontent-p0.s3.amazonaws.com\/content\/images\/12345-67890.jpg","brand":"Revcontent","type":"sponsored","uid":"sponsored_123456","target_url":"https:\/\/example.com\/123?","impression":""}],"impression":""}
Tracking Views
Views should always be tracked. A view occurs when a widget and its creative(s) enter the user's viewport. The "send_view" parameter is used to generate a view hash. By passing "send_view=true" into your request, a view parameter will be returned in your response with a unique hash as the value. To record the view, you'll need to post back the view hash returned in the response to https://trends.revcontent.com/view.php. The "view" parameter also accepts 2 additional parameters:
- view_type - the type of view event. Either "widget" or "fill"
- p[] - the creative's panel position index starting from "0"
Sample Post Body
{"view":"View_Hash_Goes_Here","view_type":"fill","p[]":"0"}
In order to determine which elements have entered a user's viewport and are considered viewed, we recommend using something like the Intersection Observer API.
The following is an example of the entire view tracking process setup in Javascript:
const settings = {
url: '//trends.revcontent.com/api/v2/',
widgetId: {Your_Widgets_ID},
apiKey: '{Your_API_Key}',
pubId: {Your_Account_ID},
domain: '{Your_Widgets_Domain}',
sponsoredOffset: 0,
sponsoredCount: 4
};
const widgetData = {
items: [],
view: '',
queue: [],
widgetView: false
};
const observerOptions = {
threshold: 0.95
};
const createItem = (item, index) => document.createRange().createContextualFragment(`
<div class="rc-item" data-index="${index}">
<a href="${item.url}">
<div>
<img src="${item.image}" />
<h3>${item.headline}</h3>
</div>
</a>
</div>
`);
const buildWidget = async () => {
const data = await fetch('${settings.url}?api_key=${settings.apiKey}&pub_id=${settings.pubId}&domain=${settings.domain}&widget_id=${settings.widgetId}&sponsored_count=${settings.sponsoredCount}&sponsored_offset=${settings.sponsoredOffset}&send_view=true`, {
credentials: 'include'
}).then(res => res.json());
widgetData.items = data.content;
widgetData.view = data.view;
widgetData.impression = data.impression;
const target = document.getElementById('app');
if (target) {
widgetData.items?.forEach((item, index) => target.appendChild(createItem(item, index)));
}
// Ideally, delay observation for a moment until html is rendered. Intersection Observer will trigger
// as true when the element is first created if in the view port. This delay gives your ad panel a chance
// to generate the markup before observation.
setTimeout(() => {
createObserver();
}, 150);
}
// Call the view event
const trackView = () => {
// Only fire an event if the queue has items. If not, do nothing.
if (widgetData.queue.length > 0) {
// Create a search params and append data to it. The view payload expects the following:
// view: The view hash received from the API. This requires decoding via decodeURIComponent
// p[]: The index to be tracked as viewed. This can be multiple entries of an index such as
// p[]: 0
// p[]: 1
// p[]: 2
const data = new URLSearchParams();
data.append('view', decodeURIComponent(widgetData.view));
if (!widgetData.widgetView) {
widgetData.widgetView = true;
data.append('view_type', 'widget');
}
else {
data.append('view_type', 'fill');
}
widgetData.queue.forEach(entry => {
data.append('p[]', entry);
})
// Once the data is added to the search params, perform a post. This must be
// form encoded as shown here, with the search params being sent as the body
// of the request. This will return 200 for successful calls.
fetch(`https://trends.revcontent.com/view.php`, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
},
body: data
})
// Clear the queue, the items currently in the queue have been tracked and
// can be removed.
widgetData.queue = [];
}
}
// This is the callback that is ran whenever an element is observed.
const onIntersection = (entries, observer) => {
entries.forEach(entry => {
if (entry.intersectionRatio >= observerOptions.threshold) {
// If this is hit, it means the element meets the intersection ratio value
// The ratio is a percentage between 0 and 1 with 1 being 100% in view. Push
// the index into the queue in preparation of sending a view event.
widgetData.queue.push(parseInt(entry.target.dataset.index, 10));
// The position has been queue for a view event and we no longer need to observe
// this element. Remove it from observation.
observer.unobserve(entry.target);
// Delay firing the event briefly. This gives your observer a chance to aggregate
// indexes into the queue before firing an event. For example, if the first and
// second panel are in view at the same time, you can send them as a single event
// with the payload holding the indexes for each.
setTimeout(() => {
trackView();
}, 50);
}
})
}
// Create a observer and then query the DOM to get the elements to watch.
const createObserver = () => {
const observer = new IntersectionObserver(onIntersection, observerOptions);
// Get the elements to observe via a class name. Set this to whatever is appropriate.
const elements = document.querySelectorAll('.rc-item');
// If any elements are found, iterate and observe them.
if (elements) {
elements.forEach(element => observer.observe(element));
}
}
buildWidget();
If running multiple widget placements, treat them each as independents when it comes to tracking views. For example, if you have two spots on a page where the API is showing ads, each of them should be treated as their own unique widget and will need to be managed as such for the view tracking logic. We track views via an index which represents the position of the ad in regards to where it's displayed for that batch of items. Each ad shown is its own panel with an index of 0 (the very first ad shown in that group of ads) to whatever the amount of items requested is (0/1/2/3 for 4 sponsored items, etc). In other words, you might have 2 places where you want to show results from the API. That would essentially give you the following:
Placement 1 (4 sponsored items requested)
- Panel indexes: 0/1/2/3
- View hash: (unique hash sent back from request)
- Unique queue for this placement: (empty array on initialization, will hold indexes of items queued for view event)
Placement 2 (another 4 sponsored items requested)
- Panel indexes: 0/1/2/3
- View hash: (unique hash sent back from request)
- Unique queue for this placement: (empty array on initialization, will hold indexes of items queued for view event)
Then, in the observer/view tracking logic:
- determine which placement it is
- push it to the appropriate queue
- get the hash for that queue
- fire the event
- then clear the appropriate queue for the placement.
You may not require this behavior depending on your needs, but it's something to consider.