TikTok / ByteDance CAPTCHA
Turn the challenge images into an answer for your flow. Read the current challenge mode and save its original images. Slide, whirl, 3D, and icon tasks consume different image sets and return different answers.
{
"clientKey": "capzy_YOUR_API_KEY",
"task": {
"type": "TikTokCaptchaTaskProxyLess",
"captchaType": "slide",
"image": "<base64 gapped background>",
"pieceImage": "<base64 piece — keep transparency>",
"puzzleWidth": 340
}
}Illustrative values. Replace the inputs with values from your current integration.
Collect the images for the selected mode.
Read the current challenge mode and save its original images. Slide, whirl, 3D, and icon tasks consume different image sets and return different answers.
Your API key authenticates Capzy.
Provider keys, challenge IDs, images, and session values belong inside task.
Choose the challenge mode before encoding.
- In Network, locate the current challenge response and save the original image bytes. Keep dimensions and transparency intact.
- For slide, use image and pieceImage. For whirl, use outerImage and innerImage. For 3D or icon, use the single image; icon also needs question.
- Base64-encode each file into the matching field and select the request variant that describes the current challenge.
import base64
from pathlib import Path
def image_bytes(filename):
return base64.b64encode(Path(filename).read_bytes()).decode("ascii")
task_inputs = {
"captchaType": "slide",
"image": image_bytes("background.png"),
"pieceImage": image_bytes("piece.png")
}A screenshot, resized background, or flattened puzzle piece can change the geometry. Prefer the original image responses.
How TikTok / ByteDance CAPTCHA works
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.
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.
- 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
Know what goes in.
Choose a field to see its purpose, where to get it, and its place in the request. Optional values omitted from the example can be added when your flow uses them.
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.
Request authentication
Required task inputs
Optional context
type
stringRequiredThe exact API identifier for the selected task variant and network mode.
Choose the task/network or request variant on this page. The integration examples update this exact API task identifier.
Open the input guideTikTokCaptchaTaskProxyLess{
"clientKey": "capzy_YOUR_API_KEY",
"task": {
"type": "TikTokCaptchaTaskProxyLess",
"captchaType": "slide",
"image": "<base64 gapped background>",
"pieceImage": "<base64 piece — keep transparency>",
"puzzleWidth": 340
}
}The selected field is highlighted when present. Preserve the declared value type and current challenge context.
Make your first request.
Create the task, keep its taskId, and poll until status is ready. Then read the selected variant's solution.
- Create the task
Send
clientKeyand the selectedtaskto/createTaskfrom your server. Keep the returnedtaskId. - Wait for the solution
Send that same key and ID to
/getTaskResult. While processing, wait two seconds before checking again. Stop on Ready or an error. - Apply the result
Use the mode's answer: slide proportion/distance, whirl angle/distance, or ordered clickTargets. Scale coordinates to the rendered image and preserve sequential clicks in the original challenge flow.
import json, os, time
import requests
API = "https://api.capzy.ai"
KEY = os.environ["CAPZY_API_KEY"]
task = json.loads("{\"type\":\"TikTokCaptchaTaskProxyLess\",\"captchaType\":\"slide\",\"image\":\"<base64 gapped background>\",\"pieceImage\":\"<base64 piece — keep transparency>\",\"puzzleWidth\":340}")
def call(path, payload):
response = requests.post(f"{API}/{path}", json={"clientKey": KEY, **payload}, timeout=30)
response.raise_for_status()
data = response.json()
if data.get("errorId", 0) or data.get("status") == "failed":
raise RuntimeError(data.get("errorDescription") or data.get("errorCode") or "Task failed")
return data
created = call("createTask", {"task": task})
for attempt in range(60):
result = call("getTaskResult", {"taskId": created["taskId"]})
if result.get("status") == "ready":
solution = result["solution"]
print(solution)
break
time.sleep(2)
else:
raise TimeoutError("Task is still processing; keep the taskId to check it later.")
Before runningReplace all illustrative inputs with your captured values. Set CAPZY_API_KEY in your environment. Install requests with pip install requests.
Polling and failuresThe example checks HTTP/API failures, uses 30-second request timeouts, and stops after 60 result checks. Retain taskId if your task is still processing.
Understand what comes back.
Follow this task from creation to completion. Response fields and usage follow your selected request variant.
Slide, rotation, or click answer
Use the mode's answer: slide proportion/distance, whirl angle/distance, or ordered clickTargets. Scale coordinates to the rendered image and preserve sequential clicks in the original challenge flow.
- number
- SLIDE: alias of slideXProportion. WHIRL: slider travel as a fraction of its width, angle divided by 360.
- number
- SLIDE — how far to drag as a 0-1 fraction of the track. Multiply by your rendered track width to get pixels. (Alias: slideProportion.)
- number
- SLIDE / WHIRL — the move in pixels: drag distance for slide, or the drag length that produces the rotation for whirl.
- number
- SLIDE — the detected gap centre in image pixels (diagnostic).
{
"errorId": 0,
"status": "ready",
"solution": {
"slideXProportion": 0.2417,
"slideProportion": 0.2417,
"distance": 82,
"x": 108
}
}Illustrative values. Additional metadata may be returned; only Ready contains a completed solution.
Slide (puzzle)
Slide: send image (the gapped background) + pieceImage. Drag the piece distance px — or slideXProportion × your rendered track width — in your own session.
Execution context Install Playwright (pip install playwright) and its browser (playwright install chromium). page is your existing synchronous Python Playwright Page showing this same challenge. result is the parsed Ready response; task is the task you submitted. Replace image and slider selectors with this widget's actual elements. The snippets account for displayed size and viewport position; keep the image unobscured and unrotated.
# 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()When something doesn't work.
Check your captured values, the selected variant, and the response before starting another task.
Which variant am I looking at?
Two concentric round images = whirl (send outerImage + innerImage). A wide background with a cut-out gap + a separate piece = slide (send image + pieceImage). A single image with several 3D-rendered shapes = 3d. A single image plus a written instruction = icon (send the instruction as question). If unsure, omit captchaType and we auto-detect.
How do I apply the answer?
You perform the move in your own browser/automation session. Slide: drag the piece by distance px (or slideXProportion × your track width). Whirl: drag until the disc has rotated angle degrees (or use distance). 3D / Icon: click each point in clickTargets (or the proportional points scaled to your rendered image size), in order.
Do I need a proxy?
No. The solve is stateless image processing, so a proxy is never required. The only time you'd use TikTokCaptchaTask with a proxy is if you send image URLs instead of base64 and want us to download them through a specific IP.
Why don't you return a token?
ByteDance verification is bound to your device_id, cookies and session IP. A token minted on our infrastructure would be rejected on yours, so we return the answer for you to submit on your own session — which is also why detection sees your real browser doing the drag.
The response uses the same field names as other services?
Yes — slideXProportion, angle, and the proportional click points mirror the common TikTok-solver contract, so existing integrations work with only an endpoint change.
Connect TikTok / ByteDance CAPTCHA to your workflow.
Get your Capzy API key and use this guide's integration.
TikTokCaptchaTaskProxyLess · Live configuration