Buvlor Ads SDK — Publisher integration guide.

Integrate rewarded video across multiple ad partners through one mediation SDK.

1. Overview

The Buvlor SDK embeds into a publisher page and displays rewarded video ads through a single BuvlorAds global. Mediation across multiple ad partners is configured server-side per siteId — the publisher integration is unchanged regardless of how many partners are wired up behind the slot.

This guide walks through prerequisites, the three-line integration, identity attachment, the full API surface, and error handling.


2. Prerequisites

  1. Email ads@buvlor.com with your domain to receive a siteId.
  2. Add the DNS TXT record Buvlor issues on _buvlor.<your-domain> for verification.

Ad partner SDKs are loaded automatically by the Buvlor SDK — no extra integration required on your side.


3. Quick Start

Integration is two steps: install (once per page) and invoke (on user action).

3.1 Install — page <head> (once per page)

html
<!-- Load SDK -->
<script src="https://buvlor.com/sdk/v1/ads.js" async></script>

<!-- Initialize -->
<script>
  BuvlorAds.init({ siteId: 'your-site-id' });
</script>
  • Loads the SDK from the Buvlor CDN, asynchronously.
  • Initializes the SDK with your siteId. Mediation config is fetched server-side. Call init() once per page.

3.2 Invoke — on user action (anywhere in your product)

BuvlorAds.showRewardedAd() is the trigger that displays the ad. Call it from whatever UI your product needs — a button, a card tap, an end-of-level modal, a programmatic event.

html
<button onclick="BuvlorAds.showRewardedAd({
  slotId: 'your-slot-id',
  onAdLoaded: () => { /* ad loaded and ready — hide your loading spinner, lock user input */ },
  onReward: () => grantUserReward()
})">Watch ad to earn reward</button>

Or from JS:

js
playAdBtn.addEventListener('click', () => {
  BuvlorAds.showRewardedAd({
    slotId: 'your-slot-id',
    onAdLoaded: () => { /* ad loaded and ready — UI hook */ },
    onReward: () => grantUserReward()
  });
});

Need more than one slot? Call showRewardedAd with a different slotId per placement. The result of each call is delivered through exactly one of three terminal callbacks — onReward, onClose, or onError — described in §5. An optional fourth callback, onAdLoaded, fires when the ad is loaded and ready to display — useful for UI hooks like hiding a loading spinner.


4. Identity

Optional. Without it, the SDK still works — ads are served, callbacks fire as documented. Passing an identity is recommended for better matching but not required for integration.

When you do provide it, pass the device advertising ID (Android AAID / iOS IDFA) into the identity field. The SDK normalizes and SHA-256 hashes the value internally before transmission — plaintext is never stored or transmitted.

js
BuvlorAds.init({
  siteId: 'your-site-id',
  identity: '<advertising id from the device>'
});

Advertising IDs are not classified as personal data under Apple's and Google's developer policies, so this avoids the privacy considerations that apply to email addresses or account identifiers.

How to obtain the advertising ID, by environment:

  • Android in-app webview — Call AdvertisingIdClient.getAdvertisingIdInfo() in your native host and hand the value to the webview through your bridge.
  • iOS in-app webview (WKWebView) — Read ASIdentifierManager.advertisingIdentifier after the user grants ATT consent. If ATT is denied, fall back to a first-party UUID stored inside your app.
  • Pure web (non in-app) — The advertising ID is not available. Use a first-party UUID persisted in your own storage.

If the identifier is not ready at init() time, call BuvlorAds.setIdentity(value) once it becomes available — calls made before init() are queued and flushed automatically. Use BuvlorAds.clearIdentity() to detach the value on logout.


5. API Reference

BuvlorAds.init(options)

Option Type Required Description
siteId string Yes Identifier issued by Buvlor.
identity string No Per-user unique identifier (auto-hashed).
primaryDomain string No Canonical domain for this deployment.
configUrl string No Override the default config URL.

BuvlorAds.setIdentity(value) / BuvlorAds.clearIdentity()

Attach or remove a per-user identifier. Returns Promise<void>. Safe to call before init() — values are queued and flushed automatically.

BuvlorAds.showRewardedAd(options)

showRewardedAd() is the function that displays the rewarded video. Call it from any UI element or programmatic trigger your product needs.

Option Type Description
slotId string Slot name defined in your mediation config.
onAdLoaded () => void Optional. Fires when the ad is loaded and ready to display. Use for UI hooks (hide loading spinner, lock user input).
onReward () => void User completed the ad — pay out here.
onClose () => void User dismissed before completion. Do not pay out.
onError (err) => void No demand source filled. err.code is a token in §6.
openUrl (url) => void Optional. Opens the ad's landing URL on click. Defaults to window.open(url, '_blank').

openUrl — opening the ad landing

