GET /balance
Read the live balance and limits for an API key. Returns balance, unlimited flag, allowed captcha types, and the current CPM bucket state.
GET /balance
Returns the live balance and access rules for the API key. The balance is updated in real time from the in-memory ledger, not from a stale DB snapshot — call it any time to see the exact funds you have right now.
GET https://api.nslsolver.com/balance| Header | Value | Required |
|---|---|---|
X-API-Key | Your API key | Yes |
This endpoint is rate-limited to 30 requests per minute per source IP. Poll it from your application boot or on a slow timer — not from every solve call.
Response
200
{
"success": true,
"balance": 14.5,
"unlimited": false,
"allowed_types": ["turnstile", "challenge", "kasada", "akamai"],
"max_cpm": 600,
"current_cpm": 12,
"cpm_limit": 600
}| Field | Type | Notes |
|---|---|---|
success | bool | Always true on 200. |
balance | number | Remaining funds in USD, fresh from the in-memory ledger. |
unlimited | bool | When true, solves are not billed against balance. |
allowed_types | string[] | Types this key may request. A solve of any other type returns 403. |
max_cpm | int | Configured CPM ceiling. 0 means uncapped. |
current_cpm | int | Tokens already consumed in the current minute (refills continuously, not on minute boundaries). |
cpm_limit | int | Mirror of max_cpm for symmetry with monitoring dashboards. |
unlimited_expires_at | string | Present only when unlimited is true and an expiry is set. ISO 8601. |
401 — Auth errors
{ "success": false, "error": "Invalid API key" }429 — IP rate limit
{ "success": false, "error": "Rate limit exceeded" }You're calling /balance faster than 30 times per minute from a single IP. Back off and call less often.
Examples
curl https://api.nslsolver.com/balance \
-H "X-API-Key: $NSL_API_KEY"import requests
r = requests.get(
"https://api.nslsolver.com/balance",
headers={"X-API-Key": "YOUR_KEY"},
timeout=10,
)
data = r.json()
if not data["success"]:
raise RuntimeError(data["error"])
print(f"${data['balance']:.4f} ({data['current_cpm']}/{data['cpm_limit']} CPM)")const r = await fetch("https://api.nslsolver.com/balance", {
headers: { "X-API-Key": process.env.NSL_API_KEY },
});
const data = await r.json();
if (!data.success) throw new Error(data.error);
console.log(`$${data.balance.toFixed(4)} ${data.current_cpm}/${data.cpm_limit} CPM`);When to call this
Hit /balance at process start to size your worker pool against cpm_limit, and again on a slow cadence (every few minutes, or on a dashboard refresh) for monitoring. Do not call it before every /solve — both rate limit budgets are wasted, and the value you read is immediately stale anyway.