Skip to content

KK API Signature Algorithm

Overview

KK API ensures request security through a robust signature verification mechanism. Every HTTP request must include a valid signature to be processed.

Signature Generation Steps

1. Parameter Sorting

Sort all request parameters alphabetically by their names in ASCII order.

Example:

yaml
Unsorted: 
- foo=1
- bar=2
- foo_bar=3
- foobar=4
yaml
Sorted: 
- bar=2
- foo=1
- foo_bar=3
- foobar=4

2. Parameter Concatenation

Combine sorted parameters without separators:

bar2foo1foo_bar3foobar4

3. API Endpoint Prepending

Prefix the concatenated string with the full API endpoint:

/partners/v1/balancebar2foo1foo_bar3foobar4

4. Signature Generation

Generate HMAC SHA256 digest using your confidential API Secret:

  • Encode string in UTF-8
  • Use HMAC SHA256 algorithm
  • Convert result to uppercase

Examples

python
import hmac
import hashlib

def platform-api_sign(secret, endpoint, params):
    sorted_params = sorted(params.items())

    param_string = ''.join(f"{k}{v}" for k, v in sorted_params)

    signature_string = f"{endpoint}{param_string}"

    return hmac.new(
        secret.encode('utf-8'),
        signature_string.encode('utf-8'),
        hashlib.sha256
    ).hexdigest().upper()
javascript
const crypto = require('crypto');

function platform-apiSign(secret, endpoint, params) {
    const sortedParams = Object.entries(params)
        .sort(([a], [b]) => a.localeCompare(b))
        .map(([k, v]) => `${k}${v}`)
        .join('');

    const signatureString = `${endpoint}${sortedParams}`;

    return crypto
        .createHmac('sha256', secret)
        .update(signatureString)
        .digest('hex')
        .toUpperCase();
}
typescript
import * as crypto from 'crypto';

function platform-apiSign(
    secret: string, 
    endpoint: string, 
    params: Record<string, string>
): string {
    const sortedParams = Object.entries(params)
        .sort(([a], [b]) => a.localeCompare(b))
        .map(([k, v]) => `${k}${v}`)
        .join('');

    const signatureString = `${endpoint}${sortedParams}`;
    return crypto
        .createHmac('sha256', secret)
        .update(signatureString)
        .digest('hex')
        .toUpperCase();
}

5. Request Header

Add the generated signature to the request header:

http
x-signature: 68656C6C6F776F726C64

6. Example code to call api

This is example code to generated signature and call api

typescript
import axios from "axios";

const baseURL = "http://localhost:3001";
const endpoint = "/v1/partners/games/launch-lobby";
const siteId = "yourSiteId";
const apiKey = "yourApiKey";
const secretKey = "yourSecretKey";

const api = axios.create({
  baseURL,
});

function apiSign(
  secret: string,
  endpoint: string,
  params: Record<string, string>
): string {
  const sortedParams = Object.entries(params)
    .sort(([a], [b]) => a.localeCompare(b))
    .map(([k, v]) => `${k}${v}`)
    .join('');

  const signatureString = `${endpoint}${sortedParams}`;

  console.log("signatureString:", signatureString);

  return crypto
    .createHmac('sha256', secret)
    .update(signatureString)
    .digest('hex')
    .toUpperCase();
}

(async () => {
  const body = {
    username: "testplayer123",
  };
  const signature = apiSign(secretKey, endpoint, body);
  try {
    const response = await api.post(endpoint, body, {
      headers: {
        "content-type": "application/json",
        "authorization": `Basic ${btoa(`${siteId}:${apiKey}`)}`,
        "x-signature": signature,
      },
      params: body,
    });
    console.log("response", response.data.data);
  } catch (error) {
    console.error("error", error.response.data);
  }
})();

Common Pitfalls

  • Incorrect parameter sorting
  • Forgetting to prepend the API endpoint
  • Using wrong encoding (must be UTF-8)
  • Exposing API Secret

Error Handling

Error TypeDescriptionHTTP Status
Missing SignatureNo x-signature header401 Unauthorized
Invalid SignatureSignature verification fails403 Forbidden
Malformed RequestIncorrect parameter formatting400 Bad Request