How do you integrate hCaptcha with an iOS app?#
Add the official HCaptcha SDK to the iOS project, initialize it with a public sitekey and application domain, and call validate(on:) from the protected action. Send the returned token to your backend. The backend must verify it with hCaptcha Siteverify before it accepts the login, signup, payment, or other request.
The SDK documentation and podspec require iOS 12 or later. Swift Package Manager is the preferred installation path because the project has deprecated CocoaPods support.
Reduce verification interruptions in your iOS app#
- Let users concentrate on their next action. hCaptcha Pro's 99.9% Passive mode reduces visual challenges during protected login, signup, and other app flows.
- Adjust verification to the interaction. Pro applies stronger checks when risk rises, balancing a less disruptive app experience with adaptive protection. The SDK must still be able to present an occasional challenge.
New Pro sitekeys use 99.9% Passive by default. For an existing sitekey upgraded to Pro, select that mode under Behavior in the hCaptcha dashboard.
Before you start#
These instructions were last validated on September 22, 2026 with iOS SDK 3.1.0.
You need:
- An iOS application with a backend endpoint for its protected action.
- A supported Xcode and Swift toolchain for SDK 3.1.0.
- An hCaptcha account with a sitekey and its matching secret.
- A secure backend secret store and outbound HTTPS access to hCaptcha.
Review the official iOS SDK repository and the hCaptcha mobile SDK and integration catalog entries. The integrations-list repository records the broader catalog.
Use iOS 12 or later, which is the minimum version supported by the SDK documentation and release artifacts.
Create your hCaptcha credentials#
- Start with hCaptcha Pro for fewer challenges and adaptive protection on protected iOS app actions, or use existing compatible hCaptcha credentials.
- Create a sitekey for the iOS application.
- Choose the domain used to initialize the SDK and keep it consistent across environments.
- Put the public sitekey and domain in the app configuration or SDK initializer.
- Store the matching secret only in protected backend configuration.
The sitekey is public. Never put the secret in Info.plist, Swift code, an application bundle, or a mobile configuration file.
Add the SDK with Swift Package Manager#
In Xcode, select File → Add Package Dependencies, enter the official repository URL, and select the reviewed 3.1.0 release:
https://github.com/hCaptcha/HCaptcha-ios-sdk
Add the HCaptcha product to the application target and import it where the protected flow starts:
import HCaptcha
The repository also documents Carthage. CocoaPods remains available in 3.1.0 but is deprecated and scheduled for removal, so avoid starting a new CocoaPods integration.
Configure and validate with UIKit#
Pass the sitekey and domain directly to the initializer, then configure the SDK's WebView and request a token:
import HCaptcha
import UIKit
import WebKit
final class SignupViewController: UIViewController {
private var captchaWebView: WKWebView?
private lazy var hcaptcha = try? HCaptcha(
apiKey: "YOUR_SITEKEY",
baseURL: URL(string: "https://app.example.com")!
)
override func viewDidLoad() {
super.viewDidLoad()
hcaptcha?.configureWebView { [weak self] webView in
self?.captchaWebView = webView
webView.frame = self?.view.bounds ?? .zero
}
}
func submitSignup() {
hcaptcha?.validate(on: view) { [weak self] result in
defer { self?.captchaWebView?.removeFromSuperview() }
do {
let token = try result.dematerialize()
self?.sendSignupToBackend(hcaptchaToken: token)
} catch {
self?.showCaptchaError(error)
}
}
}
}
The caller is responsible for removing the WebView after challenge processing. dematerialize() consumes the result and returns the token or throws an SDK error. The example's sendSignupToBackend and showCaptchaError methods represent application code you must implement.
For SwiftUI, follow the repository's SwiftUI example and use UIViewRepresentable to provide a UIKit host view for the SDK's WKWebView. Review navigation, view recreation, and cancellation behavior in the actual app.
Verify the token on your backend#
The backend endpoint that receives the mobile request must:
- Reject a missing token before performing the protected action.
- Send a URL-encoded
POSTtohttps://api.hcaptcha.com/siteverify. - Include the server-held
secretand the iOS token asresponse. - Include the expected
sitekeyso a token issued for another sitekey cannot satisfy this endpoint. Theremoteipparameter is optional. We recommend sending it for improved verification accuracy and Enterprise risk scores when the backend derives the visitor's IP address from a reviewed, trusted proxy configuration; otherwise omit it. - Parse the JSON response and continue only when
successistrue. - Stop the protected action when verification fails.
Follow the current server-side verification documentation. The SDK returns a token; it does not make the authorization decision for your backend.
Test the complete iOS flow#
- Verify valid and invalid requests against the backend.
- Confirm a token succeeds once and fails when reused.
- Test expiration, cancellation, offline mode, slow networks, and app backgrounding.
- Test UIKit or SwiftUI navigation and confirm the challenge WebView is removed.
- Test each supported iOS and Xcode version on physical devices.
- If camera-based liveness is enabled, add
NSCameraUsageDescriptionand test on iOS 15 or later. - Check portrait and landscape layouts, accessibility settings, and every configured domain.
Troubleshoot common iOS problems#
Xcode cannot load the package or build the SDK
Pin release 3.1.0, confirm the application deployment target is iOS 12 or later, and validate the application's Xcode, Swift, and package-manager configuration before shipping.
The SDK reports “Could not load embedded HTML”
Confirm that the SDK resources are included in the application target. Compare the target configuration with the official example project.
The challenge remains visible after completion
Keep a reference to the SDK WebView and remove it after the validation callback finishes. The caller owns this cleanup.
The challenge appears but does not accept input
Confirm the application has not disabled interaction events and that no transparent view covers the challenge. Use Xcode's view debugger to inspect the hierarchy.
The app closes when a camera challenge starts
Add a clear NSCameraUsageDescription entry before enabling camera-based liveness. The SDK documentation requires iOS 15 or later for that flow.
Frequently asked questions#
Is the hCaptcha iOS SDK official?
Yes. hCaptcha maintains hCaptcha/HCaptcha-ios-sdk and links it from the mobile SDK and integration catalogs.
Does the SDK support SwiftUI?
Yes, through a documented example that wraps the UIKit-oriented SDK with UIViewRepresentable. Test SwiftUI view recreation and navigation in your application.
What is the minimum supported iOS version?
Use iOS 12 or later, which is the minimum version supported by the SDK documentation and release artifacts.
Does the SDK verify the token itself?
No. Your backend must send every returned token and the private secret to Siteverify before accepting the protected request.
Can the hCaptcha secret be stored in the iOS app?
No. Values inside an application bundle can be recovered. Keep the secret on the backend and expose only the sitekey to the app.
Sources and references
- hCaptcha Pro product overview hCaptcha
- hCaptcha iOS SDK source and documentation hCaptcha
- hCaptcha mobile app SDKs hCaptcha
- hCaptcha integrations hCaptcha
- Verify the user response server-side hCaptcha
- hCaptcha integrations list source hCaptcha
- hCaptcha Pro hCaptcha