Go SDK reference
The Go 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 checks, payments and SMS scoring, and erase. It needs Go 1.26 or later
and the core module uses the standard library only. For a step-by-step setup see the Go quickstart.
Install
Section titled “Install”go mod edit -require github.com/revokegpt/revokegpt-go@v0.0.0go mod edit -replace github.com/revokegpt/revokegpt-go=/path/to/checkout/sdks/go # until the first releasego get github.com/revokegpt/revokegpt-go # after the first releaseThe credential pair check is a second module (github.com/revokegpt/revokegpt-go/pair). The firewall middleware is a
third, released separately.
Options
Section titled “Options”func New(secretKey, endpoint string, opts ...Option) (*Client, error)Create the client once; it is safe for concurrent use. A bad argument returns an *InputError.
| Name | Default | Notes |
|---|---|---|
secretKey |
required | Your site’s secret key (rgsk_...). A management key (rgmk_...) is refused. |
endpoint |
required, no default | The full siteverify URL. https:, or http: only on localhost or 127.0.0.1. No username, password, query or fragment. It must end in /siteverify for the assessment and password calls. |
WithTimeout(d) |
5 s | A whole number of milliseconds from 1 ms to 60 s. A total deadline for one call, together with the context you pass. Nothing is retried. |
WithHTTPClient(hc) |
SDK-owned client | Your own *http.Client. The SDK sends through a copy that never follows redirects and has no cookie jar. |
VerifyOptions
Section titled “VerifyOptions”| Field | Notes |
|---|---|
ExpectedHostname |
Canonical: lowercase, no trailing dot, no port. Give exactly one of this and ExpectedApp. |
ExpectedApp |
&ExpectedApp{Platform: "android" or "ios", ID: ...}, for tokens from the mobile SDKs. |
ExpectedAction |
*string. Leave it nil only if you use no actions; a token that carries an action is then refused. |
MinScore |
*float64 in [0, 1]. Always set it: without one the outcome is threshold-missing. |
RemoteIP |
Sent only when not empty; checked first. |
SiteKey |
Sent only when not empty; checked first. |
Go has no null: an absent option is the zero value or a nil pointer.
Methods
Section titled “Methods”Verify
Section titled “Verify”func (c *Client) Verify(ctx context.Context, tok string, o VerifyOptions) VerifyOutcomeReturns VerifyOutcome{OK bool, Reason string, Result SiteverifyResult}. Gate on OK alone. Result carries Score,
Action, Hostname, ErrorCodes, Reasons, APKPackageName and IOSBundleID for logging. It never returns an error
and never panics.
action, min := "signup", 0.5out := client.Verify(r.Context(), token, revokegpt.VerifyOptions{ ExpectedHostname: "shop.example", ExpectedAction: &action, MinScore: &min,})if !out.OK { /* refuse; out.Reason says why */ }CreateAssessment
Section titled “CreateAssessment”func (c *Client) CreateAssessment(ctx context.Context, in AssessmentInput) (*Assessment, error)Returns an *Assessment; Raw holds the whole body. An invalid token is still a 200 with TokenProperties.Valid == false
and score 0, so check Valid. Reason and label lists are open strings.
a, err := client.CreateAssessment(ctx, revokegpt.AssessmentInput{Token: token, ExpectedAction: "login"})if err == nil && a.TokenProperties.Valid && a.RiskAnalysis.Score >= 0.5 { /* accept */ }Annotate
Section titled “Annotate”func (c *Client) Annotate(ctx context.Context, nameOrAID string, in AnnotateInput) errorSends ground truth you learn later (a chargeback, a confirmed fraud, a legitimate purchase). An empty input is sent and the service refuses it.
EraseAccount
Section titled “EraseAccount”func (c *Client) EraseAccount(ctx context.Context, ref AccountRef) errorUse one form of account id (AccountID or HashedAccountID) everywhere you assess, annotate and erase.
IsPasswordLeaked
Section titled “IsPasswordLeaked”func (c *Client) IsPasswordLeaked(ctx context.Context, password string) (PasswordCheckResult, error)Returns PasswordCheckResult{Leaked, Count}. The password is hashed with SHA-1 locally and only the first 5 hex characters
are sent; the match is done here. A non-nil error means the password was not checked: never treat it as “not leaked”.
CheckCredentialPair (beta)
Section titled “CheckCredentialPair (beta)”func (c *Client) CheckCredentialPair(ctx context.Context, b PairBlinder, username, password string) (CredentialPairResult, error)Pass pair.New() from the pair module. Neither value leaves your server. With a nil blinder the call returns an *Error
with code feature-unavailable and sends nothing. While it is off the service answers feature-disabled.
CardFields and ContainsPANRun
Section titled “CardFields and ContainsPANRun”func CardFields(bin, last4 string) (Card, error)func ContainsPANRun(s string) boolPayments take only the card’s BIN (first 6 or 8 digits) and last four digits. CardFields returns an *Error with code
bad-request and status 0 for anything else. Every string of TransactionData is also scanned for a card number before
sending.
Errors and failure model
Section titled “Errors and failure model”Verify reports failures as a 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, timed out, or the context ended. |
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.
Every other method returns an error. A bad argument is an *InputError before any request
(errors.Is(err, revokegpt.ErrInvalidInput)). A failed call is an *Error:
| Field | Meaning |
|---|---|
Code |
unauthorized, feature-disabled, not-found, expired, rate-limited, bad-request, payload-too-large, unsupported-media-type, service-unavailable, network-error, invalid-response, feature-unavailable. 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 |
*int, set for an answer that carried Retry-After. |
IsUnavailable(err) is true for HTTP 503: “could not check”, never “clean”. A call ended by your context or the timeout is
code network-error and errors.Is(err, context.Canceled) or context.DeadlineExceeded matches it. See
errors for the service error codes.
Configuration
Section titled “Configuration”- The SDK’s own client ignores
HTTP_PROXYand the other proxy variables. For a proxy or custom CA, pass your own*http.ClientwithWithHTTPClient. A client with a nilTransportuseshttp.DefaultTransport, which does read the proxy variables. - Behind a proxy, take
RemoteIPfrom the header your own proxy appended, not fromr.RemoteAddr. An address with a zone id is invalid: leaveRemoteIPempty then. - Optional response fields (
Scoreand the strings ofSiteverifyResult) are pointers, nil when absent. - Hostnames needing full UTS 46 mapping are refused as
ExpectedHostname; pass the punycode form.
Security notes
Section titled “Security notes”- The secret goes only in the POST body (siteverify) or the
Authorizationheader, never in a URL, error, log line or printed form. TheClient’sfmt,log/slogandencoding/jsonforms are a fixed placeholder. - No retries and no redirects. At most 64 KiB of a JSON answer (4 MiB for a password range) is read.
- 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.