Skip to content

Balancy JavaScript API

Overview

The balancy namespace provides access to backend data, user profiles, purchases, and platform-specific functionality. All methods are available globally in your View JavaScript.

Namespace

All Balancy methods and classes are under the balancy global object:

balancy.getSystemProfileValue('GeneralInfo.Level')
balancy.closeView('Purchase completed')
balancy.ElementsManager.instantiate(element)

DOM & Element Queries

balancy.findDomElement(dataId, parentElement?)

Finds an element with the specified data-id attribute.

Parameters:

  • dataId (string): The data-id value to search for
  • parentElement (HTMLElement, optional): Parent element to search within (defaults to document)

Returns: HTMLElement | null

Example:

const headerElement = balancy.findDomElement('window-header');
const button = balancy.findDomElement('claim-button', headerElement);


balancy.setImage(element, sprite)

Sets an image on an HTML element using a Balancy sprite object.

Parameters:

  • element (HTMLElement): Target element (IMG tag or element with background)
  • sprite (object): Sprite object with id property

Example:

const iconElement = document.getElementById('reward-icon');
balancy.setImage(iconElement, reward.item.unnyIcon);


Profile & Data Access

balancy.getSystemProfileValue(path)

Retrieves a value from the system profile (UnnyProfile).

Parameters:

  • path (string): Dot-separated path to the desired value

Returns: Promise<any>

Example:

const playerLevel = await balancy.getSystemProfileValue('GeneralInfo.Level');
//playerLevel = 5

const generalInfo = await balancy.getSystemProfileValue('GeneralInfo');
//generalInfo = { level: 5, session: 68, country: "CY", ... }


balancy.getProfileValue(profile, path)

Retrieves a value from a specific custom profile.

Parameters:

  • profile (string): Profile name
  • path (string): Dot-separated path to the desired value

Returns: Promise<any>

Example:

const coins = await balancy.getProfileValue('PlayerData', 'Currency.Coins');


balancy.getDocumentValue(id, depth)

Retrieves a document from Balancy with specified depth.

Parameters:

  • id (string): Document ID
  • depth (number): Depth of nested objects to fetch (default: 3)

Returns: Promise<object>

Example:

const config = await balancy.getDocumentValue('245', 3);
console.info(config);


Offers & Shops

balancy.getActiveOffers(depth?)

Retrieves the list of all active offers.

Parameters:

  • depth (number, optional): How deep to extract nested objects (default: 3)

Returns: Promise<OfferInfo[]>

Example:

const offers = await balancy.getActiveOffers();
// offers = [{ instanceId: "...", gameOffer: {...}, ... }]


balancy.getActiveGroupOffers(depth?)

Retrieves the list of all active group offers.

Parameters:

  • depth (number, optional): How deep to extract nested objects (default: 3)

Returns: Promise<OfferGroupInfo[]>

Example:

const groupOffers = await balancy.getActiveGroupOffers();


balancy.canBuyGroupOffer(index)

Checks if a group offer can be purchased.

Parameters:

  • index (number): Offer index within the group

Returns: Promise<boolean>

Example:

const canBuy = await balancy.canBuyGroupOffer(0);
document.getElementById('buy-button').disabled = !canBuy;


Purchases

balancy.buyOffer()

Purchases the current offer (uses window.balancyViewOwner context).

Returns: Promise<PurchaseResult>

Example:

try {
    const result = await balancy.buyOffer();
    console.log('Purchase successful:', result);
} catch (error) {
    console.error('Purchase failed:', error);
}


balancy.buyGroupOffer(index)

Purchases a specific offer from a group.

Parameters:

  • index (number): Offer index within the group

Returns: Promise<PurchaseResult>

Example:

const result = await balancy.buyGroupOffer(0);


balancy.buyShopSlot(slotId)

Purchases a shop slot.

Parameters:

  • slotId (string): The slot identifier

Returns: Promise<PurchaseResult>

Example:

const result = await balancy.buyShopSlot('slot-123');


balancy.getProductInfo(product)

Gets IAP product information from the platform store.

Parameters:

  • product (object): Product document

Returns: Promise<ProductInfo>

Example:

const productInfo = await balancy.getProductInfo(price.product);
console.log(productInfo.LocalizedPriceString);  // "$4.99"


Resource Management

balancy.haveEnoughResources(storeItem)

Checks if the player has enough resources to purchase a store item.

Parameters:

  • storeItem (object): StoreItem document

Returns: Promise<boolean>

Example:

const canAfford = await balancy.haveEnoughResources(storeItem);
if (!canAfford) {
    button.disabled = true;
    button.classList.add('insufficient-funds');
}


