parsa
Get started

Queue-it BotDeflector solver API

Send the two challenge images, get back the three click points and the moment to submit them. No browser, no human in the loop, and nothing to pay when a solve fails.

How BotDeflector guards the queue, and where Parsa fits
Challenge
BotDeflector icons
Passed live
96–100% of 1,100 runs
Answer time
~1 s median under load
Price
€1.00 / 1,000
Billed
Only answers that come back 200

Measured in November 2026 on our own solvers; how, under benchmarks.

What is Queue-it BotDeflector?

Queue-it runs virtual waiting rooms: when a ticket sale, a product drop or an exam registration opens, visitors are held in a queue and let through to the site at a rate it can take. BotDeflector is the bot check in front of that queue (it is also sold on its own, as botdeflector.eu; this API covers the challenge Queue-it shows). Before a visitor gets a place, it asks them to prove they are not a script, so that a waiting room position can't be bought in bulk.

Its most common step is an icon challenge. It shows a strip of three small icons and a cluttered frame in which the same icons hide among decoy shapes, and asks for the icons to be clicked in the strip's order. The frame is drawn from a fixed palette of 14 colours: seven muted ones for the decoys and seven saturated ones for the icons. The server accepts a click within 15 px of an icon's centre.

The server also watches the clock. It refuses a correct answer that arrives within about 2.2 seconds of the challenge, and it refuses it with the same code it gives a missed click, so a fast solver that doesn't know this sees only failures. Parsa finds the three icons from the two images alone and tells you when to send them.

How Queue-it BotDeflector works, in depth →

The Queue-it challenge

The icon challenge

POST /botdeflector/icon · €1.00 / 1,000

The challenge starts with a flow token the waiting room page carries, which lives about two minutes and is bound to the visitor. Your client asks Queue-it's challenge host for an icon challenge with that token and gets back a challenge token and two images: the icon strip, 86 × 27 px, and the background frame, 300 × 200 px. Send both to us, base64, exactly as they were served.

We quantise the frame to the challenge's palette, look for each icon's shape only in the colour planes an icon can have, and return three points in frame pixels, in the strip's order. With them come more answers ranked by confidence, and a schedule of moments, counted from when the challenge was served, at which to post an answer.

Post the solution at the first moment. Queue-it answers with a verified token on success. If it refuses with I024 or I026, post the same answer again at each later moment: the floor varies per challenge, so an early refusal is usually the clock, not the clicks. Only when the schedule is used up, try the other answers once each. Hand the token to the rest of the waiting room flow as a browser would.

You send
icon
The icon strip PNG, base64, as served
background
The frame WebP, base64, as served
answers
Optional: how many answers to rank (1–12, default 3)
You get back
solution
Three {x, y} points in the strip's order
answers
The ranked alternatives, solution first
submit_schedule_ms
When to post each answer
accept_radius
15 px: how close a click must be
took_ms
How long the solve took

The request

Your client runs the waiting room's protocol itself: it fetches the challenge from /icon/get with the flow token and sends us only the two images. It posts the solution to /icon/verify on submit_schedule_ms, counted from when /icon/get answered, and hands the verified token on to the queue.

Keep these the same for the whole session

  • One exit IP, sticky, and the same one you send us as ip
  • A Chrome TLS and HTTP/2 fingerprint and Chrome's header order
  • The user agent and Accept-Language the payload describes
  • One cookie jar, from the first page load to the protected request
curl https://api.parsalabs.io/botdeflector/icon \
  -H "Authorization: Bearer parsa_…" \
  -H "Content-Type: application/json" \
  -d '{
    "icon":       "<base64 of the icon strip>",
    "background": "<base64 of the frame>"
  }'

# 200 OK · charged €0.001
{
  "solution": [{"x": 348, "y": 88}, {"x": 127, "y": 137},
               {"x": 253, "y": 187}],
  "submit_schedule_ms": [2200, 2700, 3200, 3800, 4500],
  "accept_radius": 15
}
import base64, requests

b64 = lambda b: base64.b64encode(b).decode()
ans = requests.post(
    "https://api.parsalabs.io/botdeflector/icon",
    headers={"Authorization": "Bearer parsa_…"},
    json={"icon": b64(icon_png), "background": b64(frame_webp)},
).json()

# The same answer at every moment (counted from when
# Queue-it served the challenge), then the others once.
tries = [(ans["solution"], ms) for ms in ans["submit_schedule_ms"]]
tries += [(a, None) for a in ans["answers"][1:]]
for points, at_ms in tries:
    if at_ms:
        wait_until(served_at + at_ms / 1000)
    r = verify(challenge_token, points)   # your POST to /icon/verify
    if "token" in r:
        break
const res = await fetch("https://api.parsalabs.io/botdeflector/icon", {
  method: "POST",
  headers: {
    "Authorization": "Bearer parsa_…",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    icon: iconPng.toString("base64"),
    background: frameWebp.toString("base64"),
  }),
});
const { solution, submit_schedule_ms } = await res.json();
// Post solution to Queue-it's /icon/verify at
// servedAt + submit_schedule_ms[0], not before.

Benchmarks

Measured against Queue-it's live challenge endpoint, not only saved frames, so a change in the icons shows up in the numbers. A first answer that passes is a correct solve; the fallback answers cover most of the rest.

MeasureParsaHeadless Chromium
Passed, icon library A (n = 300)99.7% first answer, 100% with fallbacks–
Passed, icon library B (n = 800)87.2% first answer, 96.0% with fallbacks–
Solve time under live loadMedian about 1 s, images to pointsA page, its scripts and a human or a model
Throughput, one machineAbout 31 solves/s, p95 646 msOne challenge at a time per tab
Memory per sessionNone on your side: a JSON request277 MB for the first, about 102 MB for each one after
Ten sessions at onceTen HTTPS requests1,198 MB of Chromium
Start-up, before any networkNoneAbout 100 ms to launch and load an empty page

Queue-it pricing

€1.00per 1,000 solves

Prepaid from €5, no plan and no monthly fee. Only an answer that comes back 200 is billed: an error, a timeout or a build we can't read costs nothing.

The icon challenge
€1.00 / 1,000

BotDeflector questions

Do I need a browser to solve Queue-it?

No. Your client fetches the two images over HTTP and Parsa returns the click points. Nothing renders a page.

Why does the answer come with a wait time?

Queue-it refuses a correct answer that arrives within about 2.2 seconds, and it uses the same error it gives a wrong one. Parsa tells you when to post (submit_schedule_ms), so a right answer is not thrown away for being fast.

What do the error codes mean?

I024 is a click that missed or an answer posted too early; I026 is the wrong icons or the wrong order. Both are worth another try: first the same answer at the next moment, then the alternatives. I020 (a missing field) and I028 (not evaluated, usually a failed fingerprint) are not: fix the request or start a new session.

Which BotDeflector steps are supported?

The icon challenge. BotDeflector's proof-of-work and audio steps are not available through the API yet.

What happens when Queue-it adds new icons?

We run the solver against Queue-it's live endpoint, so a new icon library shows up in the pass rate. When a new one appeared in November 2026, the pass rate fell to 36%; extending the solver to it brought the next live run back to 100%.

How long is the flow token valid?

About two minutes. Fetch the challenge, solve it and post your answers within that time; a token that has run out has to be replaced from the waiting room page.

Am I charged for a wrong answer?

You pay €0.001 when Parsa returns a solution, a 200. If the solver can't read a frame, it answers 422 and you pay nothing.

GuideHow Queue-it BotDeflector worksRead the guide →

Other solvers