> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fingerprint.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Go Server SDK

> The [Fingerprint Server Go SDK](https://github.com/fingerprintjs/go-sdk) is an easy way to interact with our Server API from your Go application. You can retrieve visitor history or individual identification events. View our [Go Server SDK quickstart](/docs/go-server-quickstart) for a step-by-step guide to get started.

## How to install

Get the package from GitHub using `go get`.

```bash Bash theme={"theme":"github-dark-dimmed"}
go get github.com/fingerprintjs/go-sdk/v8
```

Initialize the client instance and use it to make API requests. You need to specify your secret API key and region (if it is not US/Global).

```go Go theme={"theme":"github-dark-dimmed"}
package main

import (
  "context"
  "fmt"
  "log"

  "github.com/fingerprintjs/go-sdk/v8"
)

func main() {
  client := fingerprint.New(
    fingerprint.WithAPIKey("SECRET_API_KEY"),
    // fingerprint.WithRegion(fingerprint.RegionEU),
  )

  // Search events, for example, by Visitor ID
  searchEventsOpts := fingerprint.NewSearchEventsRequest().
    VisitorID("VISITOR_ID").
    Limit(10)

  searchEventsResult, searchEventsHttpRes, searchErr :=
    client.SearchEvents(context.Background(), searchEventsOpts)
  if searchErr != nil {
    if errResp, ok := fingerprint.AsErrorResponse(searchErr); ok {
      log.Printf("Error %s: %v", errResp.Error.Code, errResp)
    }
    log.Fatal(searchErr)
  }
  fmt.Printf("Search events result: %v", searchEventsResult)
  fmt.Printf("Search events response: %v", searchEventsHttpRes)

  // Get a specific identification event
  event, eventHttpRes, eventErr :=
    client.GetEvent(context.Background(), "EVENT_ID")
  if eventErr != nil {
    if errResp, ok := fingerprint.AsErrorResponse(eventErr); ok {
      switch errResp.Error.Code {
      case fingerprint.ErrorCodeEventNotFound:
        log.Fatalf("Event not found")
      default:
        log.Printf("Error %s: %v", errResp.Error.Code, errResp)
      }
    }
    log.Fatal(eventErr)
  }
  fmt.Printf("Event: %v", event)
  fmt.Printf("Event response: %v", eventHttpRes)
}
```

## Migration guide for Go SDK v8

Version 8 migrates the SDK from Server API v3 to v4. This is a breaking change.

This section summarizes the most important changes from previous versions.

### Module rename

The module path changed from `github.com/fingerprintjs/fingerprint-pro-server-api-go-sdk/v7` to `github.com/fingerprintjs/go-sdk/v8`.

```bash Bash theme={"theme":"github-dark-dimmed"}
go get github.com/fingerprintjs/fingerprint-pro-server-api-go-sdk/v7 # [!code --]
go get github.com/fingerprintjs/go-sdk/v8 # [!code ++]
```

```go Go theme={"theme":"github-dark-dimmed"}
import "github.com/fingerprintjs/fingerprint-pro-server-api-go-sdk/v7/sdk" // [!code --]
import "github.com/fingerprintjs/go-sdk/v8" // [!code ++]
```

<Info>
  The v7 and v8
  modules can be
  used side-by-side
  if you would like
  to migrate your
  codebase to the
  new version in
  stages.
</Info>

### Client construction

In v7, you created a context to pass your API key.
In v8, you pass the API key when you create the client.

```go Go theme={"theme":"github-dark-dimmed"}
cfg := sdk.NewConfiguration() // [!code --]
client := sdk.NewAPIClient(cfg) // [!code --]
ctxWithAuth := context.WithValue(context.Background(), sdk.ContextAPIKey, sdk.APIKey{Key: "SECRET_API_KEY"}) // [!code --]
client.FingerprintApi.GetEvent(ctxWithAuth, "EVENT_ID") // [!code --]
client := fingerprint.New( // [!code ++]
  fingerprint.WithAPIKey("SECRET_API_KEY"), // [!code ++]
) // [!code ++]
client.GetEvent(context.Background(), "EVENT_ID") // [!code ++]

```

### Get an event

`GetEvent` is now a method on the client, rather than nested in the `FingerprintAPI` interface, and returns `*fingerprint.Event` instead of `EventsGetResponse`.

The event data structure is flatter. For example, the ID of the event, previously called the request ID, is now available at the top level as `EventID`, and identification fields moved from `Products.Identification.Data` to the top level.

```go Go theme={"theme":"github-dark-dimmed"}
resp, _, err := client.FingerprintApi.GetEvent(ctx, "EVENT_ID") // [!code --]
requestID := resp.Products.Identification.Data.RequestId // [!code --]
visitorID := resp.Products.Identification.Data.VisitorId // [!code --]
event, _, err := client.GetEvent(context.Background(), "EVENT_ID") // [!code ++]
eventID := event.EventID // [!code ++]
visitorID := event.Identification.VisitorID // [!code ++]
```

### Search events

`SearchEvents` uses a builder to construct the request rather than positional arguments and an options struct.

```go Go theme={"theme":"github-dark-dimmed"}
linkedID := "LINKED_ID"
resp, _, err := client.FingerprintApi.SearchEvents(ctx, 10, &sdk.FingerprintApiSearchEventsOpts{ // [!code --]
  LinkedId: &linkedID, // [!code --]
}) // [!code --]
req := fingerprint.NewSearchEventsRequest().Limit(10).LinkedID("LINKED_ID") // [!code ++]
resp, _, err := client.SearchEvents(context.Background(), req) // [!code ++]
```

### `GetVisits` replaced by `SearchEvents`

`GetVisits` has been removed. Use `SearchEvents` with `VisitorID` to query a visitor's history.

```go Go theme={"theme":"github-dark-dimmed"}
resp, _, err := client.FingerprintApi.GetVisits(ctx, "VISITOR_ID") // [!code --]
req := fingerprint.NewSearchEventsRequest().VisitorID("VISITOR_ID") // [!code ++]
resp, _, err := client.SearchEvents(context.Background(), req) // [!code ++]
```

### Sealed results

`UnsealEventsResponse` is now part of the main `fingerprint` package instead of a separate `sealed` subpackage.

```go Go theme={"theme":"github-dark-dimmed"}
events, err := sealed.UnsealEventsResponse(sealedData, []sealed.DecryptionKey{ // [!code --]
  {Key: key, Algorithm: sealed.AlgorithmAES256GCM}, // [!code --]
}) // [!code --]
events, err := fingerprint.UnsealEventsResponse(sealedData, []fingerprint.DecryptionKey{ // [!code ++]
  {Key: key, Algorithm: fingerprint.AlgorithmAES256GCM}, // [!code ++]
}) // [!code ++]
```

### Error handling

Use `fingerprint.AsErrorResponse` to inspect errors.
It returns a structured response with `Error.Code` and `Error.Message`.
SDK calls also return an `*http.Response`, which you can read to use the raw response body when handling errors.

```go Go theme={"theme":"github-dark-dimmed"}
var apiErr sdk.ApiError // [!code --]
if errors.As(err, &apiErr) { // [!code --]
  log.Printf("Error %s: %v", apiErr.Code(), apiErr.Error()) // [!code --]
} // [!code --]
if errResp, ok := fingerprint.AsErrorResponse(err); ok { // [!code ++]
  log.Printf("Error %s: %s", errResp.Error.Code, errResp.Error.Message) // [!code ++]
} // [!code ++]
```

### Handling sealed client results from a v3 JavaScript agent

Go SDK v8 will fail to deserialize the decrypted payload of a [sealed client result](/docs/sealed-client-results) sent by a v3 JavaScript agent into an `Event` because the payload is an `EventsGetResponse` (i.e., the v3 event format), not an `Event`.

To upgrade to Go SDK v8 without requiring a concurrent upgrade to the v4 JavaScript agent, you can fall back to using the Server API if unsealing the sealed client results fails.
To enable this fallback path, your frontend must send the event ID alongside the sealed client results, as recommended by the [sealed client results guide](/docs/sealed-client-results#step-3-send-sealed_result-to-your-backend).

```go Go theme={"theme":"github-dark-dimmed"}
// Partial example (imports omitted).
func getEvent(
  client *fingerprint.Client,
  sealedResult []byte,
  eventID string,
  keys []fingerprint.DecryptionKey,
) (*fingerprint.Event, error) {
  // First, decrypt the sealed results
  sealedResultPayload, err := fingerprint.Unseal(sealedResult, keys)
  if err != nil {
    return nil, err
  }

  // Next, attempt to deserialize the payload into an event
  var sealedResultEvent fingerprint.Event
  err = json.Unmarshal(sealedResultPayload, &sealedResultEvent)
  if err == nil {
    return &sealedResultEvent, nil
  }

  // Deserialization failed. Fall back to the Server API using the event ID
  // sent alongside the client sealed results.
  log.Printf("Could not deserialize unsealed payload as a v4 Event, falling back to Server API: %v", err)
  serverAPIEvent, _, err := client.GetEvent(context.Background(), eventID)
  return serverAPIEvent, err
}
```

## Documentation

You can find the full documentation in the official [GitHub repository](https://github.com/fingerprintjs/go-sdk). The repository also contains [an example app](https://github.com/fingerprintjs/go-sdk/tree/main/example) demonstrating the usage of the library.
