SDKs / Swift
Swift SDK
Package CaptchaOcr, version 1.0.0. Requires Swift 6 toolchain; iOS 13+, macOS 10.15+, tvOS 13+, watchOS 6+; async/await.
Install
The SDK installs straight from our package server, captchaocr.allvoraz.com/sdk, with your usual tools. No public registry account is needed.
// Package.swift
dependencies: [
.package(url: "https://captchaocr.allvoraz.com/sdk/git/captcha-ocr-swift.git", from: "1.0.0"),
],
targets: [
.target(name: "YourApp", dependencies: [
.product(name: "CaptchaOcr", package: "captcha-ocr-swift"),
]),
]
// Xcode: File > Add Package Dependencies... > paste
// https://captchaocr.allvoraz.com/sdk/git/captcha-ocr-swift.gitPrefer the code itself? Download the source (.zip).
Configure and solve
Create the client once with your API key (from Dashboard → API keys) and reuse it. Submit the answer only when reliable is true. Only reliable answers are charged.
import CaptchaOcr
import Foundation
let config = CaptchaOcrAPIConfiguration.shared
config.basePath = "https://captchaocr.allvoraz.com"
config.customHeaders["Authorization"] = "Bearer \(ProcessInfo.processInfo.environment["CAPTCHA_API_KEY"] ?? "")"
let image = try Data(contentsOf: URL(fileURLWithPath: "captcha.png")).base64EncodedString()
// Swift labels follow declaration order: options first, image last.
let res = try await SolveAPI.solve(solveRequest: SolveRequest(numeric: true, length: 6, image: image))
if res.reliable == true { print(res.text ?? "") } // only reliable answers are chargedOptions: numeric, uppercase, lowercase, length, math, hindi. See choosing options.
Batch
Up to 256 images in one call. Top-level options are shared, and each item can override them. Results keep the request order.
let batch = try await SolveAPI.solveBatch(batchRequest: BatchRequest(
numeric: true, // shared by every image
images: [
BatchItem(image: try b64("a.png")),
BatchItem(image: try b64("b.png"), length: 5), // per-image override
BatchItem(image: try b64("sum.png"), math: true),
]
))
for r in batch.results { // same order as the request
print(r.reliable == true ? r.text ?? "" : "refresh")
}Submit now, fetch later
submit returns a task id immediately and solves in the background. getResult returns processing, then ready with the same answer solve returns (or failed, credit returned). Pass wait (up to 30 s) to hold the call until it's ready.
// Submit: returns a task id at once, the captcha is solved in the background.
let task = try await SolveAPI.submit(solveRequest: SolveRequest(numeric: true, length: 6, image: image))
// ... do other work ...
let r = try await SolveAPI.getResult(taskId: task.id, wait: 10) // waits up to 10 s
if r.status == .ready, r.result?.reliable == true { print(r.result?.text ?? "") }Or poll without holding the connection:
// Poll without holding the connection.
var r = try await SolveAPI.getResult(taskId: task.id)
while r.status == .processing {
try await Task.sleep(for: .milliseconds(500))
r = try await SolveAPI.getResult(taskId: task.id)
}Balance
let credits = try await AccountAPI.balance().creditsLow-balance alert
One alert per account: when a solve leaves your credits below threshold, the service POSTs your payload to your HTTPS url. It fires once and re-arms when you add credits. testAlert sends it now; getAlert and deleteAlert read and remove it. See how alerts work.
print(try await AccountAPI.balance().credits)
// When credits drop below 500, POST this payload to your URL (one alert per account).
_ = try await AccountAPI.setAlert(alertRequest: AlertRequest(
threshold: 500,
url: "https://hooks.example.org/captcha-credits",
payload: ["text": .string("Captcha credits low: {{credits}} left")],
headers: ["Authorization": "Bearer my-hook-secret"]))
let test = try await AccountAPI.testAlert() // sends it now
print(test.delivered, test.status ?? 0)
// try await AccountAPI.deleteAlert() // remove itReport a wrong answer
If the site rejected a reliable answer, report its id within 48 hours to get the credit back.
// The site rejected res.text: get the credit back (within 48 hours).
let r = try await AccountAPI.report(reportRequest: ReportRequest(id: res.id!))Errors
HTTP errors (401 bad key, 402 no credits, 404 unknown task, 422 invalid options, 429 too many concurrent requests, 503 retry later) raise ErrorResponse.error(statusCode, data, response, error). An undecodable image is not an exception: it's a normal result with error: "invalid_image". See errors.
More
- Source code and full reference (every class and model)
- API guide · API reference