Popular Captcha Solver
Solve object-interaction captchas using the PopularCaptchaImage or PopularClassification task types. The questionType field determines how the challenge is processed.
Supported Modes
questionType | Description | Response Format |
|---|---|---|
objectClassify | Select all matching images from a grid | boolean[] per image |
objectClick | Click on the center of a target object | {x, y}[] coordinates |
objectDrag | Drag puzzle pieces to their correct position | {start, end}[] |
objectTag | Tag objects in an image | Labels array |
grid | Generic grid selection | Boolean array |
bbox | Bounding box detection | Coordinates |
Create Task — Grid Classify
/createTask{
"apiKey": "YOUR_API_KEY",
"task": {
"type": "PopularCaptchaImage",
"questionType": "objectClassify",
"question": "Select all objects with a bridge",
"queries": ["BASE64_IMG_1", "BASE64_IMG_2"]
}
}
Response
{
"code": 200,
"msg": "",
"answers": [true, false, true, true, false, true],
"questionType": "objectClassify",
"meta": { "pass_report": true, "fail_report": true }
}
Create Task — Object Click
{
"apiKey": "YOUR_API_KEY",
"task": {
"type": "PopularCaptchaImage",
"questionType": "objectClick",
"question": "Click on the center of the car",
"queries": ["BASE64_MAIN_IMAGE"]
}
}
Create Task — Object Drag
{
"apiKey": "YOUR_API_KEY",
"task": {
"type": "PopularCaptchaImage",
"questionType": "objectDrag",
"question": "Drag the puzzle piece to the gap",
"queries": ["BASE64_BACKGROUND"],
"examples": ["BASE64_PUZZLE_PIECE"]
}
}
Task Parameters
| Property | Type | Required | Description |
|---|---|---|---|
type | string | ✅ | PopularCaptchaImage or PopularClassification |
questionType | string | ✅ | objectClassify, objectClick, objectDrag, objectTag, grid, bbox |
question | string | ✅ | The challenge instruction text |
queries | string[] | ✅ | Base64-encoded images |
examples | string[] | Drag only | Target objects for drag tasks |
screenshort | boolean | No | Set true if images are screenshots |
Video Captcha Solving (Dynamic Canvas)
Some challenges (e.g. hCaptcha variants) contain dynamic canvas animations instead of static images. These are solved using a specialized variant of the PopularCaptchaImage task type, requiring client-side canvas capturing/recording (either blending multiple video frames into a single image or submitting raw video).
To avoid recording and processing video on every challenge, it is highly recommended to implement a client-side caching mechanism mapping the target question to the resolved canvas configuration.
Caching Strategy (Client-side)
- Homoglyph Normalization: Clean the
questiontext of Unicode homoglyphs (Cyrillic/Greek characters looking like English letters) before querying or saving to the cache. This ensures cache keys match the backend's normalization pipeline. - TTL (Time to Live): 24 hours.
- Capacity: Maximum 800 entries with LRU (Least Recently Used) eviction.
- Cache Key:
"nc_video_cache"mapping normalized question text tocanvasParams.
Solving Workflows
Scenario A: Cache Miss (Two-Phase Flow)
sequenceDiagram
participant Client
participant Server
Note over Client: Step 1: Detect challenge
Client->>Server: POST /createTask (Initial standard payload)
Server-->>Client: 400 Bad Request (questionVariant: "canvasvideo")
Note over Client: Step 2: Intercept canvasParams & Save to cache
Note over Client: Step 3: Record canvas video (e.g., duration 2s) & Blend frames
Client->>Server: POST /createTask (Enriched phase 2 payload)
Server-->>Client: 200 OK (Solved answers coordinates)
- Initial Grab: Submit a standard single-frame request to the solver API (
/createTask). - Backend Signal: If the backend detects that this target question is a video captcha, it responds with
400status code andquestionVariant: "canvasvideo"containing the requiredcanvasParams. - Cache Storage: Save these
canvasParamslocally. - Canvas Recording & Blending:
- If
canvasParams.videoistrue, record the canvas for the configured duration. - Extract and blend/merge the frames according to
canvasParams.format.
- If
- Phase 2 Resubmission: Construct an enriched payload containing
canvasVideo: true, the blended frame inqueries, and the recorded video base64 array. Re-submit to the backend to get a200success response.
Scenario B: Cache Hit (One-Phase Flow)
sequenceDiagram
participant Client
participant Server
Note over Client: Step 1: Query cache (Normalized question match)
Note over Client: Step 2: Immediate canvas recording & frame blending
Client->>Server: POST /createTask (Enriched payload directly)
Server-->>Client: 200 OK (Solved answers coordinates)
Note over Client: Fallback: If server rejects, invalidate cache and run Two-Phase
- Pre-solve Cache Check: Query the local cache using the normalized question text.
- Instant Canvas Prep: If a valid cache entry exists, immediately record the canvas and blend/merge the frames based on the cached parameters.
- One-Phase Submission: Submit the fully compiled payload (blended frame + video data) directly in the first request.
- Invalidation Fallback: If the server rejects the request (e.g., cached params expired or changed on the server), invalidate/delete the cached configuration and fallback to a fresh Two-Phase Flow.
Payload Structures
1. Initial Request (Phase 1 - Cache Miss)
Sent when first trying to solve the captcha before knowing it requires video handling.
{
"apiKey": "YOUR_API_KEY",
"task": {
"type": "PopularCaptchaImage",
"queries": ["data:image/jpeg;base64,..."],
"examples": ["data:image/jpeg;base64,..."],
"question": "Please click on the living room",
"screenshot": false,
"questionType": "objectClick",
"websiteURL": "example.com",
"websiteKEY": "sitekey-value"
}
}
2. Response (Indicates Video Captcha Required)
Returned when the backend detects a video captcha is required.
{
"code": 400,
"msg": "canvasvideo",
"questionVariant": "canvasvideo",
"questionType": "objectClick",
"canvasParams": {
"duration": 2,
"video": true,
"format": ["frameMerge"],
"frames": [0.1, 0.5, 1.0],
"framecount": null
}
}
3. Enriched Request (Phase 2 Resubmit / One-Phase Cache Hit)
Contains the blended image (in queries) and the recorded canvas video.
{
"apiKey": "YOUR_API_KEY",
"task": {
"type": "PopularCaptchaImage",
"queries": ["data:image/jpeg;base64,..."], // Blended frame result
"examples": ["data:image/jpeg;base64,..."],
"question": "please click on the living room", // Normalized question
"screenshot": false,
"questionType": "objectClick",
"websiteURL": "example.com",
"websiteKEY": "sitekey-value",
"choices": [],
"canvasVideo": true,
"format": "frameMerge", // or "framecount"
"video": ["data:video/mp4;base64,..."] // Base64 recorded video
}
}
4. Response (Successful Solve)
{
"code": 200,
"status": "ready",
"questionType": "objectClick",
"answers": [
[
{ "x": 109, "y": 179 },
{ "x": 163, "y": 260 }
]
],
"meta": {
"data": "...",
"fail_report": true,
"pass_report": true
}
}
Error Codes
| Code | Error | Description |
|---|---|---|
| 1 | KEY_DOES_NOT_EXIST | API key is invalid or not found. |
| 2 | NO_SLOT_AVAILABLE | All solver slots are occupied. |
| 3 | ZERO_BALANCE | Account balance is zero. |
| 10 | ERROR_BAD_PARAMETERS | Invalid or missing request fields. |
| 12 | ERROR_CAPTCHA_UNSOLVABLE | Captcha could not be solved. |
| 14 | PLAN_EXPIRED | Your plan has expired. |
| 16 | RATE_LIMITED | Too many requests. Slow down. |
| 17 | DAILY_LIMIT_EXCEEDED | Daily usage limit reached. |
| 18 | QUOTA_LIMIT_EXCEEDED | Plan quota exhausted. |
| 21 | SERVICE_UNAVAILABLE | Backend is temporarily unavailable. |
Code Examples
# Step 1: Create a task
RESPONSE=$(curl -s -X POST "https://api.captchasonic.com/createTask" \
-H "Content-Type: application/json" \
-d '{
"apiKey": "YOUR_API_KEY",
"task": {
"type": "PopularCaptchaImage",
"questionType": "objectClassify",
"question": "Select all objects with a bridge",
"queries": [
"BASE64_IMG_1",
"BASE64_IMG_2"
]
}
}')
echo "Create Task Response: $RESPONSE"
TASK_ID=$(echo $RESPONSE | grep -o '"taskId":"[^"]*"' | cut -d'"' -f4)
# Step 2: Poll for the result
while true; do
RESULT=$(curl -s -X POST "https://api.captchasonic.com/getTaskResult" \
-H "Content-Type: application/json" \
-d "{\"apiKey\": \"YOUR_API_KEY\", \"taskId\": \"$TASK_ID\"}")
echo "Result: $RESULT"
echo "$RESULT" | grep -q '"status":"processing"' || break
sleep 2
done
API Playground
Hit Send to see response
⌘ + Enter