captchasonic

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 5, 2026 License: MIT Imports: 17 Imported by: 0

README

CaptchaSonic Go SDK

Official Go SDK for the CaptchaSonic CAPTCHA solving API — gRPC binary transport (fastest) + HTTP/REST fallback.

Go Reference Go Report Card

Installation

go get github.com/Captcha-Sonic/captchasonic-go@latest

Or pinned to a specific version:

go get github.com/Captcha-Sonic/captchasonic-go@v1.0.0

Quick Start

package main

import (
    "context"
    "fmt"
    "log"
    "os"

    "github.com/Captcha-Sonic/captchasonic-go"
)

func main() {
    // Create client — gRPC binary transport (default, fastest)
    client, err := captchasonic.NewClient("sonic_your_api_key")
    if err != nil {
        log.Fatal(err)
    }
    defer client.Close()

    ctx := context.Background()

    // Check balance
    balance, _ := client.GetBalance(ctx)
    fmt.Printf("Balance: $%.4f\n", balance)

    // Solve CAPTCHA — images sent as raw binary (zero base64 overhead)
    imgBytes, _ := os.ReadFile("tile.png")
    resp, err := client.SolvePopularCaptcha(ctx, [][]byte{imgBytes},
        "Select all traffic lights", "objectClassify")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("Solution:", resp.TypedSolution.GetGrid().GetObjects())
}

Transports

Transport Default Speed Images
gRPC ✅ yes Fastest — binary, HTTP/2 Raw []byte
HTTP no Good — JSON REST Auto base64-encoded

gRPC is the default. Pass WithHTTP() only if you specifically need the REST transport.

Configuration Options

// Production gRPC (default)
client, _ := captchasonic.NewClient("sonic_xxxx")

// HTTP/REST transport
client, _ := captchasonic.NewClient("sonic_xxxx", captchasonic.WithHTTP())

// Custom endpoint
client, _ := captchasonic.NewClient("sonic_xxxx",
    captchasonic.WithEndpoint("api.captchasonic.com:443"))

// Local development (insecure gRPC)
client, _ := captchasonic.NewClient("sonic_xxxx",
    captchasonic.WithEndpoint("localhost:50052"),
    captchasonic.WithInsecure())

// Advanced options
captchasonic.WithTimeout(45 * time.Second)
captchasonic.WithGRPCMsgSize(100 * 1024 * 1024) // 100 MB max message
captchasonic.WithHTTPPool(200, 200, 90*time.Second)

Solve Methods

PopularCaptcha
resp, err := client.SolvePopularCaptcha(ctx, images,
    "Select all traffic lights", "objectClassify",
    captchasonic.WithWebsite("https://example.com", "sitekey"))
ReCaptcha V2
resp, err := client.SolveRecaptchaV2(ctx, images, "traffic lights",
    captchasonic.WithQuestionType("split_33"),
    captchasonic.WithWebsiteURL("https://example.com"))
OCR (Image-to-Text)
// MtCaptcha
resp, err := client.SolveOcr(ctx, images,
    captchasonic.WithModule("mtcaptcha"),
    captchasonic.WithLengthRange(4, 6))

// BLS (numeric)
resp, err := client.SolveOcr(ctx, images,
    captchasonic.WithModule("bls"),
    captchasonic.WithNumeric())
Geetest
// Nine-grid
resp, err := client.SolveGeetest(ctx, "nine", "the bear",
    captchasonic.WithImages(tiles))

// Slide
resp, err := client.SolveGeetest(ctx, "slide", "",
    captchasonic.WithImages(puzzle),
    captchasonic.WithExamples(piece))

// Click
resp, err := client.SolveGeetest(ctx, "click", "the bear",
    captchasonic.WithImages(tiles))
TikTok (type-based)
resp, err := client.SolveTikTok(ctx, "whirl", "Rotate to match", images,
    captchasonic.WithExamples(examples))

resp, err := client.SolveTikTok(ctx, "click", "Select shape", images)
resp, err := client.SolveTikTok(ctx, "slide", "", images)
Binance (type-based)
resp, err := client.SolveBinance(ctx, "grid", "Select the bicycle", images)
resp, err := client.SolveBinance(ctx, "slide", "", images)
AWS WAF
resp, err := client.SolveAwsWaf(ctx, images, "Select all squares",
    captchasonic.WithWebsiteURL("https://example.com"))
