Skip to content
capzy
TikTok / ByteDance Captcha
TikTokCaptchaTaskProxyLess

TikTok / ByteDance Captcha Solver, solved in 5.0s.

Solve all four ByteDance captcha types — slide puzzle, whirl (rotate), 3D object match, and icon select. Send the challenge image(s); get back the exact move to apply in your own session.

Avg Speed~5.0s
Success99%+
Cost / 1k$2.00
Throughput12/m

ByteDance's captcha is shared across TikTok, CapCut, Lark and Douyin. It has four visual variants: • Slide (puzzle) — drag a piece to fill a gap in a background image. • Whirl (rotate) — spin an inner disc until it aligns with the outer ring. • 3D — several 3D-rendered objects; click the two that are the same shape. • Icon — an image plus a text instruction; click the matching icons, in order. Select the variant with captchaType (slide / whirl / 3d / icon). If you omit it we auto-detect from the images you send.

Quick Integration

Drag a piece to fill a gap in the background. Send the gapped background as `image` and the piece as `pieceImage` (keep its alpha). We return how far to drag — `slideXProportion` (× your track width) or `distance` in px.

solve.py
import requests, time

API = "https://api.capzy.ai"
KEY = "capzy_your_key_here"

# Step 1: Create task
task = requests.post(f"{API}/createTask", json={
    "clientKey": KEY,
    "task": {
        "type": "TikTokCaptchaTaskProxyLess",
        "captchaType": "slide",
        "image": "<base64 gapped background>",
        "pieceImage": "<base64 piece — keep transparency>",
        "puzzleWidth": 340
    }
}).json()

task_id = task["taskId"]
print(f"Task created: {task_id}")

# Step 2: Poll for result
while True:
    result = requests.post(f"{API}/getTaskResult", json={
        "clientKey": KEY,
        "taskId": task_id
    }).json()

    if result["status"] == "ready":
        print("Solved!", result["solution"])
        break
    elif result["status"] == "failed":
        print("Failed:", result.get("errorDescription"))
        break

    time.sleep(1)

Using the result

Slide: send image (the gapped background) + pieceImage. Drag the piece distance px — or slideXProportion × your rendered track width — in your own session.

use_result.py
# Slide — drag the piece by "distance" px (or slideXProportion × your track width)
sol = result["solution"]
distance = sol["distance"]                 # px to drag, e.g. 210
proportion = sol["slideXProportion"]       # 0-1 fraction of the track
# Playwright: mouse.down(); mouse.move(start_x + distance, y); mouse.up()

1. Send Payload

Dispatch your TikTokCaptchaTaskProxyLess to our processing cluster via the secure API endpoint.

2. Solving Engine

This is an image-in / answer-out solver: you extract the challenge image(s) from the page and send them; we run the vision pipeline and return the move to make (a drag distance, a rotation angle, or click points). Your own automation performs the drag/click in the real session. We deliberately do NOT mint a token — ByteDance binds verification to your device, cookies and session, so a token produced on our side would be unusable to you. Because of that, no proxy is needed to solve; an optional proxy is only used if you ask us to fetch the challenge image from a URL instead of sending it inline.

3. Get Result

Poll getTaskResult for the validated token, then finalize your automated request.

Using your own proxy

Use TikTokCaptchaTask instead of TikTokCaptchaTaskProxyLess to route the solve through your own proxy — useful when the target site checks that the solving IP matches the submitting IP.

solve_proxy.py
import requests, time

API = "https://api.capzy.ai"
KEY = "capzy_your_key_here"

# Step 1: Create task
task = requests.post(f"{API}/createTask", json={
    "clientKey": KEY,
    "task": {
        "type": "TikTokCaptchaTask",
        "captchaType": "slide",
        "imageUrl": "https://p16-sign.tiktokcdn.com/.../bg.webp",
        "pieceImageUrl": "https://p16-sign.tiktokcdn.com/.../piece.png",
        "proxyType": "http",
        "proxyAddress": "123.45.67.89",
        "proxyPort": "8080",
        "proxyLogin": "user",
        "proxyPassword": "pass"
    }
}).json()

