Guide

Redeem

Base: · Header: X-API-Key

When to use A vs B

UseIf…Failure handling
A · Your codes Codes live in your bot / supplier DB Harder for you: KA BOT does not manage your stock. On fail you decide refund / keep / retry from error_code.
B · KA BOT stock You stocked codes in KA BOT Easier: each result includes code_returned (back in inventory or consumed).

Source A is like “direct / code override”: powerful, but your bot must track every outcome. Prefer B when codes already sit in KA BOT.

Recommended: lookup before charge

GET {{BASE}}/v1/player/lookup?player_id=5123456789

Free. Confirm nickname with your customer before you deduct their balance and start a redeem job. Invalid ID → fix it; do not burn codes or wallet.

Create job

A · Your codes

{
  "player_id": "5123456789",
  "codes": ["CODE1", "CODE2", "CODE3", "CODE4"]
}

B · KA BOT inventory

{ "player_id": "5123456789", "uc": 240 }
{
  "player_id": "5123456789",
  "categories": ["60", "60", "60", "60"]
}
{
  "player_id": "5123456789",
  "packs": [{ "denomination": 60, "quantity": 4 }]
}
{ "player_id": "5123456789", "denomination": 60, "quantity": 4 }
Mixing codes with inventory fields → 400 ambiguous_source.
Not enough KA BOT inventory → NO_STOCK (job not billed).

Code state after failure

Merchants need a clear answer: did the code go back to stock or burn?

SourceFieldMeaning
B · stock code_returned: true Code is back in your KA BOT inventory — safe to sell again.
B · stock code_returned: false Code was consumed / burned — do not re-sell it.
A · your codes code_returned: null Always your responsibility. Use error_code to decide (e.g. CODE_USED → mark used; NETWORK_ERROR → your retry policy).

Job result

{
  "status": "done",
  "source": "stock",
  "job_id": "job_01HZX…",
  "requests_charged": 4,
  "results": [
    {
      "code": "CODE1",
      "success": true,
      "error_code": null,
      "message": "OK",
      "code_returned": null
    },
    {
      "code": "CODE2",
      "success": false,
      "error_code": "NETWORK_ERROR",
      "message": "Temporary failure — retry later",
      "code_returned": true
    }
  ]
}

source: external (A) or stock (B). Successful lines use code_returned: null (code was delivered).

Receipt / history

job_id is your receipt. Store it on your order.

No internal engine details are exposed — only merchant-safe status and codes.

Endpoints (cheat sheet)

CallWhat it doesCost
GET /healthService ping (no key)0
GET /v1/mePlan + wallet0
GET /v1/quotaUsage today0
GET /v1/stockKA BOT inventory counts0
GET /v1/player/lookup?player_id=Player nickname0
POST /v1/jobs/redeemCreate redeem job1 / code
GET /v1/jobs/{id}Receipt / results0

Python — source A

import time, requests

BASE, KEY = "{{BASE}}", "pk_YOUR_KEY"
H = {"X-API-Key": KEY, "Accept": "application/json"}

# 1) smoke test
assert requests.get(f"{BASE}/v1/me", headers=H, timeout=30).ok

# 2) lookup before charge
nick = requests.get(
    f"{BASE}/v1/player/lookup",
    headers=H, params={"player_id": "5123456789"}, timeout=30,
).json()

# 3) redeem
r = requests.post(
    f"{BASE}/v1/jobs/redeem",
    headers={**H, "Content-Type": "application/json"},
    json={
        "player_id": "5123456789",
        "codes": ["CODE1", "CODE2", "CODE3", "CODE4"],
    },
    timeout=60,
)
job_id = r.json()["job_id"]  # store as receipt
while True:
    job = requests.get(f"{BASE}/v1/jobs/{job_id}", headers=H, timeout=60).json()
    if job.get("status") in ("done", "failed"):
        break
    time.sleep(1.5)
print(nick, job["source"], job["requests_charged"], job["results"])

Python — source B

requests.post(
    f"{BASE}/v1/jobs/redeem",
    headers={**H, "Content-Type": "application/json"},
    json={"player_id": "5123456789", "uc": 240},
    timeout=60,
)

curl

# smoke
curl -sS "{{BASE}}/v1/me" -H "X-API-Key: pk_YOUR_KEY"

# A
curl -sS -X POST "{{BASE}}/v1/jobs/redeem" \
  -H "X-API-Key: pk_YOUR_KEY" -H "Content-Type: application/json" \
  -d '{"player_id":"5123456789","codes":["CODE1","CODE2"]}'

# B
curl -sS -X POST "{{BASE}}/v1/jobs/redeem" \
  -H "X-API-Key: pk_YOUR_KEY" -H "Content-Type: application/json" \
  -d '{"player_id":"5123456789","uc":240}'