Turnstile (token task — auto-polls)
resp, err := client.SolveTurnstile(ctx, "https://example.com", "0x4AAAAAAA")
Other Token Tasks
// Cloudflare (proxy REQUIRED)
client.SolveCloudflare(ctx, url, key, "http://user:pass@host:1080")

// reCAPTCHA v2/v3 token
client.SolveRecaptchaV2Token(ctx, url, key, captchasonic.WithProxyless())
client.SolveRecaptchaV3Token(ctx, url, key, captchasonic.WithProxy("..."))

// PopularCaptcha token (PopularCaptcha browser automation)
client.SolvePopularCaptchaToken(ctx, url, key, captchasonic.WithProxyless())

Task Option Helpers

captchasonic.WithImages(imgs)              // set images via option
captchasonic.WithExamples(exampleImages)   // reference images
captchasonic.WithScreenshot()              // enable screenshot
captchasonic.WithWebsite(url, key)         // billing: websiteUrl + websiteKey
captchasonic.WithWebsiteURL(url)           // billing: websiteUrl only
captchasonic.WithQuestionType(qt)          // e.g. "objectDrag", "split_33"
captchasonic.WithProxy("http://...")       // proxy for token tasks
captchasonic.WithProxyless()               // proxyless variant
captchasonic.WithModule("bls")             // OCR module
captchasonic.WithNumeric()                 // OCR: digits only
captchasonic.WithCaseSensitive()           // OCR: case sensitive
captchasonic.WithLengthRange(3, 8)         // OCR: min/max text length
captchasonic.WithGeetestVersion(4)         // Geetest version

Error Handling

resp, err := client.GetBalance(ctx)
if err != nil {
    if sonicErr, ok := err.(*captchasonic.SonicError); ok {
        fmt.Printf("API error %d: %s\n", sonicErr.ErrorID, sonicErr.Message)
    }
}

Retries automatically on UNAVAILABLE, RESOURCE_EXHAUSTED, DEADLINE_EXCEEDED with exponential backoff (1s, 2s).

Validation

NewClient validates the API key format immediately — zero network calls:

  • Must start with "sonic_"
  • Minimum 12 characters

Per-task validation: images required/count/size, question required, proxy format.

Connection Pooling

  • gRPC: Single grpc.ClientConn multiplexes all calls as HTTP/2 streams. Keep-alive pings every 10s. Create once, reuse across goroutines.
  • HTTP: http.Transport with configurable MaxConnsPerHost (default 100).

License

MIT — see LICENSE.

Documentation

Overview

Package captchasonic is the official Go SDK for the CaptchaSonic API.

Public Endpoints

Transport   Endpoint                             Protocol
─────────── ──────────────────────────────────── ─────────────────────
gRPC        api.captchasonic.com:443             gRPC binary (HTTP/2)
HTTP/REST   https://api.captchasonic.com         JSON REST

Usage

gRPC transport (default — fastest, binary, zero base64 overhead):

c, _ := captchasonic.NewClient("sonic_xxxx")
defer c.Close()
resp, _ := c.SolvePopularCaptcha(ctx, images, "Select all buses", "objectClassify")

HTTP transport (universal fallback — images auto-encoded to base64):

c, _ := captchasonic.NewClient("sonic_xxxx", captchasonic.WithHTTP())
defer c.Close()

Local dev (insecure gRPC):

c, _ := captchasonic.NewClient("sonic_xxxx",
    captchasonic.WithEndpoint("localhost:50052"),
    captchasonic.WithInsecure())

Index

Constants

View Source
const (
	TransportGRPC = "grpc" // native gRPC (default) — fastest, binary, zero base64 overhead
	TransportHTTP = "http" // REST JSON — images sent as base64, universal (browsers + Node)
)

Transport constants.

View Source
const DefaultEndpoint = "api.captchasonic.com:443"

DefaultEndpoint is the production CaptchaSonic gRPC endpoint (host:port, no scheme).

View Source
const DefaultHTTPEndpoint = "https://api.captchasonic.com"