balancy.getInventoryItemsCount(itemId)

Gets the count of an inventory item.

Parameters:

  • itemId (string): Item identifier

Returns: Promise<number>

Example:

const coinCount = await balancy.getInventoryItemsCount('coins');
console.log(`Player has ${coinCount} coins`);


balancy.addInventoryItems(itemId, amount)

Adds items to player inventory.

Parameters:

  • itemId (string): Item identifier
  • amount (number): Amount to add

Returns: Promise<void>

Example:

await balancy.addInventoryItems('gems', 100);


balancy.removeInventoryItems(itemId, amount)

Removes items from player inventory.

Parameters:

  • itemId (string): Item identifier
  • amount (number): Amount to remove

Returns: Promise<void>

Example:

const currentCount = await balancy.getInventoryItemsCount('coins');
if (currentCount >= 50) {
    await balancy.removeInventoryItems('coins', 50);
}


Localization

balancy.getLocalizedText(key)

Gets localized text for the specified key.

Parameters:

  • key (string): Localization key

Returns: Promise<string>

Example:

const welcomeText = await balancy.getLocalizedText('welcome_message');
document.getElementById('title').textContent = welcomeText;


balancy.getImageUrl(id)

Gets the URL for an image asset.

Parameters:

  • id (string): Image asset ID

Returns: Promise<string>

Example:

const imageUrl = await balancy.getImageUrl('123');
document.getElementById('icon').src = imageUrl;


View Control

balancy.closeView(source)

Closes the current view.

Parameters:

  • source (string): Reason for closing (for debugging)

Example:

balancy.closeView('Purchase completed');
balancy.closeView('User clicked close');


balancy.sendIsReady()

Notifies the SDK that the view is ready to be shown.

Example:

function main() {
    balancy.delayIsReady();

    // Load async data...
    await loadData();

    balancy.sendIsReady();
}
window.addEventListener('balancy-ready', main, { once: true });


balancy.delayIsReady()

Delays the automatic ready signal, giving you control over when the view is shown.

Example:

balancy.delayIsReady();

// Perform async initialization
await initializeView();

// Signal ready when done
balancy.sendIsReady();


Battle Pass

balancy.getBattlePassConfig()

Gets the configuration for the current battle pass.

Returns: Promise<BattlePassConfig>

Example:

const config = await balancy.getBattlePassConfig();
console.log('Scores required:', config.scores);
console.log('Reward lines:', config.rewards);

Response Structure:

{
    unnyId: "995",
    name: "KEY_SEASON_PASS_NAME",
    scores: [10, 20, 30, 40, 50, 60],  // XP required for each level
    rewards: [
        {
            unnyId: "1007",
            name: "Free Track",
            rewards: [/* ItemWithAmount objects */]
        }
    ]
}


balancy.getBattlePassProgress()

Gets the current player's battle pass progress.

Returns: Promise<BattlePassProgress>

Example:

const progress = await balancy.getBattlePassProgress();
console.log('Current level:', progress.level);
console.log('Current XP:', progress.scores);

Response Structure:

{
    level: 1,
    scores: 15,
    finished: false,
    progressInfo: [
        {
            progress: [1, 0, 0, 0, 0, 0],  // 0=locked, 1=available, 2=claimed
            available: true,
            unnyIdReward: "1007"
        }
    ]
}


balancy.claimBattlePassReward(lineId, index)

Claims a battle pass reward.

Parameters:

  • lineId (string): Reward line ID
  • index (number): Level index to claim

Returns: Promise<boolean>

Example:

const success = await balancy.claimBattlePassReward('1007', 0);
if (success) {
    console.log('Reward claimed successfully!');
}


Ads

balancy.watchRewardedAd(callback)

Triggers a rewarded ad display.

Parameters:

  • callback (function): Function that receives boolean indicating success

Returns: Promise<void>

Example:

balancy.watchRewardedAd((success) => {
    if (success) {
        console.log('Ad watched successfully!');
        grantReward();
    } else {
        console.log('Ad was not watched.');
    }
});


balancy.getRewardedAdsWatchedForStoreItem(storeItem)

Gets the count of rewarded ads watched for a specific store item.

Parameters:

  • storeItem (object): StoreItem document

Returns: Promise<number>

Example:

const adsWatched = await balancy.getRewardedAdsWatchedForStoreItem(storeItem);
console.log(`Watched ${adsWatched} ads for this item`);


Tasks & Events

balancy.getTasks()

Gets the list of active tasks.

Returns: Promise<Task[]>

Example:

