Authentication

Uplynk provides two types of APIs with different capabilities and design patterns:

  1. v2 APIs – Legacy APIs using RPC-style design for core platform functions.
  2. v4 APIs – Modern RESTful APIs supporting expanded functionality and HTTP methods.

All APIs require the same authentication mechanism but differ in how request data is structured.


API Types Comparison

Featurev2 APIsv4 APIs
HTTP MethodsGET, POST onlyGET, POST, PATCH, DELETE
Base Endpointhttps://services.uplynk.com/api2/https://services.uplynk.com/api/v4/
Authentication LocationQuery string parameters (msg and sig)Query string parameters (msg and sig)
Data LocationAll parameters encoded in the msg parameterAuthentication in query string, operation data in JSON body
URL Structure/api2/[resource]/[action]?msg=[encoded]&sig=[signature]/api/v4/[resource]/[id]?msg=[encoded]&sig=[signature]
Message ContentContains all request parametersContains only authentication data (_owner, _timestamp)
Content-TypeN/A (no body)application/json for requests with bodies
API Design StyleRPC-style with action verbsRESTful with resource identifiers

Authentication

Both API types use the same authentication mechanism. Each request requires:

ParameterDescription
_ownerYour User ID (found in User Settings).
_timestampThe Unix timestamp (UTC) when the request is created.
msgA Base64-encoded JSON object containing the authentication parameters (and data for v2 APIs).
sigAn HMAC-SHA256 digital signature, generated using your API key and the msg parameter.

Locating Your API Credentials

  1. User ID – Found under User Settings in the Uplynk CMS.
  2. API Key – Found under Integration Keys in the CMS.

Request Structure By API Type

v2 API Requests (All Data in Message)

For v2 APIs, all parameters are included in the encoded msg parameter:

  1. Create a JSON object with:
    • _owner – Your User ID
    • _timestamp – Current Unix timestamp
    • All request-specific parameters
  2. Compress and encode this object to create the msg parameter
  3. Sign the encoded msg to create the sig parameter
  4. Send both as URL parameters

Example v2 GET Request:

https://services.uplynk.com/api2/asset/list?msg=eNoFwUkOgCAMAMC%2F9MyBpVLLZ0jFkpCIGiXxYPy7My%2Fk49n1ggRF0dVo61wXi8xRVlYRKYEmKiwIBvJoXe8h%2FYTkCC3F4NkZ2FpvA5L%2FfsDdF4A%3D&sig=4c585dc7ca70be3ee33852500354feca9ac896122f6910b874214b9624a0dfa4

v4 API Requests (Data in Body)

For v4 APIs, only authentication parameters go in the encoded msg:

  1. Create a JSON object with only:
    • _owner – Your User ID
    • _timestamp – Current Unix timestamp
  2. Compress and encode this object to create the msg parameter
  3. Sign the encoded msg to create the sig parameter
  4. Send both as URL parameters
  5. Send request-specific data in the request body as JSON

Example v4 PATCH Request:

URL:
https://services.uplynk.com/api/v4/audiences/da3114eedfdf499fb7fb38a21614ec40?msg=eJwFwTEOgCAMAMC%2FdHYooVLKZ0itJXFAjZI4GP%2Fu3Qv1eHa%2FoIA5hZaw5bYgiSRdxVXVIs9sogQT1LF1v4f2E0pgQk4xZ%2Fx%2B5PYUiQ%3D%3D&sig=79dfaf6019f3fe0bfe68ad21a33114e769956abedaa2815d3919572a0e30ae9a

Request Body:
{
  "country_codes": ["GB", "ZA"]
}

Step-by-Step Guide to Creating Requests

1. Encoding the Message (msg)

For all APIs, you need to create and encode the msg parameter:

// Create message object
const msg = {
  _owner: "your_user_id",
  _timestamp: Math.floor(Date.now() / 1000)
};

// For v2 APIs, include all parameters here
if (isV2Api) {
  Object.assign(msg, requestSpecificParams);
}

// Compress and encode
const msgString = JSON.stringify(msg);
const compressed = zlib.deflate(msgString, { level: 9 });
const encodedMsg = base64Encode(compressed);

2. Generating the Signature (sig)

// Create HMAC-SHA256
const sig = hmacSha256(encodedMsg, "your_api_key");

3. Constructing the Request

For v2 APIs:

const url = `https://services.uplynk.com/api2/resource/action?msg=${encodedMsg}&sig=${sig}`;
// Make GET or POST request to this URL (no body)

For v4 APIs:

const url = `https://services.uplynk.com/api/v4/resource/id?msg=${encodedMsg}&sig=${sig}`;
const headers = { "Content-Type": "application/json" };
const body = JSON.stringify(requestSpecificParams);
// Make request with appropriate method and JSON body

Code Samples

Python (Handles Both v2 and v4 APIs)

import base64, hashlib, hmac, json, time, urllib.parse, zlib
import requests