DefaultHTTPEndpoint is the production HTTP/REST endpoint.

Variables

This section is empty.

Functions

func WithCaseSensitive

func WithCaseSensitive() func(*v1.Task)

func WithExamples

func WithExamples(ex [][]byte) func(*v1.Task)

func WithGeetestVersion

func WithGeetestVersion(v int32) func(*v1.Task)

func WithImages

func WithImages(imgs [][]byte) func(*v1.Task)

WithImages sets the images on a task (useful for SolveGeetest where images are passed via options instead of positional args).

func WithLengthRange

func WithLengthRange(min, max int32) func(*v1.Task)

func WithModule

func WithModule(m string) func(*v1.Task)

func WithNumeric

func WithNumeric() func(*v1.Task)

func WithProxy

func WithProxy(p string) func(*v1.Task)

func WithProxyless

func WithProxyless() func(*v1.Task)

WithProxyless signals a token task should use the proxyless variant (no proxy needed).

func WithQuestionType

func WithQuestionType(qt string) func(*v1.Task)

WithQuestionType sets the questionType (e.g. "split_33" for RecaptchaV2, "objectDrag" for PopularCaptcha).

func WithScreenshot

func WithScreenshot() func(*v1.Task)

func WithWebsite

func WithWebsite(url, key string) func(*v1.Task)

func WithWebsiteURL

func WithWebsiteURL(url string) func(*v1.Task)

WithWebsiteURL sets only the websiteURL (no sitekey). Use for analytics.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is a thread-safe, connection-pooled client for the CaptchaSonic API. Create once and reuse across goroutines.

func NewClient

func NewClient(apiKey string, opts ...Option) (*Client, error)

NewClient creates a Client. All URL formats are accepted via WithEndpoint — see WithEndpoint docs.

Examples:

// Production gRPC (default)
c, _ := captchasonic.NewClient("sonic_xxxx")

// Any of these endpoint formats work:
c, _ := captchasonic.NewClient("sonic_xxxx", captchasonic.WithEndpoint("api.captchasonic.com"))
c, _ := captchasonic.NewClient("sonic_xxxx", captchasonic.WithEndpoint("api.captchasonic.com:443"))
c, _ := captchasonic.NewClient("sonic_xxxx", captchasonic.WithEndpoint("https://api.captchasonic.com"))

// Local dev:
c, _ := captchasonic.NewClient("sonic_xxxx", captchasonic.WithEndpoint("localhost:50052"), captchasonic.WithInsecure())

// HTTP transport
c, _ := captchasonic.NewClient("sonic_xxxx", captchasonic.WithHTTP())

func (*Client) Close

func (c *Client) Close() error

Close releases all transport resources.

func (*Client) CreateTask

func (c *Client) CreateTask(ctx context.Context, task *v1.Task) (*v1.CreateTaskResponse, error)

CreateTask submits a task and polls until ready (if server returns "processing").

func (*Client) GetBalance

func (c *Client) GetBalance(ctx context.Context) (float64, error)

GetBalance returns the account balance in USD.

func (*Client) GetTaskResult

func (c *Client) GetTaskResult(ctx context.Context, taskID string) (*v1.GetTaskResultResponse, error)

GetTaskResult fetches the result of an async task.

func (*Client) HealthCheck

func (c *Client) HealthCheck(ctx context.Context) (*v1.HealthCheckResponse, error)

HealthCheck verifies the server is alive.

func (*Client) SolveAwsWaf

func (c *Client) SolveAwsWaf(ctx context.Context, images [][]byte, question string, opts ...func(*v1.Task)) (*v1.CreateTaskResponse, error)

SolveAwsWaf solves an AWS WAF image challenge. question format: "type:category:target" e.g. "grid:vehicles:cars" Server auto-detects: "grid" → grid select; "toycarcity" → toycarcity; else → others.

Optional opts: WithWebsite(url, key), WithWebsiteURL(url).

func (*Client) SolveBinance

func (c *Client) SolveBinance(ctx context.Context, binanceType, question string, images [][]byte, opts ...func(*v1.Task)) (*v1.CreateTaskResponse, error)

SolveBinance solves a Binance CAPTCHA challenge with type-based routing.