const tasks = await balancy.getTasks();
for (const task of tasks) {
    console.log(task.name, task.status);
}


balancy.claimTaskReward(taskId)

Claims a task reward.

Parameters:

  • taskId (string): Task identifier

Returns: Promise<boolean>

Example:

const success = await balancy.claimTaskReward('daily-quest-1');


balancy.restoreFailedTask(task)

Restores a failed task (e.g., for win streak recovery).

Parameters:

  • task (object): The task object with status === balancy.TaskStatus.Failed

Returns: Promise<boolean>

Example:

const tasks = await balancy.getTasks();
const failedTask = tasks.find(t => t.status === balancy.TaskStatus.Failed);

if (failedTask) {
    const restored = await balancy.restoreFailedTask(failedTask);
    console.log('Task restored:', restored);
}


balancy.activateTasks(taskIds)

Activates tasks for an event.

Parameters:

  • taskIds (string[]): Array of task IDs

Returns: Promise<Task[]>

Example:

const tasks = await balancy.activateTasks(['quest-1', 'quest-2']);


balancy.deactivateTasks(taskIds)

Deactivates tasks.

Parameters:

  • taskIds (string[]): Array of task IDs

Returns: Promise<void>

Example:

await balancy.deactivateTasks(['quest-1', 'quest-2']);


balancy.getCustomEventInfo()

Gets custom event data stored on the backend.

Returns: Promise<any>

Example:

const eventData = await balancy.getCustomEventInfo();
console.log('Event progress:', eventData.progress);


balancy.setCustomEventInfo(data)

Saves custom event data to the backend.

Parameters:

  • data (any): Data to save (will be JSON serialized)

Returns: Promise<void>

Example:

await balancy.setCustomEventInfo({
    started: true,
    progress: 50,
    lastCheckpoint: 'level-3'
});


Custom Messages

Balancy provides two-way communication between your game code and Views. For complete documentation on custom messages including SDK-side setup, see Working with Views - Custom Messages.

balancy.sendCustomMessage(sender, params)

Send a custom message from JavaScript to your game code and receive a response.

Parameters:

  • sender (string): Message identifier
  • params (object): Data to send

Returns: Promise<any> - Response from game code

Example:

balancy.sendCustomMessage('my_button', {
    param: 'myParam',
    value: 42
}).then(response => {
    console.info("Custom message response:", response);
}).catch(error => {
    console.error("Custom message error:", error);
});

Default Response:

{
  "status": "ok"
}

SDK Setup:

To intercept and respond to custom messages, see Custom Messages Documentation.


balancy.subscribeToCustomMessages(callback)

Subscribe to custom messages broadcast from the game.

Parameters:

  • callback (function): Handler function that receives message data

Returns: function - Unsubscribe function

Example:

// Method 1: Subscribe with callback (recommended)
const unsubscribe = balancy.subscribeToCustomMessages((data) => {
    console.info('Received custom message:', data);

    if (data.action === 'greeting') {
        console.log('Message:', data.message);
    }
});

// Unsubscribe later
unsubscribe();

// Method 2: Listen to DOM event
window.addEventListener('balancy-custom-message', (event) => {
    console.log('Received custom message:', event.detail);
});

SDK Setup:

To send messages from your game to Views, see Broadcasting Messages Documentation.


Formatting Utilities

balancy.formatTime(seconds)

Formats time duration into a human-readable string.

Parameters:

  • seconds (number): Duration in seconds

Returns: string

Example:

const formatted = balancy.formatTime(7200);
// Returns: "2h"

const formatted2 = balancy.formatTime(86400);
// Returns: "1d"

const formatted3 = balancy.formatTime(125);
// Returns: "02:05"


balancy.getTimeLeft()

Gets remaining time based on balancySettings.

Returns: number - Seconds remaining

Example:

const timeLeft = balancy.getTimeLeft();
document.getElementById('timer').textContent = balancy.formatTime(timeLeft);


balancy.formatDataTemplate(formatStr, data)

Formats a template string with data values. Supports nested object access and automatic document resolution.

Parameters:

  • formatStr (string): Template string with {path} placeholders
  • data (object): Data object

Returns: Promise<string>

Example - Basic:

const template = "You have {currency.coins} coins and level {level}";
const data = { currency: { coins: 100 }, level: 5 };
const result = await balancy.formatDataTemplate(template, data);
// Returns: "You have 100 coins and level 5"

Example - Document Resolution:

// If data.gameOffer is null but data.unnyIdGameOffer exists,
// the method automatically fetches the document
const template = "{gameOffer.name}";
const data = {
    gameOffer: null,
    unnyIdGameOffer: "1188"
};
const result = await balancy.formatDataTemplate(template, data);
// Returns: "DEFAULT/offer_name_key"


