Skip to main content

Server libraries

An Upollo server library can be used identify users before they login, or if they visit from multiple devices.

The library runs on your server, and can be paired with a client library for web and mobile to protect logins and payments.


Upollo's server libraries are available for the following environments and languages:

  • Go: Available via go get
  • NodeJS: Available on NPM via npm install --save @upollo/node
  • Python: Available via pip install upollo-python

Get your API Keys

Sign up at to get your Private API key.


The Upollo server API is outlined below. The details of the request and response protocol buffers are documented in upollo/userwatch-shepherd.

// To use:
// import upollo ""
// client, err := upollo.NewClientBuilder(PRIVATE_API_KEY).Build()

package upollo

// An instance of ShepherdClient is used to access Upollo functionality.
// It is recommended to create and reuse a single instance. You will not
// typically need to specify any options.
func NewClientBuilder(publicApiKey string) *ClientOptions {}
func (*ClientOptions) Build() (ShepherdClient, error)

type ShepherdClient interface {

// Inform Upollo of an event in your application.
// Include any UserInfo you have in the TrackEventRequest, or an empty
// UserInfo if you have none.
ctx context.Context,
in *upollo.TrackEventRequest,
) *upollo.AnalysisResponse

// Access the assessment of a user for whom an event was previously
// registered with Upollo via a track(EventType, UserInfo) call from
// your client application.
// At this point you can also attach any additional UserInfo your server
// has which your client might not have had available.
ctx context.Context,
in *upollo.VerifyRequest,
) *upollo.AnalysisResponse

// You can challenge the user for more identifying information. You can
// use either a phone SMS code, a WebAuthn login (like a fingerprint reader)
// or one you have built yourself which you verify.
ctx context.Context,
in *upollo.CreateChallengeRequest,
) *upollo.CreateChallengeResponse

// You can verify the result of the challenge by passing a challenge verification
// request.
ctx context.Context,
in *upollo.ChallengeVerificationRequest
) (*upollo.ChallengeVerificationResponse, error)



This example shows how to offer the first month of your product free to a genuine new user, but a lesser discount and alternative messaging to someone who is signing up with their second or third email address in an attempt to get a second or third free month. A similar approach can be taken for various other ways you might tailor your offering.

The process here involves getting an Upollo token on your client, and then verifying it on your server. Once the token is on your server, we check its validity and take a look at the analysis of the user. If the MULTIPLE_ACCOUNTS flag is not present we can confidently offer them their first month free, whereas if the user is multi accounting we will try and get them into the habit of paying, even if only a small amount to begin with. The snippet below assumes that the token has been sent to the server in the request.

func SelectOffer(
ctx context.Context,
client userwatchgo.ShepherdClient,
token String,
uid String,
email String
) String {
userInfo := &userwatchgo.UserInfo{
UserID: uid,
UserEmail: email,
analysis, err := client.Verify(ctx, &userwatchgo.VerifyRequest{
EventToken: token,
Userinfo: userInfo,

if err != nil {
if s, ok := status.FromError(err); ok && s.Code() == codes.InvalidArgument {
// If the token was invalid, this could be a malicious request.
return "multi_discount"
// Other errors suggest a system issue. Give benefit of the doubt.
return "free_month"

// Ensure the token was not maliciously swapped out for one from another event.
if analysis.GetEventType() != userwatchgo.EventType_REGISTER {
return "multi_discount"

for _, flag := range result.GetFlag() {
if flag.GetType() == userwatchgo.FlagType_MULTIPLE_ACCOUNTS {
return "multi_discount"
return "free_month"
Upollo logoUpollo

Upollo empowers teams to learn more about their users so they can expand, retain, convert and upsell effectively.

Get Started for Free
About Us
  • About
  • Pricing
  • Blog
  • Contact

© 2024

Proudly built in Sydney, Australia 🦘