PlaySuper LogoPlaySuper
API Reference

Touchpoints API Reference

Complete API reference for the PlaySuper Touchpoints system - REST endpoints and Unity SDK integration

Touchpoints API Reference

Touchpoints are visual widget configurations that define how rewards, products, and promotional content appear in your game. Each touchpoint contains a tree of nodes with visual assets, text, and optional linked data (rewards or products).


Table of Contents

  1. Authentication
  2. REST API Endpoints
  3. Unity SDK Methods
  4. Data Types Reference
  5. Example Touchpoints
  6. Unity Usage Examples
  7. Error Handling

Authentication

All endpoints require authentication headers. The Unity SDK handles these automatically when initialized.

HeaderDescriptionRequired
x-api-keyYour game's API keyYes
AuthorizationPlayer JWT token (Bearer)Yes

Unity SDK Setup:

// Initialize once at game start
PlaySuperUnitySDK.Init("gk_xxxx-xxxx-xxxx");

// Authentication is handled automatically after player login

REST API Endpoints

List All Touchpoints

Retrieves all active touchpoints for your game with hydrated node data.

GET /touchpoints?coinId={coinId}

Query Parameters:

ParameterTypeRequiredDescription
coinIdstringYesCoin ID for pricing calculations

Get Touchpoint by Name

Retrieves a single touchpoint by its unique name. This is the primary runtime API for games.

GET /touchpoints/name/{name}?coinId={coinId}

Path Parameters:

ParameterTypeRequiredDescription
namestringYesUnique touchpoint name

Query Parameters:

ParameterTypeRequiredDescription
coinIdstringYesCoin ID for pricing calculations

Get Touchpoint by ID

Retrieves a single touchpoint by its UUID.

GET /touchpoints/{id}?coinId={coinId}

Path Parameters:

ParameterTypeRequiredDescription
idstring (UUID)YesTouchpoint UUID

Query Parameters:

ParameterTypeRequiredDescription
coinIdstringYesCoin ID for pricing calculations

Unity SDK Methods

All touchpoint methods are in the TouchpointManager class under the PlaySuperUnity namespace.

GetTouchpointByName

Retrieves a touchpoint by its unique name. Recommended for most use cases.

public static async Task<TouchpointResponse> GetTouchpointByName(string name, string coinId)

Parameters:

ParameterTypeDescription
namestringTouchpoint name (e.g., "Main Store")
coinIdstringCoin ID for pricing calculations

Returns: Task<TouchpointResponse> - The touchpoint data or null on error.

Example:

TouchpointResponse store = await TouchpointManager.GetTouchpointByName("flash-sale-card", "coin-uuid-abcd");

if (store != null)
{
    Debug.Log($"Loaded: {store.name} with {store.nodes?.Length ?? 0} nodes");
}

GetTouchpointById

Retrieves a touchpoint by its UUID. Useful for deep links or saved references.

public static async Task<TouchpointResponse> GetTouchpointById(string id, string coinId)

Parameters:

ParameterTypeDescription
idstringTouchpoint UUID
coinIdstringCoin ID for pricing calculations

Returns: Task<TouchpointResponse> - The touchpoint data or null on error.

Example:

TouchpointResponse offer = await TouchpointManager.GetTouchpointById(
    "6f9a5737-0247-4a71-89eb-b5d02212f179",
    "coin-uuid-abcd"
);

ListTouchpoints

Retrieves all active touchpoints for the game.

public static async Task<TouchpointListResponse> ListTouchpoints(string coinId)

Parameters:

ParameterTypeDescription
coinIdstringCoin ID for pricing calculations

Returns: Task<TouchpointListResponse> - List of touchpoints or null on error.

Example:

TouchpointListResponse list = await TouchpointManager.ListTouchpoints("coin-uuid-abcd");

if (list != null)
{
    Debug.Log($"Found {list.total} touchpoints");
    foreach (var tp in list.touchpoints)
    {
        Debug.Log($"- {tp.name} (ID: {tp.id})");
    }
}

Data Types Reference

TouchpointResponse

Root response object for a single touchpoint.

public class TouchpointResponse
{
    public string id;           // Touchpoint UUID
    public string gameId;       // Game UUID
    public string name;         // Unique touchpoint name
    public TouchpointNode[] nodes;  // Array of root nodes
}

TouchpointListResponse

Response for listing multiple touchpoints.

public class TouchpointListResponse
{
    public TouchpointResponse[] touchpoints;  // Array of touchpoints
    public int total;                         // Total count
}

TouchpointNode

Represents a single element in the touchpoint tree.

public class TouchpointNode
{
    // Identity
    public string id;                    // Node UUID
    public int displayOrder;             // Sort order

