Why CAPTCHA solving is needed
Before Suno accepts a generation request, it verifies that the request comes from a real browser session that has passed an hCaptcha challenge. There is currently no way to bypass this requirement without completing the challenge. 2Captcha routes screenshots of the challenge to human workers who click the correct tiles and return coordinates.Setting up 2Captcha
Create an account
Register at 2captcha.com/auth/register as a customer.
If you are located in Russia or Belarus, use ruCaptcha instead. It is the same service with the same API, but supports payment methods available in those countries.
Top up your balance
Go to 2captcha.com/pay and add funds. CAPTCHA solves are billed per solve — expect approximately 0.003 per challenge. Costs vary based on challenge difficulty and worker availability.
Get your API key
Retrieve your API key from 2captcha.com/enterpage#recognition and set it as
TWOCAPTCHA_KEY in your environment.How CAPTCHA solving works
The following sequence runs automatically before each call to/api/generate/v2/:
Check if CAPTCHA is required
The API sends a POST request to Suno’s check endpoint:If the
required field in the response is false, CAPTCHA solving is skipped and null is passed as the token.Launch a headless browser
A Playwright browser (chromium by default, or firefox if The browser context is configured with the same
BROWSER=firefox) is launched using rebrowser-playwright-core with anti-bot detection flags:userAgent (randomised as a macOS user agent), locale, and all session cookies — including the current JWT __session token — so that Suno sees an authenticated browser.Navigate to suno.com/create and trigger the challenge
The browser opens
https://suno.com/create and waits for the song list API call to confirm the page is ready. Any popup dialogs are dismissed. A dummy prompt (Lorem ipsum) is typed into the composition textarea, then the Create button is clicked to trigger the hCaptcha iframe.Screenshot the challenge and send to 2Captcha
The If 2Captcha returns an error, the send is retried up to 3 times before the error is propagated.
.challenge-container element inside the hCaptcha iframe is screenshotted and sent to 2Captcha via the coordinates method of the @2captcha/captcha-solver package:Handle drag or click challenges
2Captcha workers return a list of coordinate objects. The challenge type is detected by checking whether the prompt text contains the word Drag challenges — coordinates are returned in pairs (source → destination). Playwright performs a If the solution for a drag challenge does not contain an even number of points, it is reported as bad to 2Captcha and a new solution is requested.
drag:Click challenges — Playwright clicks each returned (x, y) coordinate within the challenge container:mousedown, moves over 30 steps, then releases:Submit and intercept the token
After clicking, the hCaptcha submit button (
.button-submit) is clicked. The browser intercepts the outgoing POST /api/generate/v2/ request triggered by the successful CAPTCHA submission. The token field from the intercepted request body is extracted and used as the CAPTCHA token for the real generation payload.The browser is then closed and the token is returned.Configuration options
Browser selection
SetBROWSER=chromium (default) or BROWSER=firefox. Chromium is strongly recommended — Firefox support exists but is less tested.
Ghost cursor
SettingBROWSER_GHOST_CURSOR=true enables ghost-cursor-playwright for smooth, human-like mouse movement curves when clicking CAPTCHA tiles.
Ghost cursor does not appear to reduce the frequency of CAPTCHA challenges in practice. The option is retained for future experimentation.
Browser locale
BROWSER_LOCALE is passed both to the Playwright browser context and to 2Captcha as the lang parameter. Using en or ru is recommended — those locales have the largest pools of available workers on 2Captcha, which reduces wait times.
For a full list of supported language codes, see the 2Captcha language list.
GPU acceleration
SetBROWSER_DISABLE_GPU=true when running inside Docker. This adds the --disable-gpu and --enable-unsafe-swiftshader flags to the browser launch arguments.
Headless mode
SetBROWSER_HEADLESS=false during local development to watch the browser interact with the CAPTCHA in real time. Keep it true in production and Docker deployments.
Reducing CAPTCHA frequency
Pricing
2Captcha charges per solved CAPTCHA. Typical costs:| Challenge type | Approximate cost |
|---|---|
| Standard click | 0.002 per solve |
| Drag / complex | 0.003 per solve |
