Ingestion API
Groups
Organize users into groups and manage group properties
POST
/
groups
Groups
curl --request POST \
--url https://api.mixpanel.com/groups \
--header 'Content-Type: application/json' \
--data '
{
"$token": "<string>",
"$group_key": "<string>",
"$group_id": "<string>",
"$set": {},
"$set_once": {},
"$unset": [
{}
],
"$union": {},
"$remove": {},
"$delete": "<string>"
}
'import requests
url = "https://api.mixpanel.com/groups"
payload = {
"$token": "<string>",
"$group_key": "<string>",
"$group_id": "<string>",
"$set": {},
"$set_once": {},
"$unset": [{}],
"$union": {},
"$remove": {},
"$delete": "<string>"
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
$token: '<string>',
$group_key: '<string>',
$group_id: '<string>',
$set: {},
$set_once: {},
$unset: [{}],
$union: {},
$remove: {},
$delete: '<string>'
})
};
fetch('https://api.mixpanel.com/groups', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.mixpanel.com/groups",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'$token' => '<string>',
'$group_key' => '<string>',
'$group_id' => '<string>',
'$set' => [
],
'$set_once' => [
],
'$unset' => [
[
]
],
'$union' => [
],
'$remove' => [
],
'$delete' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.mixpanel.com/groups"
payload := strings.NewReader("{\n \"$token\": \"<string>\",\n \"$group_key\": \"<string>\",\n \"$group_id\": \"<string>\",\n \"$set\": {},\n \"$set_once\": {},\n \"$unset\": [\n {}\n ],\n \"$union\": {},\n \"$remove\": {},\n \"$delete\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.mixpanel.com/groups")
.header("Content-Type", "application/json")
.body("{\n \"$token\": \"<string>\",\n \"$group_key\": \"<string>\",\n \"$group_id\": \"<string>\",\n \"$set\": {},\n \"$set_once\": {},\n \"$unset\": [\n {}\n ],\n \"$union\": {},\n \"$remove\": {},\n \"$delete\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.mixpanel.com/groups")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"$token\": \"<string>\",\n \"$group_key\": \"<string>\",\n \"$group_id\": \"<string>\",\n \"$set\": {},\n \"$set_once\": {},\n \"$unset\": [\n {}\n ],\n \"$union\": {},\n \"$remove\": {},\n \"$delete\": \"<string>\"\n}"
response = http.request(request)
puts response.read_bodyGroups
Groups allow you to organize users into entities like companies, accounts, or organizations. Group analytics let you analyze behavior at the group level.Base URL
https://api.mixpanel.com/groups
Authentication
Use your project token for authentication.Set Group Property
Update or add properties to a group profile. Creates the group if it doesn’t exist.Request Body
string
required
Your project token
string
required
The group key (e.g., “company”, “account_id”)
string
required
The unique identifier for this group
object
required
Object containing properties to set
Example
curl https://api.mixpanel.com/groups \
--data-urlencode data='[
{
"$token": "YOUR_PROJECT_TOKEN",
"$group_key": "company",
"$group_id": "mixpanel_inc",
"$set": {
"name": "Mixpanel Inc",
"industry": "Analytics",
"employees": 350,
"plan": "enterprise"
}
}
]'
import requests
import json
data = [{
"$token": "YOUR_PROJECT_TOKEN",
"$group_key": "company",
"$group_id": "mixpanel_inc",
"$set": {
"name": "Mixpanel Inc",
"industry": "Analytics",
"employees": 350,
"plan": "enterprise"
}
}]
response = requests.post(
'https://api.mixpanel.com/groups',
data={'data': json.dumps(data)}
)
print(response.text) # Returns 1 for success
const data = [{
$token: 'YOUR_PROJECT_TOKEN',
$group_key: 'company',
$group_id: 'mixpanel_inc',
$set: {
name: 'Mixpanel Inc',
industry: 'Analytics',
employees: 350
}
}];
fetch('https://api.mixpanel.com/groups', {
method: 'POST',
body: 'data=' + encodeURIComponent(JSON.stringify(data))
});
Set Group Property Once
Set properties only if they don’t already exist on the group.Request Body
string
required
Your project token
string
required
The group key
string
required
The unique identifier for this group
object
required
Properties to set only if they don’t exist
Example
curl https://api.mixpanel.com/groups \
--data-urlencode data='[
{
"$token": "YOUR_PROJECT_TOKEN",
"$group_key": "company",
"$group_id": "mixpanel_inc",
"$set_once": {
"created_date": "2024-01-01",
"founding_year": 2009
}
}
]'
data = [{
"$token": "YOUR_PROJECT_TOKEN",
"$group_key": "company",
"$group_id": "mixpanel_inc",
"$set_once": {
"created_date": "2024-01-01",
"founding_year": 2009
}
}]
response = requests.post(
'https://api.mixpanel.com/groups',
data={'data': json.dumps(data)}
)
Delete Group Property
Remove specific properties from a group profile.Request Body
string
required
Your project token
string
required
The group key
string
required
The unique identifier for this group
array
required
Array of property names to delete
Example
curl https://api.mixpanel.com/groups \
--data-urlencode data='[
{
"$token": "YOUR_PROJECT_TOKEN",
"$group_key": "company",
"$group_id": "mixpanel_inc",
"$unset": ["temp_field", "old_data"]
}
]'
data = [{
"$token": "YOUR_PROJECT_TOKEN",
"$group_key": "company",
"$group_id": "mixpanel_inc",
"$unset": ["temp_field", "old_data"]
}]
response = requests.post(
'https://api.mixpanel.com/groups',
data={'data': json.dumps(data)}
)
Union To List Property
Add values to a list property, ensuring uniqueness.Request Body
string
required
Your project token
string
required
The group key
string
required
The unique identifier for this group
object
required
Object with arrays of values to add
Example
curl https://api.mixpanel.com/groups \
--data-urlencode data='[
{
"$token": "YOUR_PROJECT_TOKEN",
"$group_key": "company",
"$group_id": "mixpanel_inc",
"$union": {
"products": ["analytics", "data-warehouse"],
"integrations": ["salesforce", "hubspot"]
}
}
]'
data = [{
"$token": "YOUR_PROJECT_TOKEN",
"$group_key": "company",
"$group_id": "mixpanel_inc",
"$union": {
"products": ["analytics", "data-warehouse"],
"integrations": ["salesforce", "hubspot"]
}
}]
response = requests.post(
'https://api.mixpanel.com/groups',
data={'data': json.dumps(data)}
)
Remove from List Property
Remove specific values from a list property.Request Body
string
required
Your project token
string
required
The group key
string
required
The unique identifier for this group
object
required
Object with values to remove
Example
curl https://api.mixpanel.com/groups \
--data-urlencode data='[
{
"$token": "YOUR_PROJECT_TOKEN",
"$group_key": "company",
"$group_id": "mixpanel_inc",
"$remove": {
"integrations": "deprecated_tool"
}
}
]'
data = [{
"$token": "YOUR_PROJECT_TOKEN",
"$group_key": "company",
"$group_id": "mixpanel_inc",
"$remove": {
"integrations": "deprecated_tool"
}
}]
response = requests.post(
'https://api.mixpanel.com/groups',
data={'data': json.dumps(data)}
)
Delete Group
Permanently delete a group profile.Request Body
string
required
Your project token
string
required
The group key
string
required
The unique identifier for this group
string
required
Set to empty string (value is ignored)
Example
curl https://api.mixpanel.com/groups \
--data-urlencode data='[
{
"$token": "YOUR_PROJECT_TOKEN",
"$group_key": "company",
"$group_id": "old_company",
"$delete": ""
}
]'
data = [{
"$token": "YOUR_PROJECT_TOKEN",
"$group_key": "company",
"$group_id": "old_company",
"$delete": ""
}]
response = requests.post(
'https://api.mixpanel.com/groups',
data={'data': json.dumps(data)}
)
Batch Update Groups
Update multiple groups in a single request.Example
import requests
import json
data = [
{
"$token": "YOUR_PROJECT_TOKEN",
"$group_key": "company",
"$group_id": "company_1",
"$set": {"plan": "enterprise"}
},
{
"$token": "YOUR_PROJECT_TOKEN",
"$group_key": "company",
"$group_id": "company_2",
"$set": {"plan": "professional"}
},
{
"$token": "YOUR_PROJECT_TOKEN",
"$group_key": "company",
"$group_id": "company_3",
"$set": {"status": "active"}
}
]
response = requests.post(
'https://api.mixpanel.com/groups',
data={'data': json.dumps(data)}
)
print(response.text)
Linking Users to Groups
To associate users with groups, send events with group properties:import requests
import uuid
import time
# Track event with group association
event = {
"event": "Purchase",
"properties": {
"time": int(time.time()),
"distinct_id": "user123",
"$insert_id": str(uuid.uuid4()),
"company": "mixpanel_inc", # Links user to group
"amount": 99.99
}
}
response = requests.post(
'https://api.mixpanel.com/import',
auth=('SERVICE_ACCOUNT', 'SECRET'),
params={'project_id': 'PROJECT_ID', 'strict': '1'},
json=[event]
)
The group key (e.g., “company”) must be defined in your project settings under Group Keys before you can use it.
Best Practices
Define group keys in project settings
Define group keys in project settings
Before sending group data, configure your group keys in Project Settings > Group Keys. Common examples:
company: For B2B SaaS productsorganization: For enterprise customersteam: For team-based featuresworkspace: For workspace-based products
Use consistent group identifiers
Use consistent group identifiers
Use the same identifier format across all systems:
# Good: Consistent IDs
"$group_id": "company_12345"
# Bad: Inconsistent IDs
# Sometimes "company_12345", sometimes "12345"
Store group-level metrics as properties
Store group-level metrics as properties
Track aggregate information about the group:
{
"$set": {
"total_users": 150,
"monthly_usage": 50000,
"plan": "enterprise",
"seats_purchased": 200
}
}
Update group properties when they change
Update group properties when they change
Keep group data in sync with your systems:
# When a company upgrades
update_group({
"$set": {
"plan": "enterprise",
"upgrade_date": "2024-01-15"
}
})
Common Use Cases
B2B SaaS Company Analytics
# Set up company profile
data = [{
"$token": "YOUR_PROJECT_TOKEN",
"$group_key": "company",
"$group_id": "acme_corp",
"$set": {
"name": "Acme Corporation",
"industry": "Technology",
"employees": 500,
"plan": "enterprise",
"mrr": 5000,
"seats": 100
}
}]
# Track user action with company association
event = {
"event": "Feature Used",
"properties": {
"distinct_id": "user@acme.com",
"company": "acme_corp",
"feature": "advanced_analytics"
}
}
Multi-tenant Applications
# Track workspace-level metrics
data = [{
"$token": "YOUR_PROJECT_TOKEN",
"$group_key": "workspace",
"$group_id": "ws_12345",
"$set": {
"name": "Marketing Team",
"members_count": 15,
"storage_used_gb": 250,
"plan": "professional"
}
}]
Groups
curl --request POST \
--url https://api.mixpanel.com/groups \
--header 'Content-Type: application/json' \
--data '
{
"$token": "<string>",
"$group_key": "<string>",
"$group_id": "<string>",
"$set": {},
"$set_once": {},
"$unset": [
{}
],
"$union": {},
"$remove": {},
"$delete": "<string>"
}
'import requests
url = "https://api.mixpanel.com/groups"
payload = {
"$token": "<string>",
"$group_key": "<string>",
"$group_id": "<string>",
"$set": {},
"$set_once": {},
"$unset": [{}],
"$union": {},
"$remove": {},
"$delete": "<string>"
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
$token: '<string>',
$group_key: '<string>',
$group_id: '<string>',
$set: {},
$set_once: {},
$unset: [{}],
$union: {},
$remove: {},
$delete: '<string>'
})
};
fetch('https://api.mixpanel.com/groups', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.mixpanel.com/groups",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'$token' => '<string>',
'$group_key' => '<string>',
'$group_id' => '<string>',
'$set' => [
],
'$set_once' => [
],
'$unset' => [
[
]
],
'$union' => [
],
'$remove' => [
],
'$delete' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.mixpanel.com/groups"
payload := strings.NewReader("{\n \"$token\": \"<string>\",\n \"$group_key\": \"<string>\",\n \"$group_id\": \"<string>\",\n \"$set\": {},\n \"$set_once\": {},\n \"$unset\": [\n {}\n ],\n \"$union\": {},\n \"$remove\": {},\n \"$delete\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.mixpanel.com/groups")
.header("Content-Type", "application/json")
.body("{\n \"$token\": \"<string>\",\n \"$group_key\": \"<string>\",\n \"$group_id\": \"<string>\",\n \"$set\": {},\n \"$set_once\": {},\n \"$unset\": [\n {}\n ],\n \"$union\": {},\n \"$remove\": {},\n \"$delete\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.mixpanel.com/groups")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"$token\": \"<string>\",\n \"$group_key\": \"<string>\",\n \"$group_id\": \"<string>\",\n \"$set\": {},\n \"$set_once\": {},\n \"$unset\": [\n {}\n ],\n \"$union\": {},\n \"$remove\": {},\n \"$delete\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body