Official C# / .NET SDK for the CaptchaSonic CAPTCHA solving API.
Uses native gRPC via Grpc.Net.Client. Images are sent as raw binary, with no base64 overhead.
dotnet add package CaptchaSonicusing CaptchaSonic;
await using var client = new CaptchaSonicClient(new CaptchaSonicOptions
{
ApiKey = "sonic_your_api_key"
});
double balance = await client.GetBalanceAsync();
Console.WriteLine($"Balance: ${balance:F4}");
byte[] tile = await File.ReadAllBytesAsync("tile.png");
var result = await client.SolvePopularCaptchaAsync(
images: new[] { tile },
question: "Select all traffic lights",
questionType: "objectClassify"
);
Console.WriteLine(string.Join(", ", result.TypedSolution.Grid.Objects));await using var client = new CaptchaSonicClient("sonic_your_api_key");var client = new CaptchaSonicClient(new CaptchaSonicOptions
{
ApiKey = "sonic_your_api_key", // required, must start with "sonic_"
Endpoint = "https://api.captchasonic.com", // optional, default shown
CallTimeout = TimeSpan.FromSeconds(30), // optional, per-call gRPC deadline
});The client is thread-safe — create one instance and reuse it throughout your application.
await client.SolvePopularCaptchaAsync(
images: new[] { tile },
question: "Select all traffic lights",
questionType: "objectClassify", // "objectClassify" | "objectClick" | "objectDrag" | "grid"
examples: null, // optional reference images
screenshot: false, // optional
websiteUrl: "https://example.com", // optional, billing context
websiteKey: null // optional, billing context
);await client.SolveRecaptchaV2Async(
images: new[] { tile },
question: "traffic lights", // or "/m/015qff"
questionType: "split_33", // "split_33" | "33" | "44". Optional.
websiteUrl: null, // optional
websiteKey: null // optional
);await client.SolveGeetestAsync(
geetestType: "nine", // "nine" | "click" | "slide" | "match" | "winlinze"
question: "the bear", // required for "nine" and "click"
images: new[] { tile }, // required for "nine", "click", "slide"
examples: null, // optional reference images
image: null, // slice piece for "slide"
gtv: 3, // Geetest version, default 3
websiteUrl: null // optional
);await client.SolveOcrAsync(
images: new[] { tile },
module: "common", // "common" | "mtcaptcha" | "bls" | "morocco"
websiteUrl: null // optional
);
// Returns: result.TypedSolution.Text.Texts[0]await client.SolveTikTokAsync(
type: "whirl", // "click" | "whirl" | "slide"
question: "", // optional
images: new[] { tile },
examples: null, // required for "whirl" and "slide"
websiteUrl: null // optional
);await client.SolveBinanceAsync(
type: "grid", // "grid" | "slide"
question: "Select the bicycle", // required for "grid"
images: new[] { tile },
examples: null, // optional
websiteUrl: null // optional
);await client.SolveAwsWafAsync(
images: new[] { tile },
question: "grid:vehicles:cars",
websiteUrl: null, // optional
websiteKey: null // optional
);await client.SolveSlideImageAsync(images: new[] { background, piece });
// Returns: result.TypedSolution.Slide.X — pixel offsetThese submit a task and poll until a token is returned (up to 120s).
await client.SolveTurnstileAsync(websiteUrl, websiteKey, proxy?);
await client.SolvePopularCaptchaTokenAsync(websiteUrl, websiteKey, proxy?);
await client.SolveRecaptchaV2TokenAsync(websiteUrl, websiteKey, proxy?);
await client.SolveRecaptchaV3TokenAsync(websiteUrl, websiteKey, proxy?);
await client.SolveCloudflareAsync(websiteUrl, websiteKey, proxy); // proxy requireddouble balance = await client.GetBalanceAsync();
var health = await client.HealthCheckAsync();
var result = await client.GetTaskResultAsync(taskId);
var response = await client.CreateTaskAsync(task);try
{
var result = await client.SolvePopularCaptchaAsync(images, question, questionType);
}
catch (InvalidApiKeyException) { /* errorId=1 */ }
catch (InsufficientBalanceException) { /* errorId=2 */ }
catch (DailyLimitExceededException) { /* errorId=3 */ }
catch (MinuteLimitExceededException) { /* errorId=4 */ }
catch (QuotaExceededException) { /* errorId=5 */ }
catch (PlanExpiredException) { /* errorId=6 */ }
catch (CaptchaSonicException) { /* other errors */ }Retries automatically on Unavailable, ResourceExhausted, DeadlineExceeded with exponential backoff.
# 1. Pack
dotnet pack -c Release
# 2. Push
dotnet nuget push bin/Release/CaptchaSonic.1.0.0.nupkg \
--api-key YOUR_NUGET_API_KEY \
--source https://api.nuget.org/v3/index.json