balancy.formatItemCount(itemWithAmount, options)

Formats an item count based on type (currency, time, regular).

Parameters:

  • itemWithAmount (object): ItemWithAmount document
  • options (object): Formatting options

Returns: { text: string, isCurrency: boolean, isDuration: boolean }

Example:

const result = balancy.formatItemCount(item, {
    timeFormat: 2,              // LocalizedCompact
    currencyFormat: 0,          // Plain
    regularItemFormat: 2,       // WithPrefix
    timePrecision: 0            // Auto
});

console.log(result.text);  // "x50" or "100" or "5h 32m"


balancy.formatItemsCount(itemWithAmount, includePrefix) 🗑️ OBSOLETE

⚠️ This method is obsolete. Use balancy.formatItemCount() instead for more control over formatting options.

Formats an item count based on type (currency, time, regular).

Parameters:

  • itemWithAmount (object): ItemWithAmount document
  • includePrefix (boolean): Whether to include "x" prefix for regular items

Returns: { text: string, isCurrency: boolean, isDuration: boolean }

Example:

// ⚠️ Obsolete - use formatItemCount() instead
const format = balancy.formatItemsCount(reward, true);
console.log(format.text);  // "x50" or "100" or "5h 32m"

// ✓ Recommended: Use formatItemCount() for better control
const result = balancy.formatItemCount(item, {
    timeFormat: 2,
    currencyFormat: 0,
    regularItemFormat: 2,
    timePrecision: 0
});

balancy.shortenCount(count)

Shortens large numbers with K/M/B suffixes.

Parameters:

  • count (number): Number to shorten

Returns: string

Example:

balancy.shortenCount(1500);      // "1.5K"
balancy.shortenCount(1000000);   // "1M"
balancy.shortenCount(500);       // "500"


balancy.formatString(template, ...values)

Formats a template string with indexed placeholders.

Parameters:

  • template (string): Template with {0}, {1}, etc.
  • ...values (any[]): Values to insert

Returns: string

Example:

const message = balancy.formatString(
    'You earned {0} coins and {1} XP!',
    500,
    150
);
// Returns: "You earned 500 coins and 150 XP!"


balancy.itemHasDecayEffect(item)

Checks if an item has a decay/time-limited effect.

Parameters:

  • item (object): Item document

Returns: boolean

Example:

if (balancy.itemHasDecayEffect(item)) {
    // Show timer icon
    timerIcon.style.display = '';
}


Prefab & Element Management

balancy.instantiatePrefab(prefabId)

Loads and instantiates a prefab by ID.

Parameters:

  • prefabId (string): The prefab identifier

Returns: Promise<HTMLElement>

Example:

const element = await balancy.instantiatePrefab('3871');
document.body.appendChild(element);


balancy.instantiatePrefabById(prefabId)

Loads, instantiates, and returns an ElementObject for a prefab.

Parameters:

  • prefabId (string): The prefab identifier

Returns: Promise<ElementObject>

Example:

const cardObject = await balancy.instantiatePrefabById('item-card');
const buyButton = cardObject.getComponent(Balancy_UI_Common_BuyButton);
buyButton.init({ price: myPrice });

document.body.appendChild(cardObject.element);


Global Variables

window.balancyViewOwner

Contains context information about the current view.

Structure:

{
    instanceId: "offer_123",        // Current offer/event instance ID
    unnyIdGameEvent: "663",         // Game event ID (for battle pass, etc.)
    unnyIdGameOffer: "1188",        // Game offer ID
    productId: "coin_pack_small",   // Product ID for purchases
    // ... other custom fields
}

Example:

const offerId = window.balancyViewOwner.unnyIdGameOffer;
const offerDoc = await balancy.getDocumentValue(offerId, 3);


window.balancySettings

Contains view settings and timing information.

Structure:

{
    launchTime: 1751328000,  // Unix timestamp when view was launched
    secondsLeft: 86400       // Seconds remaining for time-limited content
}

Example:

const timeLeft = balancy.getTimeLeft();  // Uses balancySettings.secondsLeft


window.customFormatTime(seconds) 🗑️ OBSOLETE

⚠️ This override method is obsolete. Instead of using global function overrides, create custom script components that handle time formatting.

Override the default time formatting behavior.

Parameters:

  • seconds (number): Duration in seconds

Returns: string - Formatted time string

Example:

