Verification
Java server SDK
ai.thirdfactor:thirdfactor-sdk — create verification sessions, select workflows, retrieve decisions, and verify signed webhooks from Java.
The official Java SDK is a server-only client for the ThirdFactor API. Its
Maven coordinates are ai.thirdfactor:thirdfactor-sdk and its package namespace
is ai.thirdfactor.
Warning
Keep your tenant API key on the server. Never put it in browser code, a mobile application, an Android APK, or a public repository.
Requirements
- Java 11 or newer
- Maven or Gradle
- A tenant API key from Console → Settings → API keys
Installation
Create a session and select a workflow
import ai.thirdfactor.ThirdFactorClient;
import java.time.Duration;
import java.net.http.HttpClient;
import java.util.Map;
ThirdFactorClient thirdFactor = new ThirdFactorClient(
System.getenv("THIRDFACTOR_API_KEY"),
"https://your-tenant.thirdfactor.ai",
Duration.ofSeconds(15),
HttpClient.newHttpClient()
);
Map<String, Object> session = thirdFactor.createSession(Map.of(
"vendor_data", "user-42",
"workflow_id", "4c615aec-e173-450d-8089-30d4edc835f3",
"callback_url", "https://app.example.com/kyc/done",
"contact_email", "[email protected]",
"metadata", Map.of("source", "java-sdk")
), "kyc-user-42");
String sessionId = (String) session.get("id");
String hostedUrl = (String) session.get("url");Pass the desired Console workflow UUID as workflow_id. Omit it to use the
tenant's default workflow. Persist the session ID and send only the hosted URL
to the applicant. Use a stable idempotency key for each logical attempt so a
retry returns the original session.
Retrieve a session or decision
Map<String, Object> current = thirdFactor.retrieveSession(sessionId);
Map<String, Object> decision = thirdFactor.sessionDecision(sessionId);
if ("approved".equals(decision.get("decision"))) {
grantAccess();
}The hosted UI result is advisory. Grant access, move money, or provision an account only after a signed webhook or this authenticated decision lookup.
Verify webhooks
Pass the untouched HTTP request bytes and the X-Webhook-Signature header
before parsing JSON:
import ai.thirdfactor.Webhooks;
Map<String, Object> event = Webhooks.constructEvent(
rawRequestBody,
signatureHeader,
System.getenv("THIRDFACTOR_WEBHOOK_SECRET"),
300
);The verifier uses constant-time HMAC comparison and the example permits a
five-minute replay window. constructEvent throws IllegalArgumentException
when the signature is invalid, stale, or the body is not valid JSON.
Handle API errors
import ai.thirdfactor.ThirdFactorException;
try {
Map<String, Object> decision = thirdFactor.sessionDecision(sessionId);
} catch (ThirdFactorException error) {
System.err.println(error.getStatus());
System.err.println(error.getBody());
System.err.println(error.getRequestId());
}