    // Visual Assets
    public BackgroundConfig background;  // Background configuration
    public string[] images;              // Primary content images
    public BackgroundConfig overlay;     // Overlay configuration
    public string[] additionalAssets;    // Secondary assets

    // Text Content
    public TextItem[] title;             // Title text segments
    public TextItem[] subtitle;          // Subtitle text segments

    // Interactive Elements
    public BadgeConfig badge;            // Badge configuration
    public CtaConfig cta;                // Call-to-action configuration

    // Data References
    public string rewardId;              // Linked reward ID
    public string productId;             // Linked product ID

    // Dynamic Configuration
    public DynamicConfig dynamicConfig;  // For dynamic fetching

    // Layout
    public string layoutHint;            // Layout type hint
    public JObject styleHint;            // Additional styling metadata

    // Hydrated Data
    public JToken data;                  // Populated reward/product data

    // Nested Content
    public TouchpointNode[] nodes;       // Child nodes
    public TouchpointNode popup;         // Popup node (opens on tap)
}

Helper Properties

PropertyTypeDescription
HasRewardboolTrue if node contains reward data
HasProductboolTrue if node contains product data

Helper Methods

MethodReturnsDescription
GetData<T>(key, defaultValue)TGet value from hydrated data object
GetStyleHint<T>(key, defaultValue)TGet value from styleHint object
GetReward()HydratedRewardGet typed reward data
GetProduct()HydratedProductGet typed product data

BackgroundConfig

Configuration for backgrounds and overlays.

public class BackgroundConfig
{
    public string color;       // e.g., "#1A1A2E"
    public string gradient;    // e.g., "linear-gradient(...)"
    public string[] images;    // Background image URLs
    public float? opacity;     // 0-1
}

TextItem

Text segment with styling.

public class TextItem
{
    public string text;        // Text content
    public string color;       // Text color
    public float? fontSize;    // Font size
    public string fontWeight;  // e.g., "bold"
    public string icon;        // Icon URL
}

BadgeConfig

Badge configuration.

public class BadgeConfig
{
    public string text;            // Badge text
    public string backgroundImage; // Badge background URL
    public string icon;            // Badge icon URL
    public JObject style;          // Additional styling
}

CtaConfig

Call-to-action configuration.

public class CtaConfig
{
    public string text;            // Button text
    public string action;          // Action URL or deep link
    public string backgroundImage; // Button background URL
    public string frontImage;      // Button front image URL
    public JObject style;          // Additional styling
}

DynamicConfig

Configuration for dynamic data fetching.

public class DynamicConfig
{
    public string source;      // Data source
    public int? limit;         // Result limit
    public string sortBy;      // Sort field
    public string sortOrder;   // "asc" or "desc"
    public JObject filters;    // Filter criteria
}

HydratedReward

Populated reward data.

public class HydratedReward
{
    public string id;
    public string name;
    public string description;
    public string brandName;
    public string organizationId;
    public string brandRedirectionLink;
    public RewardMetadata metadata;
    public InventoryInfo inventory;
    public PriceInfo[] price;
}

RewardMetadata

Detailed reward metadata.

public class RewardMetadata
{
    public string brandName;
    public string[] brandCategory;
    public string brandLogoImage;
    public string campaignTitle;
    public string campaignSubTitle;
    public string campaignCoverImage;
    public string campaignDetails;
    public string termsAndConditions;
    public string howToRedeem;
    public string brandRedirectionLink;
    public bool? couponExpiryDateExists;
    public string couponExpiryDate;
    public string type;
}

HydratedProduct

Populated product data.

public class HydratedProduct
{
    public string id;
    public string type;
    public string productId;
    public string title;
    public string description;
    public string image;
    public float? price;
    public float? originalPrice;
    public string currency;
    public string url;
    public JObject metadata;
}

InventoryInfo

Inventory information.

public class InventoryInfo
{
    public int availableQuantity;
    public string type;
}

PriceInfo

Price information.

public class PriceInfo
{
    public float amount;
    public string coinId;
}

Example Touchpoints

1. Flash Sale Card (ASSET Type)

A promotional banner with countdown timer - pure visual assets, no linked rewards.

{
  "id": "uuid",
  "gameId": "uuid",
  "name": "flash-sale-card",
  "nodes": [
    {
      "id": "uuid",
      "displayOrder": 0,
      "layoutHint": "flash-sale-card",
      "background": {
        "images": ["https://.../{gameId}/flash-sale-card/nodes/0/bg.png"]
      },
      "images": [
        "https://.../{gameId}/flash-sale-card/nodes/0/product.png",
        "https://.../{gameId}/flash-sale-card/nodes/0/flash-sale-logo.png"
      ],
      "badge": {
        "text": "Up to 85%",
        "backgroundImage": "https://.../{gameId}/flash-sale-card/nodes/0/badge.png"
      },
      "cta": {
        "action": "https://store.playsuper.club/gcommerce"
      },
      "styleHint": {
        "timerEnabled": true
      }
    }
  ]
}

