Skip to content

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.

Terminal window
go mod edit -require github.com/revokegpt/revokegpt-go@v0.0.0
go mod edit -replace github.com/revokegpt/revokegpt-go=/path/to/checkout/sdks/go # until the first release
go get github.com/revokegpt/revokegpt-go # after the first release

The credential pair check is a second module (github.com/revokegpt/revokegpt-go/pair). The firewall middleware is a third, released separately.

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.
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.

func (c *Client) Verify(ctx context.Context, tok string, o VerifyOptions) VerifyOutcome

Returns 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.5
out := client.Verify(r.Context(), token, revokegpt.VerifyOptions{
ExpectedHostname: "shop.example",
ExpectedAction: &action,
MinScore: &min,
})
if !out.OK { /* refuse; out.Reason says why */ }
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 */ }
func (c *Client) Annotate(ctx context.Context, nameOrAID string, in AnnotateInput) error

Sends ground truth you learn later (a chargeback, a confirmed fraud, a legitimate purchase). An empty input is sent and the service refuses it.

func (c *Client) EraseAccount(ctx context.Context, ref AccountRef) error

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

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”.

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.

func CardFields(bin, last4 string) (Card, error)
func ContainsPANRun(s string) bool

Payments 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.

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.

  • The SDK’s own client ignores HTTP_PROXY and the other proxy variables. For a proxy or custom CA, pass your own *http.Client with WithHTTPClient. A client with a nil Transport uses http.DefaultTransport, which does read the proxy variables.
  • Behind a proxy, take RemoteIP from the header your own proxy appended, not from r.RemoteAddr. An address with a zone id is invalid: leave RemoteIP empty then.
  • Optional response fields (Score and the strings of SiteverifyResult) are pointers, nil when absent.
  • Hostnames needing full UTS 46 mapping are refused as ExpectedHostname; pass the punycode form.
  • The secret goes only in the POST body (siteverify) or the Authorization header, never in a URL, error, log line or printed form. The Client’s fmt, log/slog and encoding/json forms 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.