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

# Mixpanel SDKs: Go

## Getting Started

The Mixpanel Go library is designed to be used for scripting, or in circumstances when a client can't or won't run client side scripts

The [Full API Reference](https://pkg.go.dev/github.com/mixpanel/mixpanel-go), [Library Source Code](https://github.com/mixpanel/mixpanel-go), and [Examples](https://github.com/mixpanel/mixpanel-go/tree/main/examples) are documented in our GitHub repo.

## Installing the Library

Install the library with [Go get](https://pkg.go.dev/cmd/go/internal/get). Run the following command in your CLI to install:

```shell theme={"system"}
# install mixpanel library using Go get
go get github.com/mixpanel/mixpanel-go
```

Once the library is installed, create an instance of Mixpanel in your code by calling the [`NewApiClient()`](https://pkg.go.dev/github.com/mixpanel/mixpanel-go#NewApiClient) using [your project token](/docs/orgs-and-projects/managing-projects#find-your-project-tokens).

```go theme={"system"}
// create an instance of Mixpanel
mp := mixpanel.NewApiClient("YOUR_PROJECT_TOKEN")
```

### Library Configuration

<Warning>For projects with EU or India data residency, you must configure the SDK to use the correct regional endpoint. Events sent to the wrong region will not be ingested. Learn more about [Privacy-Friendly Tracking](/docs/tracking-methods/sdks/go#privacy-friendly-tracking).</Warning>

The library can be initialized with different configurations. See a complete list of the configuration options[here](https://pkg.go.dev/github.com/mixpanel/mixpanel-go#Options).

You can override the default configuration using the `options` argument when initializing the library.

**Example Usage**

```go theme={"system"}
// create an instance of Mixpanel and include Service Account credentials
mp := mixpanel.NewApiClient("YOUR_PROJECT_TOKEN",
	mixpanel.ServiceAccount(7282615, "service_account_name", "service_account_secret")
)
```

## Sending Events

Use [`Track()`](https://pkg.go.dev/github.com/mixpanel/mixpanel-go#ApiClient.Track) to send an event by providing the distinct\_id, event name, and any event properties. This will trigger a request to the [/track API endpoint](/reference/track-event) to ingest the event into your project.

<Note>
  The [/track endpoint](/reference/track-event) will only validate events with timestamps within the last 5 days of the request. Events with timestamps older than 5 days will not be ingested. See below on best practices for historical imports.
</Note>

**Example Usage**

```go theme={"system"}
ctx := context.Background()

// initialize Mixpanel
mp := mixpanel.NewApiClient("YOUR_PROJECT_TOKEN")

// track "some_event" with "plan" event prop
err := mp.Track(ctx, []*mixpanel.Event{
	mp.NewEvent("some_event", "", map[string]any{
		"plan": "premium",
	}),
})
```

Mixpanel can determine default geolocation data (`$city`, `$region`, `mp_country_code`) using the IP address on the incoming request. As all server-side calls will likely originate from the same IP (that is, the IP of your server), this can have the unintended effect of setting the location of all of your users to the location of your data center. [Read about best practices for geolocation with server-side implementations](https://mixpanel.com/blog/2014/09/08/everything-about-server-side-updates/).

### Importing Historical Events

The [`Track()`](https://pkg.go.dev/github.com/mixpanel/mixpanel-go#ApiClient.Track) function is designed for real-time tracking in a server-side environment and will trigger request to the [/track API endpoint](/reference/track-event), which will validate for events with a time stamp that is within the last 5 days of the request. **Events older than 5 days will not be ingested.**

Use the [`Import()`](https://pkg.go.dev/github.com/mixpanel/mixpanel-go#ApiClient.Import) function to import events that occurred more than 5 days in the past. The `Import()` function is based on the [/import API endpoint](/reference/import-events).

**Example Usage**

```go theme={"system"}
ctx := context.Background()

// initialize Mixpanel
mp := mixpanel.NewApiClient("YOUR_PROJECT_TOKEN")

//create an event
event := mp.NewEvent("import test event", mixpanel.EmptyDistinctID, nil)
event.AddTime(time.Now())
event.AddInsertID("insert_id")
importEvents := []*mixpanel.Event{event}

// import event older than 5 days
if err := mp.Import(ctx, importEvents, mixpanel.ImportOptionsRecommend); 
err != nil {
	panic(err)
}
```

You can also use the [mp-utils python module](https://github.com/mixpanel/mixpanel-utils) designed for scripting.

## Managing User Identity

Since the Go SDK is a server-side library, IDs are not generated by the SDK. Instead, you will need to generate and manage the distinct\_id yourself and include it in your events and profile data.

Learn more about [server-side identity management](/docs/tracking-methods/id-management/identifying-users-simplified#server-side-identity-management).

## Storing User Profiles

Create [user profiles](/docs/data-structure/user-profiles) by setting profile properties to describe them. Example profile properties include "name", "email", "company", and any other demographic details about the user.

The Go SDK provides a few methods for setting profile properties, which will trigger requests to the [/engage API endpoint](/reference/profile-set).

Mixpanel determines default geolocation data (`$city`, `$region`, `mp_country_code`) using the IP address on the incoming request. As all server-side calls will likely originate from the same IP (that is, the IP of your server), this can have the unintended effect of setting the location of all of your users to the location of your data center. [Learn more about best practices for geolocation.](/docs/tracking-best-practices/geolocation).

### Setting Profile Properties

Set profile properties on a user profile by calling [`PeopleSet()`](https://pkg.go.dev/github.com/mixpanel/mixpanel-go#ApiClient.PeopleSet).

If a profile property already exists, it will be overwritten with the latest value provided in the method. If a profile property does not exist, it will be added to the profile.

**Example Usage**

```go theme={"system"}
ctx := context.Background()
mp := mixpanel.NewApiClient("YOUR_PROJECT_TOKEN")

// create a payload to create profile for distinct_id 12345
// with "name" and "plan" user props
exampleUser := mixpanel.NewPeopleProperties("12345", map[string]any{
	"name": "John",
	"plan": "premium",
	"$ip": 0, // prevent geolocation update
})

// pass the profile payload in the PeopleSet function
err := mp.PeopleSet(ctx,
	[]*mixpanel.PeopleProperties{
		exampleUser,
	},
)
```

### Other Types of Profile Updates

There are a few other methods for setting profile properties. See a complete reference of the available methods [here](https://pkg.go.dev/github.com/mixpanel/mixpanel-go#ApiClient).

A few commonly used people methods are highlighted below:

<Tabs>
  <Tab title="PeopleSetOnce()">
    The [`PeopleSetOnce()`](https://pkg.go.dev/github.com/mixpanel/mixpanel-go#ApiClient.PeopleSetOnce) method set profile properties only if they do not exist yet. If it is setting a profile property that already exists, it will be ignored.

    Use this method if you want to set profile properties without the risk of overwriting existing data.

    **Example Usage**

    ```go theme={"system"}
    ctx := context.Background()
    mp := mixpanel.NewApiClient("YOUR_PROJECT_TOKEN")

    // create a user profile with name and plan user props
    exampleUser := mixpanel.NewPeopleProperties("12345", map[string]any{
    	"name": "John",
    	"plan": "premium",
    	"$ip": 0, // prevent geolocation update
    })
    err := mp.PeopleSet(ctx,
    	[]*mixpanel.PeopleProperties{
    		exampleUser,
    	},
    )

    userUpdateA := mixpanel.NewPeopleProperties("12345", map[string]any{
    	"name": "samantha",
    	"$ip": 0,
    })
    // will be ignored since "name" already exists
    err := mp.PeopleSetOnce(ctx,
    	[]*mixpanel.PeopleProperties{
    		userUpdateA,
    	},
    )

    userUpdateB := mixpanel.NewPeopleProperties("12345", map[string]any{
    	"location": "us",
    	"$ip": 0,
    })
    // set "location" user prop since it does not exist
    err := mp.PeopleSetOnce(ctx,
    	[]*mixpanel.PeopleProperties{
    		userUpdateB,
    	},
    )
    ```
  </Tab>

  <Tab title="PeopleAppendListProperty()">
    The [`PeopleAppendListProperty()`](https://pkg.go.dev/github.com/mixpanel/mixpanel-go#ApiClient.PeopleAppendListProperty) method append values to a list profile property.

    Use this method to add additional values to an existing list property instead of redefining the entire list.

    **Example Usage**

    ```go theme={"system"}
    ctx := context.Background()
    mp := mixpanel.NewApiClient("YOUR_PROJECT_TOKEN")

    // create a user profile with name and roles user props
    exampleUser := mixpanel.NewPeopleProperties("12345", map[string]any{
    	"name": "John",
    	"roles": []string{"sales", "engineer"},
    	"$ip": 0, // prevent geolocation update
    })
    err := mp.PeopleSet(ctx,
    	[]*mixpanel.PeopleProperties{
    		exampleUser,
    	},
    )


    // add "legal" to "roles"  
    // new role values are ['sales','engineer','legal']
    if err := mp.PeopleAppendListProperty(ctx, "12345", map[string]any{
    	"roles": []string{"legal"},
    }); err != nil {
    	return err
    }

    // .append() allows duplicates
    // new "roles" values are ['sales','engineer','legal', 'legal']
    if err := mp.PeopleAppendListProperty(ctx, "12345", map[string]any{
    	"roles": []string{"legal"},
    }); err != nil {
    	return err
    }
    ```
  </Tab>

  <Tab title="PeopleUnionProperty()">
    The [`PeopleUnionProperty()`](https://pkg.go.dev/github.com/mixpanel/mixpanel-go#ApiClient.PeopleUnionProperty) method append new values to a list property, excluding duplicates.

    Use this method to create a list profile property that only contains unique values without duplicates.

    **Example Usage**

    ```go theme={"system"}
    ctx := context.Background()
    mp := mixpanel.NewApiClient("YOUR_PROJECT_TOKEN")

    // create a user profile with name and roles user props
    exampleUser := mixpanel.NewPeopleProperties("12345", map[string]any{
    	"name": "John",
    	"roles": []string{"sales", "engineer"},
    	"$ip": 0, // prevent geolocation update
    })
    err := mp.PeopleSet(ctx,
    	[]*mixpanel.PeopleProperties{
    		exampleUser,
    	})

    // "engineer" ignored since it already exists
    // append "legal" to "roles"
    err := mp.PeopleUnionProperty(ctx, "12345", map[string]any{
    	"vehicles": []string{"engineer", "legal"},
    })
    ```
  </Tab>

  <Tab title="PeopleIncrement()">
    The [`PeopleIncrement()`](https://pkg.go.dev/github.com/mixpanel/mixpanel-go#ApiClient.PeopleIncrement) method increments a numeric property by a whole number.

    Use this method to add to or subtract from your numeric property based on its current value.

    **Example Usage**

    ```go theme={"system"}
    // initialize Mixpanel
    ctx := context.Background()
    mp := mixpanel.NewApiClient("YOUR_PROJECT_TOKEN")

    // create a user profile with name and roles user props
    exampleUser := mixpanel.NewPeopleProperties("12345", map[string]any{
    	"name": "John",
    	"age": 25,
    	"$ip": 0, // prevent geolocation update
    })
    err := mp.PeopleSet(ctx,
    	[]*mixpanel.PeopleProperties{
    		exampleUser,
    	})

    // increment "age" by 2
    err := mp.PeopleIncrement(ctx, "12345", map[string]int{
    	"age": 2,
    })

    // use negative number to decrement
    // decrement "age" by 5
    err := mp.PeopleIncrement(ctx, "12345", map[string]int{
    	"age": -5,
    })

    ```
  </Tab>
</Tabs>

## Group Analytics

<Note>
  Read more about [Group Analytics](/docs/data-structure/group-analytics) before proceeding. You will need to have the [group key defined in your project settings](/docs/data-structure/group-analytics#group-keys-in-project-settings) first.
</Note>

Mixpanel Group Analytics is a paid add-on that allows behavioral data analysis by selected groups, as opposed to individual users.

A group is identified by the `group_key` and `group_id`.

* `group_key` is the event property that connects event data to a group. (e.g. `company`)
* `group_id` is the identifier for a specific group. (e.g. `mixpanel`,`company_a`,`company_b`, etc.)

### Sending Group Identifiers With Events

[All events must have the group key as an event property in order to be attributed to a group](/docs/data-structure/group-analytics#group-keys-tracked-as-event-properties). Without the group key, an event cannot be attributed to a group.

To send group identifiers with your events, set the `group_key` as an event property with the `group_id` as the value.

**Example Usage**

```go theme={"system"}
ctx := context.Background()
mp := mixpanel.NewApiClient("YOUR_PROJECT_TOKEN")

// send "some_event"
// event will be attributed to the "mixpanel" company group
mp.Track(ctx, []*mixpanel.Event{
	mp.NewEvent("some_event", "sample_distinct_id", map[string]any{
		"Plan Type": "Premium",
		"company":   "mixpanel",
	}),
})
```

**Multiple Groups**

[An event can be attributed to multiple groups](/docs/data-structure/group-analytics#attribute-events-to-multiple-groups) by passing in the `group_key` value as a list of multiple `group_id` values.

**Example Usage**

```go theme={"system"}
ctx := context.Background()
mp := mixpanel.NewApiClient("YOUR_PROJECT_TOKEN")

// send "some_event"
// event is attributed to 2 company groups: "mp-us" and "mp-eu"
mp.Track(ctx, []*mixpanel.Event{
	mp.NewEvent("some_event", "sample_distinct_id", map[string]any{
		"Plan Type": "Premium",
		"company":   []string{"mp-us", "mp-eu"},
	}),
})
```

### Adding Group Identifiers to User Profiles

To connect group information to a user profile, include the `group_key` and `group_id` as a user profile property using the `.PeopleSet` call.

**Example Usage**

```go theme={"system"}
ctx := context.Background()
mp := mixpanel.NewApiClient("YOUR_PROJECT_TOKEN")

// create a payload to create profile for distinct_id 12345
// with group key "company" as user prop and group ID "mixpanel" as value
exampleUser := mixpanel.NewPeopleProperties("12345", map[string]any{
	"name": "sam",
	"company": "mixpanel",
	"$ip": 0
})

// pass the profile payload in the PeopleSet function
err := mp.PeopleSet(ctx,
	[]*mixpanel.PeopleProperties{
		exampleUser,
	},
)
```

### Setting Group Profile Properties

Create a group profiles by setting group properties, similar to a user profile. For example, you may want to describe a company group with properties such as "ARR", "employee\_count", and "subscription".

The Go SDK provides a few methods for setting group profile properties, which will trigger requests to the [/engage API endpoint](/reference/group-set-property).

To set group profile properties, use the [`GroupSet()`](https://pkg.go.dev/github.com/mixpanel/mixpanel-go#ApiClient.GroupSet) method.

**Example Usage**

```go theme={"system"}
ctx := context.Background()
mp := mixpanel.NewApiClient("YOUR_PROJECT_TOKEN")

// Create or update a the "mixpanel" company group
// setting "Industry" and "Name" as group props
mp.GroupSet(ctx, "company", "mixpanel", map[string]any{
	"Industry": "Analytics",
	"Name":        "Mixpanel",
})
```

### Other Group Profile Methods

See all of the group methods under the [here](https://pkg.go.dev/github.com/mixpanel/mixpanel-go#ApiClient).

A few commonly used group methods are highlighted below:

<Tabs>
  <Tab title="GroupSetOnce()">
    The [`GroupSetOnce()`](https://pkg.go.dev/github.com/mixpanel/mixpanel-go#ApiClient.GroupSetOnce) method set group profile properties only if they do not exist yet. If it is setting a profile property that already exists, it will be ignored.

    Use this method if you want to set group profile properties without the risk of overwriting existing data.

    **Example Usage**

    ```go theme={"system"}
    ctx := context.Background()
    mp := mixpanel.NewApiClient("YOUR_PROJECT_TOKEN")

    // set group profile for "mixpanel" company group
    mp.GroupSet(ctx, "Company", "mixpanel", map[string]any{
    	"Name": "Mixpanel",
    	"employee_count": 100
    })

    // ignored since "Name" is already exists
    mp.GroupSetOnce(ctx, "Company", "mixpanel", map[string]any{
    	"Name": "mp-us",
    })

    // set "location" group prop since it does not exist
    mp.GroupSetOnce(ctx, "Company", "mixpanel", map[string]any{
    	"location": "us",
    })
    ```
  </Tab>

  <Tab title="GroupDeleteProperty()">
    The [`GroupDeleteProperty()`](https://pkg.go.dev/github.com/mixpanel/mixpanel-go#ApiClient.GroupDeleteProperty) method removes a group property from a group profile.

    Use this method to delete unwanted group profile properties from a specific group profile.

    **Example Usage**

    ```go theme={"system"}
    ctx := context.Background()
    mp := mixpanel.NewApiClient("YOUR_PROJECT_TOKEN")

    // set group profile for "mixpanel" company group
    mp.GroupSet(ctx, "Company", "mixpanel", map[string]any{
    	"Name": "Mixpanel",
    	"employee_count": 100
    })

    // delete "employee_count" from the group profile
    mp.GroupDeleteProperty(ctx, "Company", "mixpanel", "employee_count")

    // only "Name" remains as a group prop
    ```
  </Tab>

  <Tab title="GroupUnionListProperty()">
    The [`GroupUnionListProperty()`](https://pkg.go.dev/github.com/mixpanel/mixpanel-go#ApiClient.GroupUnionListProperty) method append new values to a list property, excluding duplicates.

    Use this method to create a list group profile property that only contains unique values without duplicates.

    **Example Usage**

    ```go theme={"system"}
    ctx := context.Background()
    mp := mixpanel.NewApiClient("YOUR_PROJECT_TOKEN")

    // set group profile for "mixpanel" company group
    mp.GroupSet(ctx, "Company", "mixpanel", map[string]any{
    	"Name": "Mixpanel",
    	"features": []string{"alert","report","cohort"},
    })

    // add "data pipeline" to "features" prop
    // ignore "alert" since it is a duplicate value
    mp.GroupUnionListProperty(ctx, "Company", "mixpanel", map[string]any{
    	"features": []string{"data pipeline","alert"},
    })
    ```
  </Tab>

  <Tab title="GroupRemoveListProperty()">
    The [`GroupRemoveListProperty()`](https://pkg.go.dev/github.com/mixpanel/mixpanel-go#ApiClient.GroupRemoveListProperty) method removes a value from a list-valued group profile property.

    Use this method to remove specific values from a list without affecting all of the other values in the list.

    **Example Usage**

    ```go theme={"system"}
    ctx := context.Background()
    mp := mixpanel.NewApiClient("YOUR_PROJECT_TOKEN")

    // set group profile for "mixpanel" company group
    mp.GroupSet(ctx, "Company", "mixpanel", map[string]any{
    	"Name": "Mixpanel",
    	"features": []string{"alert","report","cohort"},
    })

    // remove "alerts" from "features"
    // "features" now contain ["reports","cohorts"]
    mp.GroupRemoveListProperty(ctx, "Company", "mixpanel", map[string]any{
    	"features": []string{"alert"},
    })
    ```
  </Tab>
</Tabs>

## Privacy-Friendly Tracking

You have control over the data you send to Mixpanel. The Go SDK has a few configurations to help you protect user data.

Since this is a server-side tracking library where you have control of the servers, your server is responsible for determining whether to send data about a particular user or not.

### EU Data Residency

Route data to Mixpanel's EU servers by using the [`EuResidency`](https://pkg.go.dev/github.com/mixpanel/mixpanel-go#EuResidency) option during the library initialization.

```go theme={"system"}
ctx := context.Background()

//Initialize Mixpanel with request URL set to Mixpanel's EU domain
mp := mixpanel.NewApiClient("YOUR_PROJECT_TOKEN", mixpanel.EuResidency())
```

### IN Data Residency

Route data to Mixpanel's IN servers by using the [`InResidency`](https://github.com/mixpanel/mixpanel-go/blob/2d7b4a098b47064e7ae5874472368e8699232a96/mixpanel.go#L138) option during the library initialization.

```go theme={"system"}
ctx := context.Background()

//Initialize Mixpanel with request URL set to Mixpanel's IN domain
mp := mixpanel.NewApiClient("YOUR_PROJECT_TOKEN", mixpanel.InResidency())
```

### Disable Geolocation

The Go SDK parse the request IP address to generate geolocation properties for events and profiles. You may want to disable them to prevent the unintentional setting of your data's geolocation to the location of your server that is sending the request, or to prevent geolocation data from being tracked entirely.

You can also disable geolocation for individual requests by setting the `$ip`/`ip` in your events and profile payloads to `0`.

**Example Usage**

```go theme={"system"}
ctx := context.Background()
mp := mixpanel.NewApiClient("YOUR_PROJECT_TOKEN")

// set profile without geolocation parsing
exampleUser := mixpanel.NewPeopleProperties("12345", map[string]any{
	"name": "John",
	"plan": "premium",
	"$ip": 0, // prevent geolocation update
})
err := mp.PeopleSet(ctx,
	[]*mixpanel.PeopleProperties{
		exampleUser,
	},
)

// track "some_event" without setting geolocation
err := mp.Track(ctx, []*mixpanel.Event{
	mp.NewEvent("some_event", "", map[string]any{
		"plan": "premium",
		"ip": "0",
	}),
})
```

## Release History

[See all releases.](https://github.com/mixpanel/mixpanel-go/releases)
