Skip to content

Java SDK reference

The Java SDK sends a response token to siteverify and applies every relying-party check: success must be the boolean true, the hostname (or app) and the action must match exactly, and the score must meet your threshold. It also wraps assessments, account protection, leaked-password and credential pair checks, payments and SMS scoring, and erase. It needs Java 11 or later and has no runtime dependencies (it uses java.net.http). For a step-by-step setup see the Java quickstart.

Terminal window
cd sdks/java && mvn install # from a checkout, until the first release
<dependency>
<groupId>com.revokegpt</groupId>
<artifactId>revokegpt</artifactId>
<version>0.1.0</version>
</dependency>

The jar is a named module, com.revokegpt (it exports com.revokegpt and com.revokegpt.model), and works on the class path as well.

RevokeGPT revokegpt = RevokeGPT.builder()
.secret(System.getenv("REVOKEGPT_SECRET"))
.endpoint("https://<api host>/v1/siteverify")
.build();

The client is immutable and thread safe: create it once. A bad value makes build() throw an IllegalArgumentException whose message never shows the value.

Builder method Default Notes
secret(String) required Your site’s secret key (rgsk_...). A management key (rgmk_...) is refused.
endpoint(String) required, no default The full siteverify URL. https:, or http: only on localhost or 127.0.0.1. No userinfo, query or fragment. It must end in /siteverify for the other calls.
timeout(Duration) 5 seconds Whole milliseconds from 1 to 60000. A total deadline for one call. Nothing is retried.
httpClient(HttpClient) SDK-owned client Must be built with followRedirects(HttpClient.Redirect.NEVER); build() refuses one that follows redirects. The SDK never closes it.

Build with VerifyOptions.builder().

Setter Notes
expectedHostname Canonical: lowercase, no trailing dot, no port. Set exactly one of this and expectedApp.
expectedApp ExpectedApp.android(packageName) or ExpectedApp.ios(bundleId), for tokens from the mobile SDKs.
expectedAction Leave it out only if you use no actions; a token that carries an action is then refused.
minScore A number in [0, 1]. Always set it: without one the outcome is threshold-missing.
remoteip Sent only when given and not empty; checked first.
sitekey Sent only when given and not empty; checked first.

A setter you never call means “not given”. A setter called with null means “given, but invalid” and the outcome is invalid-expectation or invalid-options.

Every method has an ...Async twin that returns a CompletableFuture and blocks no thread. An argument error is thrown by the ...Async method itself, before any request, not delivered through the future. Cancelling a future stops its exchange.

public VerifyOutcome verify(String token, VerifyOptions options)
public CompletableFuture<VerifyOutcome> verifyAsync(String token, VerifyOptions options)

Returns a VerifyOutcome. Gate on outcome.ok() alone; reason() says why it is false. outcome.result() has score(), action(), hostname(), errorCodes() and reasons() for logging. It never throws, and verifyAsync’s future always completes normally.

VerifyOutcome outcome = revokegpt.verify(token, VerifyOptions.builder()
.expectedHostname("shop.example")
.expectedAction("signup")
.minScore(0.5)
.build());
if (!outcome.ok()) { /* refuse */ }
public Assessment createAssessment(AssessmentRequest request)
public CompletableFuture<Assessment> createAssessmentAsync(AssessmentRequest request)

Returns an Assessment; raw() holds the whole parsed answer. An invalid token is still a 200 with tokenProperties().valid() == false and score 0, so check valid(). Reason and label enums are open strings.

public void annotate(String nameOrAid, AnnotateInput input)
public CompletableFuture<Void> annotateAsync(String nameOrAid, AnnotateInput input)

Sends ground truth you learn later. An input with nothing in it is sent and the service refuses it (bad-request).

public void eraseAccount(AccountRef account)
public CompletableFuture<Void> eraseAccountAsync(AccountRef account)

Use one form of account id (accountId or hashedAccountId) everywhere you assess, annotate and erase.

public PasswordCheckResult isPasswordLeaked(String password)
public CompletableFuture<PasswordCheckResult> isPasswordLeakedAsync(String password)

Returns leaked() and count(). The password is hashed with SHA-1 here and only the first 5 hex characters are sent. A RevokeGPTError means the password was not checked: never treat it as “not leaked”.

public CredentialPairResult checkCredentialPair(String username, String password)
public CompletableFuture<CredentialPairResult> checkCredentialPairAsync(String username, String password)

Returns leaked(). Neither value leaves your server. While it is off the service answers feature-disabled. A username over 512 UTF-16 code units or holding U+0000, or a username and password over 65535 UTF-8 bytes together, throws IllegalArgumentException.

CardFields.of(String bin, String last4)

Payments take only the card’s BIN (first 6 or 8 digits) and last four digits. It throws RevokeGPTError bad-request with status 0 for anything else. Every string of TransactionData is also scanned for a card number before sending.

verify reports failures as reason(). Treat every reason as “do not accept”.

Reason Meaning
invalid-expectation Bad expectation. Nothing was sent.
invalid-options A given remoteip or sitekey is invalid. Nothing was sent.
invalid-token-format Not 1 to 2048 characters of A-Z a-z 0-9 - _. Nothing was sent.
network-error The request failed or timed out, or the calling thread was interrupted (the flag stays set).
http-error A status other than 200 (redirects included), or a body over 64 KiB.
not-verified Siteverify did not verify the token, or the body was malformed. result().errorCodes() says why.
hostname-mismatch, app-mismatch, action-mismatch The token was issued for something else.
score-missing, threshold-missing, score-invalid, score-below-threshold The score check failed.

A token is single use: after network-error or http-error it may already be spent, so a retry needs a new token.

Other methods throw IllegalArgumentException for a bad argument (before any request) and the unchecked RevokeGPTError for a failed call. The futures of the async twins complete exceptionally with a RevokeGPTError.

Member Meaning
code() unauthorized, feature-disabled, not-found, expired, rate-limited, bad-request, payload-too-large, unsupported-media-type, service-unavailable, network-error, invalid-response. Treat the set as open.
status() The HTTP status; 0 when nothing was answered or no request was made.
requestId() The service’s request id, when sent. Quote it to support.
retryAfterSeconds() Set for a 429 that carried Retry-After.
RevokeGPTUnavailable The subclass for HTTP 503: “could not check”, never “clean”.

See errors for the service error codes.

  • The SDK’s own HttpClient has no proxy (it ignores http.proxyHost and https.proxyHost), follows no redirects, keeps no cookies and has no authenticator. For a proxy, trust store or executor, pass your own client. A CookieHandler, Authenticator or SSLContext on it stays in effect and is yours.
  • Behind a proxy, request.getRemoteAddr() is the proxy unless your server trusts its header. On Spring Boot set server.forward-headers-strategy=native (or framework). An address with a zone id is invalid: leave remoteip out.
  • Hostnames needing full UTS 46 mapping are refused as expectedHostname; pass the punycode form.
  • Pair check usernames follow your JDK’s Unicode data (Normalizer NFKC); one holding a newer character is refused.
  • The secret goes only in the POST body (siteverify) or the Authorization header, never in a URL, exception, log line or toString(). The client and its builder are not Serializable.
  • No retries and no redirects. At most 64 KiB of a JSON answer (4 MiB for a password range) is read, and Accept-Encoding: identity is sent so the cap counts real bytes.
  • Never choose between the hostname and app expectation from anything the client controls.
  • If you call siteverify yourself, never concatenate the token into the body.