def call_v2_api(uri, **params):
    """Call v2 API with all parameters in the msg."""
    user_id = "your_user_id"
    api_key = "your_api_key"
    
    # Include all params in the message
    msg = {
        "_owner": user_id,
        "_timestamp": int(time.time()),
        **params
    }
    
    # Encode and sign
    msg_json = json.dumps(msg)
    msg_compressed = zlib.compress(msg_json.encode(), level=9)
    msg_b64 = base64.b64encode(msg_compressed).decode()
    sig = hmac.new(api_key.encode(), msg_b64.encode(), hashlib.sha256).hexdigest()
    
    # Make request (all in URL, no body)
    url = f"https://services.uplynk.com{uri}"
    payload = dict(msg=msg_b64, sig=sig)
    response = requests.post(url, data=payload)
    return response.json()

def call_v4_api(uri, method, body=None):
    """Call v4 API with auth in msg and data in the request body."""
    user_id = "your_user_id"
    api_key = "your_api_key"
    
    # Only auth params in message
    msg = {
        "_owner": user_id,
        "_timestamp": int(time.time())
    }
    
    # Encode and sign
    msg_json = json.dumps(msg)
    msg_compressed = zlib.compress(msg_json.encode(), level=9)
    msg_b64 = base64.b64encode(msg_compressed).decode()
    sig = hmac.new(api_key.encode(), msg_b64.encode(), hashlib.sha256).hexdigest()
    
    # Make request (auth in URL, data in body)
    url = f"https://services.uplynk.com{uri}"
    params = dict(msg=msg_b64, sig=sig)
    headers = {"Content-Type": "application/json"} if body else None
    
    response = requests.request(
        method=method,
        url=url,
        params=params,
        json=body,  # Will be sent as JSON in body
        headers=headers
    )
    return response.json()

# Example v2 API call
assets = call_v2_api("/api2/asset/list", limit=10)

# Example v4 API call
audience = call_v4_api(
    "/api/v4/audiences/da3114eedfdf499fb7fb38a21614ec40",
    "PATCH",
    {"country_codes": ["GB", "ZA"]}
)

JavaScript

const crypto = require("crypto");
const zlib = require("zlib");
const fetch = require("node-fetch");

async function callUplynkApi(uri, method, params, isV2) {
    const USER_ID = "your_user_id";
    const API_KEY = "your_api_key";
    
    // Create message object (auth params only for v4)
    const msg = { 
        _owner: USER_ID, 
        _timestamp: Math.floor(Date.now() / 1000)
    };
    
    // For v2, include all params in message
    if (isV2) {
        Object.assign(msg, params);
    }
    
    // Encode and sign
    const msgString = JSON.stringify(msg);
    const compressed = zlib.deflateSync(msgString, { level: 9 });
    const base64Msg = compressed.toString("base64");
    const sig = crypto.createHmac("sha256", API_KEY).update(base64Msg).digest("hex");
    
    // Create URL with auth params
    const baseUrl = "https://services.uplynk.com";
    const url = new URL(baseUrl + uri);
    url.searchParams.append("msg", base64Msg);
    url.searchParams.append("sig", sig);
    
    // Set up request options
    const options = {
        method: method,
        headers: {}
    };
    
    // For v4, add body if not GET/DELETE
    if (!isV2 && params && method !== "GET" && method !== "DELETE") {
        options.body = JSON.stringify(params);
        options.headers["Content-Type"] = "application/json";
    }
    
    // Make request
    const response = await fetch(url.toString(), options);
    return await response.json();
}

// Example v2 API call
callUplynkApi("/api2/asset/list", "GET", { limit: 10 }, true)
    .then(data => console.log("V2 result:", data));

// Example v4 API call
callUplynkApi(
    "/api/v4/audiences/da3114eedfdf499fb7fb38a21614ec40",
    "PATCH", 
    { country_codes: ["GB", "ZA"] }, 
    false
).then(data => console.log("V4 result:", data));

Error Handling

All API responses include an error field indicating success or failure:

Error CodeDescription
0Success
1Error (see msg for details)

Example Error Responses

Invalid Parameter:

{
  "msg": ["Unrecognized parameter: allowed_play."],
  "error": 1
}

Invalid Value:

{
  "msg": ["track_type is not valid: Values allowed are ['SD', 'HD', 'AUDIO', 'UHD1', 'UHD2', 'ALL']"],
  "error": 1
}

Resource Not Found:

{
  "msg": ["DRM Config not found."],
  "error": 1
}

Summary

  1. Choose API Version:

    • v2 APIs include all data in the message
    • v4 APIs include data in the body
  2. Authentication:

    • Always required: msg (encoded) and sig (signature) in query string
    • v2: Message contains all parameters
    • v4: Message contains only auth parameters
  3. Request Structure:

    • v2: GET/POST to /api2/resource/action
    • v4: GET/POST/PATCH/DELETE to /api/v4/resource/id
  4. Sending Data:

    • v2: All data encoded in msg parameter
    • v4: Data sent as JSON in request body

For further details, refer to the specific API documentation sections.