binanceType selects the sub-type (alias expansion built-in):

"grid"   or "binance_grid"  — grid select (question required)
"slide"  or "binance_slide" — slide puzzle

Example:

c.SolveBinance(ctx, "grid", "Select the bicycle", images)
c.SolveBinance(ctx, "slide", "", images)

func (*Client) SolveCloudflare

func (c *Client) SolveCloudflare(ctx context.Context, websiteURL, websiteKey, proxy string) (*v1.CreateTaskResponse, error)

SolveCloudflare solves a Cloudflare challenge via browser automation (polls until ready). Task type: AntiCloudflareTask. Proxy is ALWAYS required.

func (*Client) SolveGeetest

func (c *Client) SolveGeetest(ctx context.Context, geetestType, question string, opts ...func(*v1.Task)) (*v1.CreateTaskResponse, error)

SolveGeetest solves a Geetest challenge.

geetestType selects the sub-type:

"click"    — click matching objects. question = what to find, e.g. "the bear". Pass images via WithImages.
"slide"    — slide pixel offset. Pass puzzle images via WithImages, slice piece via WithExamples.
"nine"     — nine-tile grid. question = what to find. Pass images via WithImages.
"match"    — 3x3 swap puzzle. No images needed.
"winlinze" — 5x5 swap puzzle. No images needed.

Example:

c.SolveGeetest(ctx, "click", "the bear", WithImages(tiles))
c.SolveGeetest(ctx, "slide", "", WithImages(puzzle), WithExamples(slice))
c.SolveGeetest(ctx, "nine",  "the bear", WithImages(tiles))
c.SolveGeetest(ctx, "match", "")

func (*Client) SolveOcr

func (c *Client) SolveOcr(ctx context.Context, images [][]byte, opts ...func(*v1.Task)) (*v1.CreateTaskResponse, error)

SolveOcr solves an image-to-text (OCR) task. Max 50 images.

Optional opts:

  • WithModule("bls") — BLS/Morocco: numeric=true, maxLength=3, needs exactly 9 images.
  • WithNumeric() — digits only.
  • WithCaseSensitive() — preserve letter case.
  • WithLengthRange(3, 8) — min/max text length.

func (*Client) SolvePopularCaptcha

func (c *Client) SolvePopularCaptcha(ctx context.Context, images [][]byte, question, questionType string, opts ...func(*v1.Task)) (*v1.CreateTaskResponse, error)

SolvePopularCaptcha solves a popular CAPTCHA image classification task (PopularCaptcha image classification (grid/bbox)).

Task type: PopularCaptchaImage Billing: grid/objectClassify=ceil(len(images)/9) credits; bbox/objectClick=len(images) credits

questionType accepted values (server may override via text inference):

  • "objectClassify" — grid select. Returns TypedSolution.Grid.Objects ([]bool).
  • "objectClick" — bbox click per image. Returns TypedSolution.Click.
  • "objectDrag" — drag pairs. Returns TypedSolution.Drag.
  • "grid" — same as objectClassify.

Optional opts: WithExamples, WithScreenshot, WithWebsite.

func (*Client) SolvePopularCaptchaToken

func (c *Client) SolvePopularCaptchaToken(ctx context.Context, websiteURL, websiteKey string, opts ...func(*v1.Task)) (*v1.CreateTaskResponse, error)

SolvePopularCaptchaToken solves a popular CAPTCHA browser automation token task (polls until ready). Use WithProxy(...) for PopularTask or WithProxyless() for PopularTaskProxyless.

func (*Client) SolveRecaptchaV2

func (c *Client) SolveRecaptchaV2(ctx context.Context, images [][]byte, question string, opts ...func(*v1.Task)) (*v1.CreateTaskResponse, error)

SolveRecaptchaV2 solves a reCAPTCHA v2 image classification task.

question accepts plain text OR Google class codes:

  • Plain: "traffic lights", "bicycles", "fire hydrant"
  • Codes: "/m/015qff" (traffic light), "/m/0k4j" (car), "/m/07r04" (truck)

Optional opts: WithQuestionType("split_33"), WithWebsite(url, key), WithWebsiteURL(url).

func (*Client) SolveRecaptchaV2Token

