ID Validation
Validate a player's game account (nickname, region, first-topup double-bonus, and pass availability) before you sell.
Validate a player’s game account before checkout. One call returns the nickname, region, first-recharge double-bonus availability per tier, and pass availability, so you can confirm the account, gate by region, or show which first-topup promos the player can still claim.
A game is validatable only when we have enabled its ID Checker. Discover which games with the games endpoint below.
Free, rate-limited only
Validation does not cost balance. It counts against your tier’s per-minute rate limit, and results are cached, so repeat checks of the same account are effectively free.
Discover validatable games
Request Headers
Headers
| Parameter | Type | Required | Description |
|---|---|---|---|
X-Api-Key | String | Yes | Your API Key. |
X-Timestamp | String | Yes | Current Unix timestamp in ms. |
X-Signature | String | Yes | HMAC-SHA256 signature. GET has an empty body; sign the timestamp only. |
{
"success": true,
"data": {
"games": [
{
"game": "MLBBID",
"name": "Mobile Legends",
"required_fields": ["userId", "zoneId"],
"checks": ["identity", "region", "first_topup", "pass_availability"]
}
]
},
"meta": { "total": 1 }
}game: your product code (slug). Pass this exact value to the validation endpoint.required_fields: the fields you must supply infields.checks: the capabilities available for this game.
Validate an account
Request Headers
Headers
| Parameter | Type | Required | Description |
|---|---|---|---|
X-Api-Key | String | Yes | Your API Key. |
X-Timestamp | String | Yes | Current Unix timestamp in ms. |
X-Signature | String | Yes | HMAC-SHA256 of (requestBody + timestamp), keyed with your Secret Key. |
Content-Type | String | Yes | application/json |
Request Body
Body
| Parameter | Type | Required | Description |
|---|---|---|---|
game | String | Yes | Your game code (slug) from /validation/games (e.g. "MLBBID"). |
fields | Object | Yes | Map of the game's required_fields, e.g. { "userId": "123", "zoneId": "2685" }. |
checks | String[] | No | Subset of ["identity","region","first_topup","pass_availability"]. Defaults to every capability the game supports. |
Response
{
"success": true,
"data": {
"game": "MLBBID",
"account": { "found": true, "nickname": "beezbumble_11", "region": "Indonesia" },
"checks": {
"identity": { "status": "ok" },
"region": { "status": "ok" },
"first_topup": {
"status": "ok",
"denominations": { "50": true, "150": true, "250": false, "500": false }
},
"pass_availability": {
"status": "ok",
"passes": [
{ "title": "Weekly Elite Bundle", "available": true },
{ "title": "Monthly Epic Bundle", "available": true }
]
}
},
"cached": false
}
}account.found:true= valid,false= invalid ID (a successful check whose answer is “no such account”),null= undetermined.first_topup.denominations: per tier,true= the player can still claim that first-recharge double bonus.pass_availability.passes: each named bundle with whether it is still purchasable.- A capability with
"status": "unavailable"means no source could resolve it this time; treat it as unknown, never a hard “no”.
Invalid ID
An invalid ID is a 200 with account.found: false, not an error.
{
"success": true,
"data": { "game": "MLBBID", "account": { "found": false }, "checks": { "identity": { "status": "ok" } }, "cached": false }
}Errors
Errors use the standard envelope { success:false, error, message, request_id }:
Error codes
| Parameter | Type | Required | Description |
|---|---|---|---|
GAME_NOT_SUPPORTED | 404 | No | The game has no reseller-enabled ID checker. |
VALIDATION_FIELDS_MISSING | 400 | No | A required field for this game was not supplied. |
VALIDATION_ERROR | 400 | No | Malformed body (bad types, unknown field, invalid checks). |
CHECKER_UNAVAILABLE | 503 | No | Every source was temporarily unreachable, retry shortly. |
Example cURL
API_KEY="algan_live_..."
API_SECRET="sk_live_..."
TIMESTAMP=$(python3 -c "import time; print(int(time.time() * 1000))")
BODY='{"game":"MLBBID","fields":{"userId":"2081190166","zoneId":"19751"}}'
SIGNATURE=$(echo -n "${BODY}${TIMESTAMP}" | \
openssl dgst -sha256 -hmac "${API_SECRET}" | awk '{print $2}')
curl -s https://algan.id/api/v1/validation \
-X POST -H "Content-Type: application/json" \
-H "X-Api-Key: ${API_KEY}" \
-H "X-Timestamp: ${TIMESTAMP}" \
-H "X-Signature: ${SIGNATURE}" \
-d "${BODY}"
Example (Node.js)
const crypto = require('crypto');
const API_KEY = 'algan_live_...';
const API_SECRET = 'sk_live_...';
const body = JSON.stringify({ game: 'MLBBID', fields: { userId: '2081190166', zoneId: '19751' } });
const timestamp = Date.now().toString();
const signature = crypto.createHmac('sha256', API_SECRET).update(body + timestamp).digest('hex');
const res = await fetch('https://algan.id/api/v1/validation', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Api-Key': API_KEY,
'X-Timestamp': timestamp,
'X-Signature': signature,
},
body,
});
const { data } = await res.json();
if (data.account.found) console.log(`${data.account.nickname} (${data.account.region})`);
Sandbox
The sandbox mirror at https://dev.algan.id/api/v1/validation (+ /games) returns a deterministic demo account so you can build against the exact response shape without a live lookup.