NSLSolver
API Reference

Authentication

Every API call authenticates via the X-API-Key header. Keys carry balance, allowed captcha types, CPM ceiling, and an optional IP allowlist.

Authentication

Every endpoint except the health checks requires an API key sent in the X-API-Key HTTP header.

curl https://api.nslsolver.com/balance \
  -H "X-API-Key: $NSL_API_KEY"

There is no query-parameter authentication. Passing the key as ?api_key=… returns 401 Unauthorized.

What a key carries

A single key encodes several access rules. You can read them all with GET /balance.

PropertyDescription
balanceFunds remaining, in USD. Drained per successful solve. Failures do not deduct.
unlimitedIf true, solves don't touch the balance (subject to unlimited_expires_at).
allowed_typesCaptcha types the key is allowed to solve. Requesting another type returns 403.
max_cpmMaximum captchas per minute, enforced via a token bucket. 0 means uncapped.
IP allowlistIf set, only requests originating from one of the listed IPs are accepted. Otherwise: 403.

Code examples

curl -X POST https://api.nslsolver.com/solve \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $NSL_API_KEY" \
  -d '{"type":"turnstile","site_key":"0x4AAAAAAA","url":"https://example.com"}'
import os, requests

requests.post(
    "https://api.nslsolver.com/solve",
    headers={"X-API-Key": os.environ["NSL_API_KEY"]},
    json={"type": "turnstile", "site_key": "0x4AAAAAAA", "url": "https://example.com"},
    timeout=120,
)
await fetch("https://api.nslsolver.com/solve", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-API-Key": process.env.NSL_API_KEY,
  },
  body: JSON.stringify({
    type: "turnstile",
    site_key: "0x4AAAAAAA",
    url: "https://example.com",
  }),
});
req, _ := http.NewRequest("POST", "https://api.nslsolver.com/solve", body)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-API-Key", os.Getenv("NSL_API_KEY"))

Error responses

401 — Missing API key

{
  "success": false,
  "error": "Missing API key. Use X-API-Key header."
}

No header was present. Add X-API-Key: <key> and resend.

401 — Invalid API key

{
  "success": false,
  "error": "Invalid API key"
}

The key is not recognized — common causes are typos, trailing whitespace, or a key that was rotated or deleted. Verify the value end-to-end with printf '%s' "$NSL_API_KEY" | xxd | tail to spot stray newlines.

403 — IP not whitelisted

{
  "success": false,
  "error": "IP not whitelisted"
}

The key has an IP allowlist and your egress IP is not on it. Either update the allowlist or originate the call from an allowed IP.

403 — Type not allowed

{
  "success": false,
  "error": "Captcha type 'kasada' is not allowed for your account"
}

The requested type is missing from the key's allowed_types. Use GET /balance to inspect the list.

Repeated 401s often come from accidentally including the key inside JSON or with extra characters. Always pass it in the X-API-Key header, never the body.

On this page