Appearance
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=4yaml
Sorted:
- bar=2
- foo=1
- foo_bar=3
- foobar=42. Parameter Concatenation
Combine sorted parameters without separators:
bar2foo1foo_bar3foobar43. API Endpoint Prepending
Prefix the concatenated string with the full API endpoint:
/partners/v1/balancebar2foo1foo_bar3foobar44. 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: 68656C6C6F776F726C646. 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 Type | Description | HTTP Status |
|---|---|---|
| Missing Signature | No x-signature header | 401 Unauthorized |
| Invalid Signature | Signature verification fails | 403 Forbidden |
| Malformed Request | Incorrect parameter formatting | 400 Bad Request |