Some ad formats have buvlor open the landing URL on click (SDK-rendered ads handle their own clicks, so this isn't needed there). When it applies, openUrl is invoked; if you don't pass one, it defaults to window.open(url, '_blank'). In environments where window.open doesn't reach an external browser (e.g. native webviews), inject your own function that opens the external browser via your app's bridge.

js
BuvlorAds.showRewardedAd({
  slotId: 'your-slot-id',
  onReward: () => grantUserReward(),
  openUrl: (url) => nativeBridge.openExternalBrowser(url), // example
});

Typical cases where openUrl fires: click-through banners and interstitials, and native ads that buvlor renders as a card (landing + privacy-policy links).

Callback behavior

Every call to showRewardedAd() resolves through exactly one of the three terminal callbacks — onReward, onClose, or onError — fired once. There are no duplicate, partial, or contradictory callbacks. The SDK guarantees this internally, so you can put your reward-granting code directly inside onReward without worrying about double payouts.

onAdLoaded is an optional lifecycle signal that fires before the terminal callback whenever an ad fetch succeeds and the ad is ready to display. It is independent of the three terminal callbacks.

  • onAdLoaded() — The ad is loaded and ready to display. Fires at most once per call, and always before onReward / onClose. Does not fire on onError (the ad was never fetched). Use this hook to hide your "loading..." UI and lock user input.
  • onReward() — The user watched the ad to completion. Grant the reward here.
  • onClose() — The ad was shown, but the user closed it before completion. Do not grant the reward.
  • onError(err) — No ad could be displayed at all. Inspect err.code (§6) to decide your fallback: retry later, hide the entry point, fall back to a non-ad reward path, etc.

Ordering guarantees

  • onAdLoaded always fires before onReward or onClose when an ad fills.
  • onAdLoaded never fires together with onError.
  • Exact timing of onAdLoaded varies slightly by mediation tier — it fires when the ad fetch completes and the ad is ready, before the display starts. The ordering relative to all terminal callbacks is always preserved.

UI is yours. showRewardedAd() only handles the ad display and the result callbacks. The button shown in §3 is illustrative — the SDK does not care whether the trigger is a button, a tappable card, an automatic call after a game round, a daily-check-in flow, or a low-balance modal. Design the entry point however fits your product.

BuvlorAds.preloadRewardedAd({ slotId })

Optional. Warms the first mediation tier so a subsequent showRewardedAd call renders with minimal latency.


6. Error Codes

onError receives { code, message }. code is one of:

Code Meaning Recommended response
all_unavailable Mediation ran through all tiers but none could fill the slot. Show "Try again in a moment" to the user.
invalid_slot Slot configuration is malformed or missing. Contact Buvlor — config-side issue.
init_failed The SDK could not load or parse the site config. Check network connectivity and retry.

7. FAQ

Q. Ads aren't loading. How do I debug? Check three things in order: (1) the ad partner site-script Buvlor provided is loaded in your page <head> and reaches readyState: complete; (2) the browser console for errors emitted by BuvlorAds (init failures and slot errors log with a [BuvlorAds] prefix); (3) the onError callback code against §6. If all three look clean, send the siteId, slot name, and console log to ads@buvlor.com.

Q. When should I call setIdentity()? Pass the advertising ID directly into init({siteId, identity}) if it is available at page load — that is the recommended path. Only call setIdentity(value) separately when the identifier arrives later (for example, an asynchronous native-bridge call, or a first-party UUID generated on first visit). Calls made before init() are automatically queued and flushed once init completes.

Q. How do I add a new domain to my site? Email ads@buvlor.com with the new domain. Buvlor registers it server-side and issues a fresh DNS TXT record for _buvlor.<new-domain>. Once the record propagates, the same siteId works on the new domain — no code change required.

Q. Can Buvlor Ads run alongside other ad SDKs? Yes. Buvlor Ads is rewarded-only and isolated to its own globals. Display, native, and other rewarded SDKs on the same page are not affected.

Q. Do I have to use a button to call showRewardedAd? No. The <button> in §3 is just an example. Call showRewardedAd() from any UI element, lifecycle hook, or programmatic trigger your product uses — an end-of-level reward popup, a daily check-in tap, a low-coin modal, a tappable card on a home screen, or a fully scripted flow. The SDK is responsible for displaying the ad; your code decides when and where to invoke it.

Q. When does onAdLoaded fire? Can I use it to hide a loading spinner? Yes — that is the intended use case. onAdLoaded fires once when the ad fetch completes and the ad is ready to display, before onReward or onClose. It does not fire on onError. Show your loading spinner immediately after calling showRewardedAd(), and hide it inside onAdLoaded. The ordering guarantee (onAdLoaded → terminal callback) always holds, so your spinner-hide will never run after your reward grant.


8. Contact

  • Integration & support: ads@buvlor.com
  • siteId requests: include your site domain, contact name, and the rewarded slot names you plan to implement. Staging config and debug tokens are provisioned on request.