# Rewarded Video SDK for HTML5

## Eligible Placement & AdSlot Combinations <a href="#eligible-placement-and-adslot-combinations" id="eligible-placement-and-adslot-combinations"></a>

The table below shows all Placement & AdSlot Type combinations which allow you to utilize the Rewarded Video for Web integration.

| Placement Type | AdSlot Type    | Eligible Integration Type    |
| -------------- | -------------- | ---------------------------- |
| Website        | Rewarded Video | Rewarded Video SDK for HTML5 |

{% hint style="danger" %}
If you integrate the Rewarded Video for Web SDK while using a different Placement & AdSlot combination in the ayeT-Studios dashboard, you won't be able to send correct ad requests.
{% endhint %}

## Getting Started

Before you start with the integration, make sure you:

* [x] Created an Account
* [x] Added a Placement
* [x] Added an AdSlot

You will find more details here:

{% content-ref url="/pages/W7CE6bNya8L7RoaXXY21" %}
[Dashboard Setup](/v/product-docs/dashboard-setup.md)
{% endcontent-ref %}

### Ads.txt

{% hint style="warning" %}
Adding an ads.txt to your domain is required (see Integration) to correctly utilize the Rewarded Video solution.
{% endhint %}

You can find the relevant ads.txt lines that you have to add to [www.your-website.com/ads.txt](http://www.your-website.com/ads.txt) under "Edit Placements" in your publisher dashboard.

### CMP

We highly recommend using a **CMP** (Consent Management Platform) on your website.

{% hint style="info" %}
Without a compliant **CMP** and without requesting consent from affected GDPR & CCPA users, both fill rate and eCPM will be impacted significantly or no ads will be delivered at all.
{% endhint %}

There are two different options for you to integrate a CMP:

1. **Self-Hosted CMP**
   * Go to <https://iabeurope.eu/cmp-list/>
   * Look for a CMP that suits you
   * Follow the integration docs of that CMP
2. **CMP from Google AdSense (free of charge)**
   * Create a Google AdSense account
   * Setup and integrate the Google CMP
   * Our Team can assist with the setup

### Supported Features

Our JavaScript library supports the following features:

* OpenRTB header bidding with bundled prebid.js
* Ad server functionality with custom waterfall demand sources, bid buckets and back fill
* Consecutive waterfall VAST tag validation and fallback handling for no-bid scenarios
* Content isolation and parent page protection using iframe playback
* Native browser video rendering
* Automatic detection of external CMPs and support for TCF2 / GDPR consent handling
* Both S2S and signed client-side callbacks for user rewards

## Integration

To integrate our video SDK on your site, add the following script to the <mark style="color:red;">`<head></head>`</mark> section of your web / app or pages where videos are supposed to be played:

```php
<script src="https://cdn.ayet.io/offerwall/js/ayetvideosdk.min.js"></script>	
```

The script above is around **35kb** in size and will load additional required scripts (bidders, players, configuration) upon initialization.&#x20;

Next, please verify that the **ads.txt** on your server contains all requested entries listed for your placement in our dashboard in the *Placement Details > Overview* page.

### Initialization & Global Callback Handlers <a href="#initialization-and-global-callback-handlers" id="initialization-and-global-callback-handlers"></a>

To initialize the SDK for a user, make the following asynchronous call that returns a Promise:

```php
var placementId=3; // This is the numeric id of your web placement
var externalIdentifier="{your user identifier}";
var optionalParameter=null; // or a string(32)
AyetVideoSdk.init(placementId, externalIdentifier, optionalParameter).then(function() {
	console.log("finished initialization!");
});
```

<mark style="color:red;">`externalIdentifier`</mark> is a string (up to 128 chars, min. 3 characters) you set to uniquely identify your user. It might be a **UUID**, a **hashed email address** or anything that allows you to persistently identify a user.

<mark style="color:red;">`optionalParameter`</mark> is an optional string (up to 32 chars) you can use to add an additional reporting dimension to the video statistics. It can be accessed and filtered in the video adslot statistics and the reporting API.

To receive notifications for video playback events, the following global callbacks can be configured:

```php
/* An error occured when trying to play a video ad. After this callback, no video is being rendered and a new ad has to be requested first: */
AyetVideoSdk.callbackError = function(e) {console.log("callbackError: "+JSON.stringify(e));};

/* After this callback, a video will start playing: */
AyetVideoSdk.callbackPlaying = function() {console.log("callbackPlaying");};

/* After this callback, playing the video is finished and the player is closed: */
AyetVideoSdk.callbackComplete = function() {console.log("callbackComplete");};

/* This callback is sent once a second while a video is being played: */
AyetVideoSdk.callbackProgress = function(remainingSeconds) {console.log("callbackProgress: "+Math.round(remainingSeconds)+"s remaining");};

/* This callback is sent if a video has been completed and the impression has gone through fraud checks (see "Rewarding Users" for more details): */
AyetVideoSdk.callbackRewarded = function(details) {appendLog("callbackRewarded: "+JSON.stringify(details));};
```

### Requesting Video Ads

To request a video ad for your AdSlot, make the following asynchronous call:

```php
AyetVideoSdk.requestAd(
	'{your_rewarded_video_adslot_name}',
	function() { // success callback function
		console.log("requestAd successful");
	},
	function(msg) { // error callback function
		appendLog("requestAd failed: "+msg);
	}
);	  
```

Make sure not to call <mark style="color:red;">`requestAd`</mark> before the initialization of the SDK is complete, otherwise the call will fail. Also note, that after a success callback, a video ad is ready to be played. Depending on your video demand sources, successful bids will timeout after a while (usually 1-60 minutes). It's advisable to make a <mark style="color:red;">`requestAd`</mark> call just in time when a video should be played.

### Playing Video Ads

After a video ad has been successfully requested, the following calls are available to play an ad. Please note, that these functions should be called from a user-interaction (for example a click event) or from the <mark style="color:red;">`requestAd`</mark> **success callback** which itself has been called from a user-interaction. Otherwise, video autoplay will be rejected by most browsers and we must render an additional button over the video for the user to click, which lowers the acceptance and usability.

```php
/* Play the ad in a pre-defined div (consult your account manager to determine if size & location is appropriate for all demand partners): */
AyetVideoSdk.playInPageAd('video_div');

/* Play the ad full size (100% of your page viewport): */
AyetVideoSdk.playFullsizeAd();

/* Play the ad fullscreen (this temporarily switches the browser to fullscreen mode): */
AyetVideoSdk.playFullscreenAd();
```

The different <mark style="color:red;">`play...Ad`</mark> functions will silently abort if an ad is already playing. In all other cases, they make use of the global callback handlers described in the *Initialization & Global Callback Handlers* section.

Additionally, it makes sense to check if a video is ready to play, especially if there's a bigger expected delay between <mark style="color:red;">`requestAd`</mark> and <mark style="color:red;">`play...Ad`</mark>, for example:

```php
/* This example assumes an ad was requested a longer time ago and we're unsure if the bid expired already */
if (AyetVideoSdk.isAdAvailable()) {
	AyetVideoSdk.playInPageAd('{your_html_video_div_id}');
} else {
	/* Either abort and notify the user or request and play a fresh ad: */
	AyetVideoSdk.requestAd(
		'{your_rewarded_video_adslot_name}',
		function() { // success callback function
			AyetVideoSdk.playInPageAd('{your_html_video_div_id}');
		},
		function(msg) { // error callback function
			appendLog("requestAd failed: "+msg);
		}
	);
}
```

While a video is playing, it's possible to externally **interrupt the ad and destroy the player** by making a call to <mark style="color:red;">`destroy`</mark>:

```php
/* Interrupt a playing ad and destroy the player (to play another ad later, a new call to AyetVideoSdk.requestAd is required) */
AyetVideoSdk.destroy();
```

## Rewarding Users

There are two ways to reward users for rewarded video views, **(1) Clientside Video SDK Callbacks** and **(2) Server2Server Conversion Callbacks**.

The **S2S Callbacks** are usually sent to your server within 60 seconds after a completed & rewarded video view.

{% hint style="info" %}
Since rewarding users for video views in real time is usually important for a frictionless user flow, we recommend using **(1) Clientside Video SDK Callbacks**!
{% endhint %}

### Server2Server Conversion Callbacks <a href="#server2server-conversion-callbacks" id="server2server-conversion-callbacks"></a>

For more information on Server2Server Conversion Callbacks please use this link:

{% content-ref url="/pages/5sxVWIW1fto5Mmv1JxeJ" %}
[Callbacks & Testing](/v/product-docs/callbacks-and-testing.md)
{% endcontent-ref %}

### Clientside Video SDK Callbacks <a href="#clientside-video-sdk-callbacks" id="clientside-video-sdk-callbacks"></a>

The **Clientside SDK Callbacks** are received through the global <mark style="color:red;">`AyetVideoSdk.callbackRewarded`</mark> function shown in Initialization & Global Callback Handlers:

```php
/* This callback is sent if a video has been completed and the impression has gone through fraud checks: */
AyetVideoSdk.callbackRewarded = function(details) {appendLog("callbackRewarded: "+JSON.stringify(details));};

/* Example output:
callbackRewarded: {"status":"success","rewarded":true,"externalIdentifier":"your user identifier","currency":10,"conversionId":"aef8cd370cfe-video-u94-adbcec159f76","signature":"f98c35ae4facef42dce5b31f6a5f9f0e8819b8ec"}
*/

/* Example output if custom parameters were set:
callbackRewarded: {"status":"success","rewarded":true,"externalIdentifier":"your user identifier","currency":10,"conversionId":"aef8cd370cfe-video-u94-adbcec159f76","custom_1":"bar", "custom_3":"foo","signature":"e35d78be4facef42dce5b31f6a5f9f0e8821c3de"}
*/
```

{% hint style="danger" %}
Please use `AyetVideoSdk.callbackRewarded` and not `AyetVideoSdk.callbackComplete` to reward users!
{% endhint %}

You can send the callback response to your server and validate the callback signature serverside. The signature can be verified serverside with your publisher API key (found in our Dashboard > Account Settings > Api Key), like the following example (in PHP). If custom parameters are present in the callback, they are also part of the `signature`. Signature calculation example:

```php
$signature = hash_hmac('sha1',
	$response['externalIdentifier'] .
	$response['currency'] .
	$response['conversionId'] .
	(isset($response['custom_1']) ? isset($response['custom_1'] : '') .
	(isset($response['custom_2']) ? isset($response['custom_2'] : '') .
	(isset($response['custom_3']) ? isset($response['custom_3'] : '') .
	(isset($response['custom_4']) ? isset($response['custom_4'] : '') .
	(isset($response['custom_5']) ? isset($response['custom_5'] : '')
	, $user->publisher->user->api_key);
```

## Passing Custom Parameters <a href="#passing-custom-parameters" id="passing-custom-parameters"></a>

To pass custom parameters to server-side conversion callbacks and clientside callbacks, the function <mark style="color:red;">`AyetVideoSdk.setCustomParameter('custom_n', 'value')`</mark> is available.&#x20;

Where:

&#x20;<mark style="color:red;">`custom_n`</mark> can be one of these: `custom_1, custom_2, custom_3, custom_4, custom_5`. `value` is a string (up to 64 chars).

{% hint style="info" %}
Custom Parameters are up to **64 chars** of length!
{% endhint %}

<mark style="color:red;">`AyetVideoSdk.setCustomParameter`</mark> can be called any time with the most recent content used when a video view is completed.

```php
/* Example of setting custom parameters: */
AyetVideoSdk.setCustomParameter("custom_1", "bar");
AyetVideoSdk.setCustomParameter("custom_3", "foo");

/* Example of unsetting custom parameter: */
AyetVideoSdk.setCustomParameter("custom_1", null);
```

## Error Handling / Error Codes <a href="#error-handling-error-codes" id="error-handling-error-codes"></a>

There are two different callback methods for errors in the <mark style="color:red;">`ayetvideosdk`</mark>:

1. The global <mark style="color:red;">`AyetVideoSdk.callbackError`</mark> function that can be configured and is invoked for any type of callback errors: <mark style="color:red;">`AyetVideoSdk.callbackError = function(e)`</mark> <mark style="color:red;">`{console.log("callbackError: "+JSON.stringify(e));};`</mark>
2. The local error function in <mark style="color:red;">`AyetVideoSdk.requestAd(adslotName, successFunction, errorFunction);`</mark> that is invoked if an ad request did not succeed

**Possible error messages for `AyetVideoSdk.callbackError`:**

| <mark style="color:red;">`no adTagUrl set, no video ad available.`</mark>                                    | No ad was requested using `requestAd` or the request was unsuccessful.                        |
| ------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------- |
| <mark style="color:red;">`provided ad unit did not start.`</mark>                                            | The player was unable to start the playback of the video.                                     |
| <mark style="color:red;">`provided ad unit stalled.`</mark>                                                  | The video playback was interrupted for > 5 seconds and aborted (for ex. network issues).      |
| <mark style="color:red;">`provided ad unit is corrupt.`</mark>                                               | The video file or companion ads are corrupted or not supported (for ex. codecs).              |
| <mark style="color:red;">`all bids expired or contained invalid VAST responses, unable to render ad.`</mark> | No valid bids response was found or all bids responses are expired (please request a new ad). |
| <mark style="color:red;">`unrecoverable ad error: {message}`</mark>                                          | Other video player or VAST parser errors that were not covered above.                         |

**Possible error messages for the `AyetVideoSdk.requestAd(...)` error callback:**

| <mark style="color:red;">`no fill.`</mark>                    | This is expected behaviour: There is currently no video ad available for the device & user.                |
| ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| <mark style="color:red;">`unhandled client exception.`</mark> | Unspecified exception in the `ayetvideosdk` during ad request.                                             |
| <mark style="color:red;">`invalid server response.`</mark>    | Error communicating with our servers, check your internet connection & make sure ad blockers are disabled. |
| <mark style="color:red;">`cap reached.`</mark>                | The user/device video cap has been reached.                                                                |

## Conversion Callbacks & Currency Handling <a href="#conversion-callbacks-and-currency-handling" id="conversion-callbacks-and-currency-handling"></a>

Learn about:

* Setting up callbacks
* IP Whitelists
* Securing callbacks using HMAC Security Hash
* Testing callbacks

Click on the link below:

{% content-ref url="/pages/5sxVWIW1fto5Mmv1JxeJ" %}
[Callbacks & Testing](/v/product-docs/callbacks-and-testing.md)
{% endcontent-ref %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.ayetstudios.com/v/product-docs/rewarded-video/web-integrations/rewarded-video-sdk-for-html5.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
