BloxSolve API
BloxSolve is an HTTP API that solves Roblox FunCaptcha for both login and account creation. You submit the data-exchange blob and a proxy, poll for the result, and receive a token you submit back to Roblox. A token is only returned on a real solve. The API never returns a fake one.
Point your requests at the BloxSolve base URL. All examples below use https://api.bloxsolve.com.
Authentication
Solve endpoints require an API key. Send it in either header form:
X-API-Key: justice_k3n8x2p9q7w1m5r4t6y0
# or, equivalently:
Authorization: Bearer justice_k3n8x2p9q7w1m5r4t6y0Keys are formatted as justice_ followed by 20 secure characters. They are stored only as a SHA-256 hash, shown in full exactly once when created, and displayed masked (like justice_…t6y0) afterwards. A missing, invalid, or revoked key returns 401 with a generic body.
Quickstart
Three steps: create a task, poll getTask until it is completed, then use captcha.token.
It is plain HTTP and JSON, so it works in any language. The same flow is shown below in cURL, Python, and JavaScript.
# 1. Create a solve task (returns a task_id)
curl -X POST https://api.bloxsolve.com/funcaptcha/createTask \
-H "X-API-Key: justice_k3n8x2p9q7w1m5r4t6y0" \
-H "Content-Type: application/json" \
-d '{
"blob": "<dataExchangeBlob>",
"proxy": "http://user:pass@host:port",
"custom_cookies": "<roblox cookies>",
"public_key": "<roblox_login_public_key>"
}'
# 2. Poll for the result until status == "completed"
curl -X POST https://api.bloxsolve.com/funcaptcha/getTask \
-H "X-API-Key: justice_k3n8x2p9q7w1m5r4t6y0" \
-H "Content-Type: application/json" \
-d '{ "task_id": "<task_id from step 1>" }'Create task
/funcaptcha/createTaskSubmits a solve task. Returns immediately with a task_id while the solver works in the background. Requires an API key.
| Field | Type | Description |
|---|---|---|
blob | stringrequired | The FunCaptcha data-exchange blob for the challenge. |
proxy | string | Proxy used for the solve, e.g. http://user:pass@host:port (http/https/socks supported). |
custom_cookies | string | Roblox cookies string to attach to the session. |
custom_locale | string | Locale for the request. Defaults to "en-US". |
chrome_version | string | Chrome version to present. Defaults to "131". |
public_key | string | Roblox sitekey. Use the login key (default) or the signup key. See Logins & signups below. |
Request
curl -X POST https://api.bloxsolve.com/funcaptcha/createTask \
-H "X-API-Key: justice_k3n8x2p9q7w1m5r4t6y0" \
-H "Content-Type: application/json" \
-d '{
"blob": "<dataExchangeBlob>",
"proxy": "http://user:pass@host:port",
"custom_cookies": "<roblox cookies>",
"custom_locale": "en-US",
"chrome_version": "131",
"public_key": "<roblox_login_public_key>"
}'Response
{
"success": true,
"task_id": "8f2c1e4a-...-b7d9",
"status": "processing",
"type": "FuncaptchaTask"
}Get task result
/funcaptcha/getTaskPolls a task by task_id. While solving, status is processing. On completion the captcha object carries the token. Requires an API key.
| Field | Type | Description |
|---|---|---|
task_id | stringrequired | The task_id returned by createTask. |
Request
curl -X POST https://api.bloxsolve.com/funcaptcha/getTask \
-H "X-API-Key: justice_k3n8x2p9q7w1m5r4t6y0" \
-H "Content-Type: application/json" \
-d '{ "task_id": "<task_id>" }'Response (still processing)
{
"success": true,
"task_id": "8f2c1e4a-...-b7d9",
"status": "processing",
"type": "FuncaptchaTask"
}Response (completed)
{
"success": true,
"task_id": "8f2c1e4a-...-b7d9",
"status": "completed",
"type": "FuncaptchaTask",
"captcha": {
"success": true,
"token": "<token>",
"error": null,
"process_time": 6.2
}
}Solve responses carry only success, the token, and process_time. Your proxy, cookies, and request details are never returned.
Alternate task API
/createTask/taskResultA second create and poll pair that takes the challenge details under a challengeInfo object. Both require an API key. /createTask returns a taskId. Poll /taskResult with { "taskId": "<uuid>" } until it completes.
Request (create then poll)
curl -X POST https://api.bloxsolve.com/createTask \
-H "X-API-Key: justice_k3n8x2p9q7w1m5r4t6y0" \
-H "Content-Type: application/json" \
-d '{
"challengeInfo": {
"publicKey": "<roblox_login_public_key>",
"site": "https://www.roblox.com/",
"surl": "https://arkoselabs.roblox.com",
"extraData": { "blob": "<dataExchangeBlob>" }
},
"browserInfo": { "User-Agent": "Mozilla/5.0 ... Chrome/131.0.0.0 ..." },
"cookies": "rbx-ip2=...; RBXEventTrackerV2=..."
}'Responses
// create -> { "taskId": "<uuid>" }
// poll /taskResult:
{ "status": "pending" }
{ "status": "completed",
"result": { "solution": "<token>", "gameInfo": { "solveTime": 6.2 } } }
{ "status": "failed", "error": "unsolved" }Get balance
/getBalanceReturns the balance for your own API key. Authenticate with the same X-API-Key or Bearer header. It returns only your key's label, balance, and successful-solve count, and nothing about any other key.
Request
curl https://api.bloxsolve.com/getBalance \
-H "X-API-Key: justice_k3n8x2p9q7w1m5r4t6y0"Response
{
"success": true,
"label": "Alex",
"balance": 128,
"suppressed_count": 42
}Logins & signups
Roblox uses one sitekey for login and a different one for account creation. Both are fully supported. The flow is identical: you send the blob and proxy, and optionally set public_key to target signup. If you omit it, the login sitekey is used automatically, so most callers never set it.
| Field | Type | Description |
|---|---|---|
Login | public_key | Roblox login sitekey (used by default when public_key is omitted). |
Signup | public_key | Roblox account-creation sitekey. Pass public_key to target signup. |
Solve a signup challenge
curl -X POST https://api.bloxsolve.com/funcaptcha/createTask \
-H "X-API-Key: justice_k3n8x2p9q7w1m5r4t6y0" \
-H "Content-Type: application/json" \
-d '{
"blob": "<dataExchangeBlob>",
"proxy": "http://user:pass@host:port",
"public_key": "<roblox_signup_public_key>"
}'Everything else is identical: same headers, same getTask polling, same response shape.
Balances & charging
You only pay for successful solves, and charging is concurrency-safe:
- 1. On submit, one balance credit is atomically reserved.
- 2. If the solve succeeds and returns a token, the credit is kept and your solve count increments.
- 3. If it fails or errors and no token is returned, the credit is refunded.
If a key's balance is 0, the request is rejected with 402 insufficient_balance before any solve is attempted, so you never burn a proxy on an empty balance.
Errors & rate limits
Errors use a consistent JSON shape and generic values. No stack traces or internal detail are ever returned. Most errors carry { "success": false, "error": "<value>" }; the alternate task API returns solve outcomes under a status field instead.
| Status | error value | Meaning |
|---|---|---|
401 | {"success":false,"error":"unauthorized"} | Missing, invalid, or revoked API key. Do not retry; fix the key. |
402 | {"success":false,"error":"insufficient_balance"} | The key's balance is 0. Rejected before any solve. Top up, then retry. |
429 | {"success":false,"error":"rate_limited"} | A per-key or global rate limit was hit (off by default). Back off and retry. |
403 | {"success":false,"error":"key_disabled"} | This key has been disabled by an administrator. Not billed. Contact support. |
503 | {"success":false,"error":"solves_paused"} | Solving is temporarily paused for maintenance. Not billed. Retry shortly. |
400 | {"success":false,"error":"no_data"} | Empty or non-JSON request body. |
400 | {"success":false,"error":"missing_blob"} | The blob field is required. The alternate /createTask returns {"error":"missing_blob"}. |
400 | {"success":false,"error":"missing_task_id"} | getTask was called without a task_id. |
404 | {"success":false,"error":"task_not_found"} | No task exists for the given id (expired, wrong id, or never created). |
200 | {"status":"failed","error":"unsolved"} | getTask/taskResult completed but no token was produced for this challenge. Not billed; retry with a fresh blob. |
500 | {"success":false,"error":"internal_error"} | Transient server error. Safe to retry after a short delay. |
Internal solve failures surface inside the task error text (for example HTTP 401 from upstream or DENIED ACCESS for an invalid or stale blob). These are never billed. There is no hard rate limit by default (0 = unlimited), so bursty back-to-back traffic works out of the box.
Best practices
- 1.Use sticky residential or ISP proxies, one per solve. Non-rotating IPs that hold for the full create-then-poll cycle solve far more reliably than datacenter or mid-request rotating proxies.
- 2.Set a generous client timeout. Solves typically take about 4 to 20 seconds; allow up to 120 seconds and keep polling
getTaskonce per second untilcompleted. - 3.Retry only transient errors (500 and network timeouts). Never retry
400,401, or402; fix the request or top up instead. - 4.Watch your balance. Poll
getBalanceand top up before it reaches 0 so you never get a402mid-run. - 5.Keep the API key server-side. Never ship it in client-side code or a browser bundle. Treat it like a password.
Support
Questions, higher limits, or a custom deployment? Reach out and we will help.
Join our server for the fastest response. Open Discord
Need a key? Head to the pricing section to get access.