Rewarded ads for Telegram Mini Apps
A rewarded ad is a placement a user chooses to watch in exchange for an in-app benefit. Adsun Reward blocks connect this experience to a JavaScript controller and a server-verified completion flow.

Rewarded ads vs interstitial ads
A rewarded placement makes the exchange explicit before playback: for example, a player may choose an ad to unlock an extra attempt. An interstitial appears at a natural break and does not need the same reward exchange. Task blocks are a separate Adsun format with their own element and events; do not reuse a Reward controller's event names for a Task placement.
Choose placements around the actual app experience, rather than treating every screen transition as an ad opportunity. Explain the reward before the user opts in, and handle unavailable ads without trapping the user.
Create and test an Adsun Reward block
- Add your Telegram Mini App in the publisher workspace and create a Reward block.
- Copy its integration code, including the deployed API address and block ID.
- Load the SDK, initialize the controller and connect an explicit user action to show().
- Test with debug enabled before switching the placement to production.
Debug mode is for integration testing: it does not create billable production activity or call the production Reward URL. Use the SDK integration guide for script loading and examples.
Completion events are not a reward ledger
The controller emits onReward after server-verified completion. It also exposes onStart, onComplete, onSkip, onError, onBannerNotFound, onNotSuitable and onProgress. A successful promise resolution alone is not proof that a user earned a reward: some non-reward outcomes can also resolve the show request.
Use the block's server-to-server Reward URL for authoritative grants. Your reward endpoint must validate incoming requests and make grants idempotent, so repeated notifications cannot issue the same benefit twice. Client events are useful for updating the interface, not as a replacement for your server's reward checks.
const ad = window.Adsun.init({
blockId: "YOUR_BLOCK_ID",
debug: true,
});
ad.addEventListener("onReward", () => {
// Refresh your UI from your own server's reward state.
});
ad.addEventListener("onBannerNotFound", () => {
// Keep the app usable when no eligible ad is available.
});
ad.show().catch(() => {
// Restore the interface after a playback error.
});Why might no ad appear?
Available demand, eligibility, campaign status and frequency settings affect delivery. A no-ad response is different from a broken SDK URL or a JavaScript exception. Test these cases separately; avoid a rapid retry loop that can hit cooldown controls. Review the block's SDK health panel and reporting when diagnosing live behavior.
What should publishers measure?
Compare requests, impressions, clicks, fill rate and earnings over the same date range. Publisher eCPM is realized earnings per thousand impressions, not a guaranteed price for every request. Audience mix and completed billable events affect earnings. The CPM, CPC, CTR and eCPM guide explains the denominators and worked examples.