// ⚠️ Obsolete - use custom components instead
window.customFormatTime = function(seconds) {
    if (seconds < 60) return `${seconds}s`;
    if (seconds < 3600) return `${Math.floor(seconds/60)}m`;
    return `${Math.floor(seconds/3600)}h`;
};

// ✓ Recommended: Create a custom component
class CustomTimer extends balancy.ElementBehaviour {
    // @serialize {element}
    timerText = null;

    formatTime(seconds) {
        if (seconds < 60) return `${seconds}s`;
        if (seconds < 3600) return `${Math.floor(seconds/60)}m`;
        return `${Math.floor(seconds/3600)}h`;
    }

    update(deltaTime) {
        const timeLeft = balancy.getTimeLeft();
        this.timerText.element.textContent = this.formatTime(timeLeft);
    }
}

Why it's obsolete:

  • Global function overrides make code harder to maintain
  • Component-based approach is more reusable
  • Better for team collaboration
  • Easier to test and debug

Learn more: Prefabs & Components


Constants & Enums

RequestAction

balancy.RequestAction = {
    None: 0,
    GetProfile: 1,
    SetProfile: 2,
    GetDocument: 3,
    GetLocalization: 10,
    GetImageUrl: 11,
    GetInfo: 12,
    CanBuyGroupOffer: 13,
    GetBattlePassProgress: 20,
    GetCustomEventInfo: 21,
    SetCustomEventInfo: 22,
    GetTasksInfoForTheEvent: 23,
    ActivateTasksForTheEvent: 24,
    DeactivateTasksForTheEvent: 25,
    ClaimTaskReward: 26,
    GetCustomDocumentInfo: 27,
    SetCustomDocumentInfo: 28,
    StopEventManually: 29,
    GetInventoryItemsCount: 30,
    AddInventoryItems: 31,
    RemoveInventoryItems: 32,
    WatchRewardedAd: 40,
    RestoreFailedTask: 41,
    BuyOffer: 101,
    BuyGroupOffer: 102,
    BuyShopSlot: 103,
    BattlePassClaim: 104,
    CloseWindow: 200,
    BalancyIsReady: 201,
    CustomMessage: 1000
};

InfoType

balancy.InfoType = {
    None: 0,
    OfferPrice: 1,
    OfferGroupPrice: 2,
    TimeLeft: 3,
    OwnerLocalizedKey: 4,
    OwnerCustom: 5,
    CustomPrice: 9,
    Custom: 10
};

BattlePassStatus

balancy.BattlePassStatus = {
    NotAvailable: 0,
    Available: 1,
    Claimed: 2
};

TaskStatus

balancy.TaskStatus = {
    Active: 0,
    Completed: 1,
    Failed: 2,
    Claimed: 3
};

PriceType

balancy.PriceType = {
    Hard: 1,   // Real money (IAP)
    Soft: 2,   // Virtual currency
    Ads: 3     // Rewarded ads
};

BuyButtonState

balancy.BuyButtonState = {
    Available: 0,    // Ready to purchase
    Unavailable: 1,  // Disabled
    Cooldown: 2,     // On cooldown with timer
    Locked: 3        // Locked with overlay
};

Best Practices

1. Handle Async Operations

// ✓ Good: Use async/await
async function loadData() {
    const level = await balancy.getSystemProfileValue('GeneralInfo.Level');
    const coins = await balancy.getProfileValue('Profile', 'Currency.Coins');
    updateUI(level, coins);
}

// ✗ Avoid: Not handling promises
function loadData() {
    const level = balancy.getSystemProfileValue('GeneralInfo.Level');  // This is a Promise!
    console.log(level);  // Logs: Promise { <pending> }
}

2. Check for Null/Undefined

// ✓ Good: Check before accessing
const offers = await balancy.getActiveOffers();
if (offers && offers.length > 0) {
    displayOffer(offers[0]);
}

// ✗ Avoid: Assuming data exists
const offers = await balancy.getActiveOffers();
displayOffer(offers[0]);  // May throw if offers is empty

3. Use Error Handling

// ✓ Good: Handle errors
try {
    const result = await balancy.buyOffer();
    showSuccess(result);
} catch (error) {
    console.error('Purchase failed:', error);
    showError(error.message);
}

// ✗ Avoid: No error handling
const result = await balancy.buyOffer();
showSuccess(result);  // What if it fails?

4. Clean Up Listeners

// ✓ Good: Unsubscribe when done
const unsubscribe = balancy.subscribeToCustomMessages(handler);

// Later...
unsubscribe();

// ✗ Avoid: Memory leaks
balancy.subscribeToCustomMessages(handler);
// Never unsubscribed - handler keeps running

Next Steps