Tips

Best practices: speed, stability, low costs

2026-01-24

Integrating an API is easy, but making it robust and cost-effective requires attention to detail. Here are our top tips.

1. Implement Retries

Network issues or temporary server errors (5xx) can occur. Always implement a retry mechanism with exponential backoff.

  • Retry on 500, 502, 503, 504.
  • Wait 1s, 2s, 4s between retries.

C# Example with Polly

// Install-Package Polly

using Polly;
using Polly.Retry;

var retryPolicy = Policy
    .Handle<HttpRequestException>()
    .OrResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode)
    .WaitAndRetryAsync(
        retryCount: 3,
        sleepDurationProvider: attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt)),
        onRetry: (outcome, timespan, attempt, context) =>
        {
            Console.WriteLine($"Retry {attempt} after {timespan}");
        }
    );

var response = await retryPolicy.ExecuteAsync(async () =>
{
    using var client = new HttpClient();
    client.DefaultRequestHeaders.Add("X-API-Key", "YOUR_API_KEY");
    return await client.PostAsync(
        "http://api.noncaptcha.com/api/json/text",
        new MultipartFormDataContent()
    );
});

2. Handle Balance Errors

If you receive a 402 (Insufficient Balance) error, pause your requests immediately. Do not retry endlessly, as this will not solve the captcha.

Error Handling Example

try
{
    var response = await client.PostAsync(url, content);
    
    if (response.StatusCode == HttpStatusCode.PaymentRequired)
    {
        Console.WriteLine("⚠️ Insufficient balance! Pausing requests...");
        await Task.Delay(TimeSpan.FromMinutes(5)); // Wait and check balance
        return;
    }
    
    response.EnsureSuccessStatusCode();
    var result = await response.Content.ReadAsStringAsync();
}
catch (HttpRequestException ex)
{
    Console.WriteLine($"Request failed: {ex.Message}");
    // Log and handle appropriately
}

3. Parallelism

Our API is designed to handle concurrent requests. If you need to solve multiple captchas, run requests in parallel rather than sequentially.

Parallel Requests Example

// Solve multiple captchas concurrently
var captchaFiles = new[] { "cap1.png", "cap2.png", "cap3.png" };

var tasks = captchaFiles.Select(async file =>
{
    using var stream = File.OpenRead(file);
    var content = new MultipartFormDataContent();
    content.Add(new StreamContent(stream), "image", file);
    
    var response = await client.PostAsync(
        "http://api.noncaptcha.com/api/json/text", 
        content
    );
    
    return await response.Content.ReadAsStringAsync();
});

var results = await Task.WhenAll(tasks);

// Process all results
foreach (var result in results)
{
    Console.WriteLine($"Result: {result}");
}

Timeout Configuration

// Configure HttpClient with timeout
var client = new HttpClient
{
    Timeout = TimeSpan.FromSeconds(60) // 60 seconds timeout
};

// Or use CancellationToken for more control
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(45));
try
{
    var response = await client.PostAsync(url, content, cts.Token);
    // Process response
}
catch (OperationCanceledException)
{
    Console.WriteLine("Request timed out!");
}