2. Refer & Earn (STATIC Type with Popup)

A list of reward banners that open popups when tapped.

{
  "id": "6f9a5737-0247-4a71-89eb-b5d02212f179",
  "name": "refer-and-earn",
  "nodes": [
    {
      "id": "0f171ae3-da25-4f09-b200-b3c318123e8f",
      "displayOrder": 0,
      "images": ["https://.../refer-and-earn/nodes/0/img.png"],
      "rewardId": "6ab8709b-4be9-4b84-b69b-7944e6d69b30",
      "layoutHint": "banner-card",
      "popup": {
        "id": "508c3f3b-074e-4c39-8c58-2a249218ecb6",
        "displayOrder": 0,
        "images": ["https://.../refer-and-earn/nodes/0/popup/img.png"],
        "title": [{ "text": "Woohoo!", "color": "#FFFFFF" }],
        "subtitle": [{ "text": "Get your coupon", "color": "#FFFFFF" }],
        "cta": {
          "text": "Get it for FREE",
          "action": "https://store.playsuper.club/rewards/..."
        },
        "layoutHint": "popup-card",
        "data": {
          /* HydratedReward */
        }
      },
      "data": {
        /* HydratedReward */
      }
    }
  ]
}

3. FTUE Onboarding Flow (Nested Nodes)

A container with multiple child cards for onboarding.

{
  "id": "uuid",
  "name": "FTUE",
  "nodes": [
    {
      "id": "container-uuid",
      "displayOrder": 0,
      "layoutHint": "container",
      "background": { "images": ["https://.../FTUE/nodes/0/bg.png"] },
      "title": [
        {
          "text": "Win Matches & Get Discount!",
          "color": "#FFFFFF",
          "fontSize": 20,
          "fontWeight": "bold"
        }
      ],
      "cta": {
        "text": "Shop Now",
        "action": "navigate:/shop",
        "backgroundImage": "https://.../FTUE/nodes/0/cta.png"
      },
      "nodes": [
        {
          "id": "card-1-uuid",
          "displayOrder": 0,
          "layoutHint": "card",
          "images": ["https://.../FTUE/nodes/0/nodes/0/img.png"],
          "cta": { "text": "Play Game", "action": "navigate:/game" }
        },
        {
          "id": "card-2-uuid",
          "displayOrder": 1,
          "layoutHint": "card",
          "images": ["https://.../FTUE/nodes/0/nodes/1/img.png"],
          "cta": { "text": "Earn Gems", "action": "navigate:/gems" }
        }
      ]
    }
  ]
}

4. Exclusive Deal Widget (Layered Assets)

A home screen widget with multiple layers.

{
  "id": "uuid",
  "name": "home-exclusive-deal-widget",
  "nodes": [
    {
      "id": "uuid",
      "displayOrder": 0,
      "layoutHint": "card",
      "background": { "images": ["https://.../nodes/0/bg.png"] },
      "images": ["https://.../nodes/0/img.png"],
      "overlay": {
        "images": [
          "https://.../nodes/0/overlay-1.png",
          "https://.../nodes/0/overlay-2.png"
        ]
      },
      "badge": { "backgroundImage": "https://.../nodes/0/badge.png" },
      "styleHint": {
        "aspectRatio": "1:1",
        "cornerRadius": 12
      }
    }
  ]
}

Unity Usage Example

Accessing Flash Sale Card Fields

using UnityEngine;
using PlaySuperUnity;

