Guide

Limits

What counts, what is free, and what happens when you go over.

You pay for outcomes, not attempts

Requests are charged up front (so two concurrent jobs cannot overdraw your wallet), then every code whose failure was caused by our infrastructure is refunded automatically and reported back as refunded_requests.
Per-code statusBilledWhy
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

Reconcile from the response headers

Every response carries the running totals, so you never need a second call:

HeaderMeaning
KA-CostRequests actually billed for this call
KA-Quota-Used / KA-Quota-RemainingToday’s plan usage
KA-Balance-UsdWallet balance after the call
KA-Idempotent-Replaytrue when this was a replay of an earlier answer
X-Request-IdQuote this in support tickets
KA-VersionAPI contract version

Free endpoints

CallNotes
GET /v1/healthNo API key
GET /v1/mePlan, quota, balance, subscription
GET /v1/stockYour KA BOT inventory, by category
GET /v1/jobs/{id}Async job state and result
POST /v1/webhookRegister 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.

FieldMeaning
planLabel of the plan assigned to you
plan_activeWhether the plan is currently usable
quota.daily_limitIncluded requests per UTC day (null = no cap)
quota.used_today / remaining_todayToday’s usage
quota.overage_todayRequests billed from wallet after the daily include
per_request_usdRate billed from wallet after the daily include (and for uncapped plans)
balance_usdWallet balance
subscription.requiredtrue only when a Telegram bot subscription is billed. When the bot is free this is false
subscription.activeWhether 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.

An API plan is always required. A Telegram bot subscription is required only when 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 }

Request size

Not API quota