# Cloudflare Waiting Room vs a Challenge Page: What Crawlers See

> A Cloudflare Waiting Room is a queue, not a bot check. How to tell it from a challenge page, how its cookie and JSON mode work, and how to wait your turn.

- Source: https://zerocaptcha.io/blog/cloudflare-waiting-room
- Published: 2026-10-01
- Author: ZeroCaptcha Engineering

A **Cloudflare Waiting Room** is a queue, not a bot check. It holds visitors when traffic to a
page passes limits the site owner set ("total active users" and "new users per minute"), shows
them a waiting page that refreshes itself every 20 seconds, and keeps their place in an encrypted
cookie named `__cfwaitingroom`. A **challenge page** is different: it answers HTTP 403 with the
header `cf-mitigated: challenge`, and waiting does not help, while a waiting room answers `200` by
default and waiting is the whole point. An automated client should keep its cookie, ask again at
the room's interval, and never open new sessions to jump the line.

This explainer compares the two, shows the JSON mode Cloudflare offers for non-browser clients, and
gives a polite client that waits its turn. Facts are from Cloudflare's documentation as checked on
1 October 2026.

## Waiting room or challenge page?

| | Waiting room | Challenge page |
| --- | --- | --- |
| Why you see it | Traffic passed the owner's limits | A rule, Bot Management or Under Attack mode challenged your request |
| Status | `200` by default; the owner can pick another code | `403` |
| Marker | The `__cfwaitingroom` cookie; with JSON mode, a `cfWaitingRoom` object | Header `cf-mitigated: challenge` |
| What passes it | Time: the queue lets you in when there is room | Passing the challenge, which sets `cf_clearance` |
| What a client should do | Wait, with its cookie, at the room's interval | Back off, or pass it where allowed |

A waiting room can also include a Cloudflare Turnstile widget. Its settings offer the modes `off`,
`invisible`, `visible_non_interactive` and `visible_managed` (default `invisible`), and two actions
for a failed check, `log` (the default) and `infinite_queue`. In Cloudflare's analytics for that
widget, an infinite queue shows up as "the number of refresh requests from bots in the infinite
queue": a client judged a bot keeps waiting and never gets in.

## How the queue works

- **Limits:** the owner sets the number of active users the site can take at once and how many
  new users may enter per minute; the room queues everyone beyond them.
- **Order:** "First In First Out (FIFO)" by default. Some plans can use Random, Passthrough (let
  everyone through) or Reject (let nobody through).
- **Refresh:** in a browser, "the user's browser automatically refreshes every 20 seconds".
- **Cookie:** `__cfwaitingroom` holds "a unique group ID corresponding to when the visitor entered
  the waiting room" and an `acceptedAt` value. While queued, its "expiration is always set to five
  minutes, but renews every 20 seconds"; once in, it lasts for the room's session duration, 5 minutes
  by default and up to 30.
- **Cookies are required:** "When a waiting room is actively queueing, users cannot visit that host
  and path combination without enabling cookies."

## JSON mode for non-browser clients

A site owner can turn on JSON responses for "mobile and other non-browser traffic" (the
`json_response_enabled` setting, off by default). The client must send exactly
`Accept: application/json`: "If it is anything else or has any additional content such as
`Accept: application/json, text/html` the response will not return in the JSON format." The reply
while queued looks like this, in Cloudflare's example:

```json
{
  "cfWaitingRoom": {
    "inWaitingRoom": true,
    "waitTime": 5,
    "waitTimeKnown": true,
    "waitTimeFormatted": "5 minutes",
    "queueIsFull": false,
    "queueAll": false,
    "lastUpdated": "2021-08-03T23:46:00.000Z",
    "refreshIntervalSeconds": 20
  }
}
```

The client must "retry the request every `refreshIntervalSeconds` in order for users to advance in
the queue", sending the cookie and keeping it updated from each response. Without the cookie, the
room treats the client as new, at the back of the queue.

## A client that waits its turn

This Python function waits in a room with one session, at the interval the room asks for, and
gives up after a limit you choose. It returns the first response that is not a queue reply; ask
for the page again with your usual headers once it returns.