public class FlashSaleExample : MonoBehaviour
{
    async void Start()
    {
        // Fetch the touchpoint
        TouchpointResponse flashSale = await TouchpointManager.GetTouchpointByName(
            "flash-sale-card",
            "coin-uuid-abcd"
        );

        if (flashSale?.nodes?.Length > 0)
        {
            TouchpointNode node = flashSale.nodes[0];

            // === BASIC FIELDS ===
            string nodeId = node.id;                     // Node UUID
            int order = node.displayOrder;               // 0
            string layout = node.layoutHint;             // "flash-sale-card"

            // === BACKGROUND ===
            string bgImage = node.background?.images?[0];  // bg.png URL

            // === PRIMARY IMAGES ===
            string productImage = node.images?[0];         // product.png URL
            string logoImage = node.images?[1];            // flash-sale-logo.png URL

            // === BADGE ===
            string badgeText = node.badge?.text;           // "Up to 85%"
            string badgeBgImage = node.badge?.backgroundImage;  // badge.png URL

            // === CTA ===
            string ctaAction = node.cta?.action;           // "https://store.playsuper.club/gcommerce"
            string ctaText = node.cta?.text;               // Button text (if provided)

            // === STYLE HINTS ===
            bool timerEnabled = node.GetStyleHint<bool>("timerEnabled", false);  // true
            float cornerRadius = node.GetStyleHint<float>("cornerRadius", 0);
            string aspectRatio = node.GetStyleHint<string>("aspectRatio", null);

            // === OVERLAY (if present) ===
            string overlayImage = node.overlay?.images?[0];

            // === TITLE/SUBTITLE (if present) ===
            string titleText = node.title?[0]?.text;
            string titleColor = node.title?[0]?.color;
            float? titleFontSize = node.title?[0]?.fontSize;

            // === NESTED NODES (if present) ===
            if (node.nodes?.Length > 0)
            {
                foreach (var childNode in node.nodes)
                {
                    // Access child node fields the same way
                }
            }

            // === POPUP (if present) ===
            if (node.popup != null)
            {
                string popupTitle = node.popup.title?[0]?.text;
                string popupCtaText = node.popup.cta?.text;
            }

            // === REWARD DATA (if node has rewardId) ===
            if (node.HasReward)
            {
                HydratedReward reward = node.GetReward();
                string brandName = reward?.brandName;
                string campaignTitle = reward?.metadata?.campaignTitle;
                float? price = reward?.price?[0]?.amount;
            }

            // === PRODUCT DATA (if node has productId) ===
            if (node.HasProduct)
            {
                HydratedProduct product = node.GetProduct();
                string productTitle = product?.title;
                float? productPrice = product?.price;
            }
        }
    }
}

Field Access Quick Reference

FieldAccess Pattern
Background imagenode.background?.images?[0]
Primary imagesnode.images?[0], node.images?[1]
Badge textnode.badge?.text
Badge backgroundnode.badge?.backgroundImage
CTA actionnode.cta?.action
CTA textnode.cta?.text
Layout hintnode.layoutHint
Style hint (bool)node.GetStyleHint<bool>("key", false)
Style hint (string)node.GetStyleHint<string>("key", null)
Title textnode.title?[0]?.text
Title colornode.title?[0]?.color
Nested nodesnode.nodes
Popup nodenode.popup
Reward datanode.GetReward()
Product datanode.GetProduct()

Error Handling

REST API Errors

StatusDescription
400Invalid request (missing coinId, etc.)
401Invalid or missing API key
404Touchpoint not found
500Server error
{
  "statusCode": 404,
  "message": "Touchpoint \"invalid-name\" not found for game \"game-uuid\"",
  "error": "Not Found"
}

Unity SDK Error Handling

public async Task SafeLoadTouchpoint()
{
    try
    {
        TouchpointResponse tp = await TouchpointManager.GetTouchpointByName(
            "my-touchpoint",
            "coin-uuid-abcd"
        );

        if (tp == null)
        {
            Debug.LogWarning("Touchpoint not found or error occurred");
            ShowFallbackUI();
            return;
        }

        if (tp.nodes == null || tp.nodes.Length == 0)
        {
            Debug.LogWarning("Touchpoint has no nodes");
            ShowFallbackUI();
            return;
        }

        // Process touchpoint
        await RenderTouchpoint(tp);
    }
    catch (Exception e)
    {
        Debug.LogError($"Failed to load touchpoint: {e.Message}");
        ShowFallbackUI();
    }
}

private void ShowFallbackUI()
{
    // Show default/cached content
}

Common Error Messages

ErrorCauseSolution
API key not setSDK not initializedCall PlaySuperUnitySDK.Init() first
name is requiredEmpty touchpoint nameProvide a valid touchpoint name
coinId is requiredEmpty coin IDProvide a valid coin ID
404 Not FoundTouchpoint doesn't existVerify touchpoint name in dashboard
401 UnauthorizedInvalid API key or tokenCheck API key and player authentication

Best Practices

  1. Cache Touchpoints - Use ListTouchpoints at startup to cache frequently used touchpoints
  2. Handle Null Safely - Always use null-conditional operators (?.) when accessing optional fields
  3. Sort by displayOrder - Always sort nodes by displayOrder before rendering
  4. Preload Images - Load images asynchronously and cache them for smooth UX
  5. Check layoutHint - Use layoutHint to determine which UI template to use
  6. Handle Popups - Check for popup field before navigating on tap