func (c *Client) SolveRecaptchaV2Token(ctx context.Context, websiteURL, websiteKey string, opts ...func(*v1.Task)) (*v1.CreateTaskResponse, error)

SolveRecaptchaV2Token solves a reCAPTCHA v2 browser automation token task (polls until ready). Use WithProxy(...) for RecaptchaV2Task or WithProxyless() for RecaptchaV2TaskProxyless.

func (*Client) SolveRecaptchaV3Token

func (c *Client) SolveRecaptchaV3Token(ctx context.Context, websiteURL, websiteKey string, opts ...func(*v1.Task)) (*v1.CreateTaskResponse, error)

SolveRecaptchaV3Token solves a reCAPTCHA v3 browser automation token task (polls until ready). Use WithProxy(...) for RecaptchaV3Task or WithProxyless() for RecaptchaV3TaskProxyless.

func (*Client) SolveSlideImage

func (c *Client) SolveSlideImage(ctx context.Context, images [][]byte) (*v1.CreateTaskResponse, error)

SolveSlideImage solves a slide CAPTCHA using local alpha/contour detection (no AI). Task type: SlideImage. Billed as PopularCaptcha credits. Pass 1–2 images: single image with transparent overlay, or [background, piece]. Returns TypedSolution.GetSlide().GetX() as pixel offset.

func (*Client) SolveTikTok

func (c *Client) SolveTikTok(ctx context.Context, tikTokType, question string, images [][]byte, opts ...func(*v1.Task)) (*v1.CreateTaskResponse, error)

SolveTikTok solves a TikTok CAPTCHA challenge with type-based routing.

tikTokType selects the sub-type (alias expansion built-in):

"click"  or "tiktok_click"  — click matching objects
"whirl"  or "tiktok_whirl"  — rotation puzzle
"slide"  or "tiktok_slide"  — slide puzzle

Example:

c.SolveTikTok(ctx, "whirl", "Rotate to match", images)
c.SolveTikTok(ctx, "click", "Select shape", images, captchasonic.WithExamples(ex))

func (*Client) SolveTurnstile

func (c *Client) SolveTurnstile(ctx context.Context, websiteURL, websiteKey string, opts ...func(*v1.Task)) (*v1.CreateTaskResponse, error)

SolveTurnstile solves a Cloudflare Turnstile token task (polls until ready, up to 120s). Use WithProxy("http://user:pass@host:port") for proxy variant, or WithProxyless() for no-proxy (AntiTurnstileTaskProxyless).

type Option

type Option func(*config)

Option configures the Client.

func WithEndpoint

func WithEndpoint(addr string) Option

WithEndpoint overrides the server address. All formats are accepted:

"api.captchasonic.com"          → gRPC: host:443, HTTP: https://host
"api.captchasonic.com:443"       → gRPC: host:443, HTTP: https://host:443
"https://api.captchasonic.com"   → gRPC: host:443, HTTP: https://host  (scheme stripped for gRPC)
"localhost:50052"                → gRPC: localhost:50052, HTTP: http://localhost:50052
"http://localhost:50052"         → gRPC: localhost:50052, HTTP: http://localhost:50052

func WithGRPC

func WithGRPC() Option

WithGRPC explicitly selects gRPC transport (this is the default).

func WithGRPCMsgSize

func WithGRPCMsgSize(bytes int) Option

WithGRPCMsgSize sets max gRPC message size in bytes (default 50 MB).

func WithHTTP

func WithHTTP() Option

WithHTTP switches to HTTP/JSON transport. Images are automatically base64-encoded before sending.

func WithHTTPPool

func WithHTTPPool(maxConns, maxIdle int, idleTimeout time.Duration) Option

WithHTTPPool configures the HTTP connection pool.

func WithInsecure

func WithInsecure() Option

WithInsecure disables TLS on gRPC (local / internal servers only).

func WithTimeout

func WithTimeout(d time.Duration) Option

WithTimeout sets the per-call timeout (default 30s).

type SonicError

type SonicError struct {
	Message    string
	ErrorID    int32
	RetryAfter int32
}

SonicError is returned for all API-level and transport-level errors.

func (*SonicError) Error

func (e *SonicError) Error() string

Directories

Path Synopsis
internal
pb

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL