Guide
Limits
What counts, what is free, and what happens when you go over.
You pay for outcomes, not attempts
refunded_requests.
| Per-code status | Billed | Why |
|---|---|---|
activated | ✅ | UC delivered |
code_used | ✅ | Real outcome — the code was already spent |
invalid_code | ✅ | Real outcome — the code is not usable |
bad_player | ❌ | Nothing was attempted against a valid target |
failed | ❌ | Temporary issue on our side — automatically refunded |
- 240 UC built from 4 codes, all activated → 4 requests
- Same job where 1 code failed on our side → 3 billed, 1 refunded
- Job rejected before any attempt (
no_stock, bad body,402) → not billed - An idempotent replay → not billed again
- Polling
GET /v1/jobs/{id}→ free
Reconcile from the response headers
Every response carries the running totals, so you never need a second call:
| Header | Meaning |
|---|---|
KA-Cost | Requests actually billed for this call |
KA-Quota-Used / KA-Quota-Remaining | Today’s plan usage |
KA-Balance-Usd | Wallet balance after the call |
KA-Idempotent-Replay | true when this was a replay of an earlier answer |
X-Request-Id | Quote this in support tickets |
KA-Version | API contract version |
Free endpoints
| Call | Notes |
|---|---|
GET /v1/health | No API key |
GET /v1/me | Plan, quota, balance, subscription |
GET /v1/stock | Your KA BOT inventory, by category |
GET /v1/jobs/{id} | Async job state and result |
POST /v1/webhook | Register a callback (re-registering rotates the secret) |
Live numbers come from GET /v1/me under quota:
daily_limit, used_today,
remaining_today, overage_today.
Plans
Plans are assigned per merchant — there is no public
catalog and no self-serve checkout. Your live numbers come from
GET /v1/me:
{
"ok": true,
"customer_id": 123456789,
"key_prefix": "pk_0123",
"scopes": ["redeem", "read"],
"mode": "live",
"plan": "assigned-label",
"plan_active": true,
"quota": {
"daily_limit": 3000,
"used_today": 12,
"remaining_today": 2988,
"overage_today": 0
},
"per_request_usd": 0.0,
"balance_usd": 25.0,
"subscription": { "active": true, "required": false, "expires_at": null, "days_left": null }
}
mode is live or test (from the
key prefix). quota.daily_limit of null means
no daily cap.
| Field | Meaning |
|---|---|
plan | Label of the plan assigned to you |
plan_active | Whether the plan is currently usable |
quota.daily_limit | Included requests per UTC day (null = no cap) |
quota.used_today / remaining_today | Today’s usage |
quota.overage_today | Requests billed from wallet after the daily include |
per_request_usd | Rate billed from wallet after the daily include (and for uncapped plans) |
balance_usd | Wallet balance |
subscription.required | true only when a Telegram bot subscription is billed. When the bot is free this is false |
subscription.active | Whether that bot subscription currently allows API use. Always true when required is false |
Daily counters reset at 00:00 UTC.
To change a plan, message support
(@Nogitsuneiii) — do not assume another merchant’s quota or rate applies to you.
GET /v1/me reports
subscription.required: true. In that case a lapse returns
402 subscription_expired while the API plan keeps running —
watch subscription.days_left. When
required is false (bot priced at 0$), that
error is never returned and you can ignore days_left.
When the wallet cannot pay
Wallet too low for the billed rate → 402. Top up
/wallet, then retry.
{
"ok": false,
"error_code": "insufficient_funds",
"message": "Wallet balance too low."
}
Do not show that raw body to your end customer — tell them the shop is temporarily unavailable.
Rate limit (429)
Separate from the daily plan quota. POST /v1/redeem is
limited to 30 requests per 10 seconds per key
(other endpoints are not on this burst cap):
HTTP/1.1 429 Too Many Requests
Retry-After: 4
{ "ok": false, "error_code": "rate_limited",
"message": "Too many requests — slow down.", "retry_after_sec": 4 }
- Respect
Retry-After/retry_after_sec(seconds) - Back off on your side — do not tight-loop poll faster than ~1–2s
- Hitting the daily plan limit is a different code,
quota_exceeded, also on429 - A
429itself does not consume redeem quota
Request size
- Max 50 codes per redeem request
- Max 256 KB body →
413 payload_too_large
Not API quota
- Manual redeem in the KA BOT chat (active Telegram subscription)
- Checker — priced separately