task_id = task["taskId"]
print(f"Task created: {task_id}")

# Step 2: Poll for result
while True:
    result = requests.post(f"{API}/getTaskResult", json={
        "clientKey": KEY,
        "taskId": task_id
    }).json()

    if result["status"] == "ready":
        print("Solved!", result["solution"])
        break
    elif result["status"] == "failed":
        print("Failed:", result.get("errorDescription"))
        break

    time.sleep(1)

Additional proxy parameters

proxyTypetypestringreqyesProxy protocol: http, https, socks4, or socks5
proxyAddresstypestringreqyesProxy IP address or hostname
proxyPorttypenumberreqyesProxy port number
proxyLogintypestringreqnoProxy username (if auth required)
proxyPasswordtypestringreqnoProxy password (if auth required)
userAgenttypestringreqnoUser-Agent string to use. Must match the UA you use when submitting the token

Task Parameters

API Spec
typetypestringreqyesTikTokCaptchaTaskProxyLess (default) or TikTokCaptchaTask (only needed if you want us to fetch an image URL through your proxy)
captchaTypetypestringreqnoslide | whirl | 3d | icon. Aliases accepted (puzzle=slide, rotate=whirl, shapes=3d, select=icon). Auto-detected from the images if omitted.
imagetypestringreqnoBase64 image. SLIDE: the gapped background. 3D / ICON: the single challenge image. (Alias: bgImage. Or pass imageUrl / bgImageUrl to have us download it.)
pieceImagetypestringreqnoSLIDE only — base64 of the puzzle piece (keep its transparency/alpha; it locates the piece's home position). Alias: piece / pieceImageUrl.
outerImagetypestringreqnoWHIRL only — base64 of the outer ring (the larger image). Alias: outerImageUrl.
innerImagetypestringreqnoWHIRL only — base64 of the inner disc (the smaller image). Alias: innerImageUrl.
questiontypestringreqnoICON only — the on-page instruction text (e.g. 'select the objects in the order shown'). Alias: comment / prompt.
puzzleWidthtypenumberreqnoSLIDE (optional) — rendered width of the drag track in px, so distance comes back in your widget's pixels. Alias: trackWidth. Defaults to the image width.
sliderWidthtypenumberreqnoWHIRL (optional) — width of the drag bar in px, so distance is scaled to your widget. Alias: trackWidth / drag_width.

Response Shape

slideXProportiontypenumberSLIDE — how far to drag as a 0-1 fraction of the track. Multiply by your rendered track width to get pixels. (Alias: slideProportion.)
distancetypenumberSLIDE / WHIRL — the move in pixels: drag distance for slide, or the drag length that produces the rotation for whirl.
angletypenumberWHIRL — degrees (0-360) to rotate the inner disc so it aligns with the ring.
xtypenumberSLIDE — the detected gap centre in image pixels (diagnostic).
clickTargetstypearray3D / ICON — points to click as [{x, y}] in image pixels, in order.
pointOneProportionXtypenumber3D — first object's centre X as a 0-1 fraction of image width (also pointOneProportionY, pointTwoProportionX, pointTwoProportionY). Device-independent.
x1typenumber3D — first object's centre in image pixels (also y1, x2, y2).
proportionalPointstypearrayICON — click points as [{proportionX, proportionY}] 0-1 fractions, in order.

Example response

{
  "errorId": 0,
  "status": "ready",
  "solution": {
    "angle": 273,
    "slideProportion": 0.2417,
    "distance": 84
  }
}

Error response

{
  "errorId": 1,
  "errorCode": "ERROR_CAPTCHA_UNSOLVABLE",
  "errorDescription": "Solver gave up."
}

Features

All four variants: slide, whirl, 3D and icon
Answer-out model — no device/session binding to worry about
Whirl solved to sub-degree accuracy
Accepts base64 or image URLs
No proxy required to solve
SadCaptcha-compatible response fields for drop-in migration

Pricing & Stats

Per 1,000 solves$2.00
Avg solve time~5.0s
Success rate99%+
Throughput12/m

Start solving tiktok / bytedance captcha.

$0.10 in free credits — no card. ~250 free solves to test before you spend.

Frequently asked questions