```python
import time

import requests


def wait_in_queue(session, url, max_wait_seconds=1800):
    deadline = time.monotonic() + max_wait_seconds
    while time.monotonic() < deadline:
        response = session.get(url, headers={"Accept": "application/json"}, timeout=30)
        try:
            state = response.json().get("cfWaitingRoom")
        except (ValueError, AttributeError):
            state = None
        if not state or not state.get("inWaitingRoom"):
            return response
        print("queued, estimated wait:", state.get("waitTimeFormatted", "unknown"))
        time.sleep(state.get("refreshIntervalSeconds", 20))
    raise TimeoutError(f"still queued after {max_wait_seconds} seconds")


with requests.Session() as session:
    wait_in_queue(session, "https://tickets.example.com/event/42")
    page = session.get("https://tickets.example.com/event/42", timeout=30)
    print(page.status_code)
```

If the owner has not turned on JSON mode, the queue page is HTML: wait 20 seconds between
requests, keep the same session, and look for the page you asked for.

Three rules keep a crawler from hurting the queue it is in:

- **One session per place in line.** Opening many sessions puts many places in the queue, which
  pushes real visitors back. Don't.
- **Honour the interval.** Asking faster than `refreshIntervalSeconds` does not move you up.
- **Set a limit.** A queue can be long, and a client judged a bot may be put in an infinite queue.
  Give up after a time that fits your job.

## Where ZeroCaptcha fits, and where it doesn't

A waiting room has nothing to solve, and ZeroCaptcha does not move anyone up a queue. What it
covers are the checks that sit in front of pages: Cloudflare Turnstile widgets in forms, through
the [Cloudflare Turnstile solver](https://zerocaptcha.io/cloudflare-turnstile-solver),
and Cloudflare challenge pages, through the [Cloudflare WAF and 5-second challenge solver](https://zerocaptcha.io/cloudflare-challenge-solver).
If a site answers with a challenge rather than a queue, see
[Cloudflare challenge types](https://zerocaptcha.io/blog/cloudflare-challenge-types); if it answers 429 with error 1015,
you are being rate limited, which [Cloudflare error 1015](https://zerocaptcha.io/blog/cloudflare-error-1015) covers.

## Sources

- [Cloudflare Waiting Room: about](https://developers.cloudflare.com/waiting-room/about/)
  (checked 1 October 2026).
- [Cloudflare Waiting Room: get JSON response for mobile and other non-browser traffic](https://developers.cloudflare.com/waiting-room/how-to/json-response/)
  (checked 1 October 2026).
- [Cloudflare Waiting Room: cookies](https://developers.cloudflare.com/waiting-room/reference/waiting-room-cookie/)
  (checked 1 October 2026).
- [Cloudflare Waiting Room: configuration settings](https://developers.cloudflare.com/waiting-room/reference/configuration-settings/)
  and [queueing methods](https://developers.cloudflare.com/waiting-room/reference/queueing-methods/)
  (checked 1 October 2026).
- [Cloudflare Waiting Room: analytics](https://developers.cloudflare.com/waiting-room/waiting-room-analytics/),
  for Cloudflare Turnstile widget traffic (checked 1 October 2026).
- [Cloudflare challenges: detect a challenge response](https://developers.cloudflare.com/cloudflare-challenges/challenge-types/challenge-pages/detect-response/)
  (checked 1 October 2026).
- [Cloudflare: Error 403](https://developers.cloudflare.com/support/troubleshooting/http-status-codes/4xx-client-error/error-403/)
  (checked 1 October 2026).

## Questions

### Is a Cloudflare Waiting Room a bot check?

No. It is a queue that holds visitors when traffic passes the limits the site owner set, total active users and new users per minute. A waiting room can also run a Cloudflare Turnstile widget, but its main job is pacing, not detecting bots.

### How does a script wait in a Cloudflare Waiting Room?

Keep the __cfwaitingroom cookie and ask again at the interval the room gives. If the owner turned on JSON responses, send exactly Accept: application/json and retry every refreshIntervalSeconds with the updated cookie; without the cookie you go to the back of the queue.

### Can a solving API skip a Cloudflare Waiting Room?

No, and it should not. There is nothing to solve: the queue lets visitors in as the site has room for them. Wait your turn with one session and a time limit.
