Management APIs
Service Accounts
Manage programmatic access to Mixpanel
GET
/
api
/
app
/
organizations
/
{organizationId}
/
service-accounts
Service Accounts
curl --request GET \
--url https://mixpanel.com/api/app/organizations/{organizationId}/service-accounts \
--header 'Content-Type: application/json' \
--data '
{
"username": "<string>",
"role": "<string>",
"expires": "<string>",
"projects": [
{
"id": 123,
"service_account_ids": [
{}
]
}
],
"service_account_ids": [
{}
]
}
'import requests
url = "https://mixpanel.com/api/app/organizations/{organizationId}/service-accounts"
payload = {
"username": "<string>",
"role": "<string>",
"expires": "<string>",
"projects": [
{
"id": 123,
"service_account_ids": [{}]
}
],
"service_account_ids": [{}]
}
headers = {"Content-Type": "application/json"}
response = requests.get(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'GET',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
username: '<string>',
role: '<string>',
expires: '<string>',
projects: [{id: 123, service_account_ids: [{}]}],
service_account_ids: [{}]
})
};
fetch('https://mixpanel.com/api/app/organizations/{organizationId}/service-accounts', 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://mixpanel.com/api/app/organizations/{organizationId}/service-accounts",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_POSTFIELDS => json_encode([
'username' => '<string>',
'role' => '<string>',
'expires' => '<string>',
'projects' => [
[
'id' => 123,
'service_account_ids' => [
[
]
]
]
],
'service_account_ids' => [
[
]
]
]),
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://mixpanel.com/api/app/organizations/{organizationId}/service-accounts"
payload := strings.NewReader("{\n \"username\": \"<string>\",\n \"role\": \"<string>\",\n \"expires\": \"<string>\",\n \"projects\": [\n {\n \"id\": 123,\n \"service_account_ids\": [\n {}\n ]\n }\n ],\n \"service_account_ids\": [\n {}\n ]\n}")
req, _ := http.NewRequest("GET", 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.get("https://mixpanel.com/api/app/organizations/{organizationId}/service-accounts")
.header("Content-Type", "application/json")
.body("{\n \"username\": \"<string>\",\n \"role\": \"<string>\",\n \"expires\": \"<string>\",\n \"projects\": [\n {\n \"id\": 123,\n \"service_account_ids\": [\n {}\n ]\n }\n ],\n \"service_account_ids\": [\n {}\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://mixpanel.com/api/app/organizations/{organizationId}/service-accounts")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"username\": \"<string>\",\n \"role\": \"<string>\",\n \"expires\": \"<string>\",\n \"projects\": [\n {\n \"id\": 123,\n \"service_account_ids\": [\n {}\n ]\n }\n ],\n \"service_account_ids\": [\n {}\n ]\n}"
response = http.request(request)
puts response.read_bodyService Accounts API
Manage service accounts for programmatic access to Mixpanel APIs.Base URL
https://mixpanel.com/api/app
Authentication
Use Service Account credentials with HTTP Basic Auth.List Service Accounts
Get all service accounts for your organization.integer
required
Your Mixpanel organization ID
Example Request
curl "https://mixpanel.com/api/app/organizations/123/service-accounts" \
-u SERVICE_ACCOUNT_USERNAME:SERVICE_ACCOUNT_SECRET
import requests
from requests.auth import HTTPBasicAuth
response = requests.get(
'https://mixpanel.com/api/app/organizations/123/service-accounts',
auth=HTTPBasicAuth('SERVICE_ACCOUNT_USERNAME', 'SERVICE_ACCOUNT_SECRET')
)
accounts = response.json()
for account in accounts['results']:
print(f"{account['username']}: ID {account['id']}")
Response
{
"status": "ok",
"results": [
{
"id": 12345,
"username": "api-bot",
"last_used": "2024-01-15T10:30:00Z",
"expires": "2025-01-15T10:30:00Z",
"creator": 789,
"created": "2024-01-01T09:00:00Z",
"user": 12345
}
]
}
Create Service Account
Create a new service account for your organization.integer
required
Your Mixpanel organization ID
string
required
A descriptive name for the service account
string
The service account’s roleOptions:
owner, admin, analyst, consumerstring
Expiration date and time in ISO formatExample:
2025-12-31T23:59:59Zarray
Example Request
curl "https://mixpanel.com/api/app/organizations/123/service-accounts" \
-X POST \
-u SERVICE_ACCOUNT_USERNAME:SERVICE_ACCOUNT_SECRET \
-H "Content-Type: application/json" \
-d '{
"username": "data-pipeline-bot",
"role": "admin",
"expires": "2025-12-31T23:59:59Z",
"projects": [
{"id": 456, "role": "admin"},
{"id": 789, "role": "analyst"}
]
}'
import requests
from requests.auth import HTTPBasicAuth
response = requests.post(
'https://mixpanel.com/api/app/organizations/123/service-accounts',
auth=HTTPBasicAuth('SERVICE_ACCOUNT_USERNAME', 'SERVICE_ACCOUNT_SECRET'),
json={
'username': 'data-pipeline-bot',
'role': 'admin',
'expires': '2025-12-31T23:59:59Z',
'projects': [
{'id': 456, 'role': 'admin'},
{'id': 789, 'role': 'analyst'}
]
}
)
result = response.json()
print(f"Service Account ID: {result['results']['id']}")
print(f"Secret (save this!): {result['results']['token']}")
Response
{
"status": "ok",
"results": {
"id": 12345,
"username": "data-pipeline-bot",
"token": "SECRET_TOKEN_SAVE_THIS",
"last_used": null,
"expires": "2025-12-31T23:59:59Z",
"creator": 789,
"created": "2024-01-15T10:30:00Z",
"user": 12345
}
}
The
token (secret) is only returned once during creation. Store it securely - it cannot be retrieved later.Get Service Account
Retrieve details of a specific service account.integer
required
Your Mixpanel organization ID
integer
required
The service account ID
Example Request
curl "https://mixpanel.com/api/app/organizations/123/service-accounts/12345" \
-u SERVICE_ACCOUNT_USERNAME:SERVICE_ACCOUNT_SECRET
Delete Service Account
Remove a service account from your organization.integer
required
Your Mixpanel organization ID
integer
required
The service account ID to delete
Example Request
curl "https://mixpanel.com/api/app/organizations/123/service-accounts/12345" \
-X DELETE \
-u SERVICE_ACCOUNT_USERNAME:SERVICE_ACCOUNT_SECRET
import requests
from requests.auth import HTTPBasicAuth
response = requests.delete(
'https://mixpanel.com/api/app/organizations/123/service-accounts/12345',
auth=HTTPBasicAuth('SERVICE_ACCOUNT_USERNAME', 'SERVICE_ACCOUNT_SECRET')
)
print(response.json()) # {"status": "ok"}
Add Service Account to Projects
Add one or more service accounts to one or more projects.integer
required
Your Mixpanel organization ID
array
required
array
required
Array of service account IDs to add
Example Request
curl "https://mixpanel.com/api/app/organizations/123/service-accounts/add-to-project" \
-X POST \
-u SERVICE_ACCOUNT_USERNAME:SERVICE_ACCOUNT_SECRET \
-H "Content-Type: application/json" \
-d '{
"projects": [
{"id": 456, "role": "admin"},
{"id": 789, "role": "analyst"}
],
"service_account_ids": [12345, 67890]
}'
Remove Service Account from Projects
integer
required
Your Mixpanel organization ID
array
required
Example Request
curl "https://mixpanel.com/api/app/organizations/123/service-accounts/remove-from-project" \
-X POST \
-u SERVICE_ACCOUNT_USERNAME:SERVICE_ACCOUNT_SECRET \
-H "Content-Type: application/json" \
-d '{
"projects": [
{"id": 456, "service_account_ids": [12345]},
{"id": 789, "service_account_ids": [12345, 67890]}
]
}'
Best Practices
Create service accounts for specific purposes
Create service accounts for specific purposes
Use dedicated service accounts for different integrations:
data-pipeline-bot: For data exportsci-cd-bot: For CI/CD integrationsanalytics-dashboard: For custom dashboards
Use least privilege
Use least privilege
Grant only the minimum required permissions:
# Good: Specific role for specific purpose
{
"username": "readonly-reporter",
"projects": [{"id": 123, "role": "consumer"}]
}
Set expiration dates
Set expiration dates
Always set expiration dates for security:
{
"expires": "2025-12-31T23:59:59Z"
}
Rotate credentials regularly
Rotate credentials regularly
Rotate service account credentials periodically:
# 1. Create new service account
# 2. Update applications to use new credentials
# 3. Delete old service account
⌘I
Service Accounts
curl --request GET \
--url https://mixpanel.com/api/app/organizations/{organizationId}/service-accounts \
--header 'Content-Type: application/json' \
--data '
{
"username": "<string>",
"role": "<string>",
"expires": "<string>",
"projects": [
{
"id": 123,
"service_account_ids": [
{}
]
}
],
"service_account_ids": [
{}
]
}
'import requests
url = "https://mixpanel.com/api/app/organizations/{organizationId}/service-accounts"
payload = {
"username": "<string>",
"role": "<string>",
"expires": "<string>",
"projects": [
{
"id": 123,
"service_account_ids": [{}]
}
],
"service_account_ids": [{}]
}
headers = {"Content-Type": "application/json"}
response = requests.get(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'GET',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
username: '<string>',
role: '<string>',
expires: '<string>',
projects: [{id: 123, service_account_ids: [{}]}],
service_account_ids: [{}]
})
};
fetch('https://mixpanel.com/api/app/organizations/{organizationId}/service-accounts', 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://mixpanel.com/api/app/organizations/{organizationId}/service-accounts",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_POSTFIELDS => json_encode([
'username' => '<string>',
'role' => '<string>',
'expires' => '<string>',
'projects' => [
[
'id' => 123,
'service_account_ids' => [
[
]
]
]
],
'service_account_ids' => [
[
]
]
]),
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://mixpanel.com/api/app/organizations/{organizationId}/service-accounts"
payload := strings.NewReader("{\n \"username\": \"<string>\",\n \"role\": \"<string>\",\n \"expires\": \"<string>\",\n \"projects\": [\n {\n \"id\": 123,\n \"service_account_ids\": [\n {}\n ]\n }\n ],\n \"service_account_ids\": [\n {}\n ]\n}")
req, _ := http.NewRequest("GET", 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.get("https://mixpanel.com/api/app/organizations/{organizationId}/service-accounts")
.header("Content-Type", "application/json")
.body("{\n \"username\": \"<string>\",\n \"role\": \"<string>\",\n \"expires\": \"<string>\",\n \"projects\": [\n {\n \"id\": 123,\n \"service_account_ids\": [\n {}\n ]\n }\n ],\n \"service_account_ids\": [\n {}\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://mixpanel.com/api/app/organizations/{organizationId}/service-accounts")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"username\": \"<string>\",\n \"role\": \"<string>\",\n \"expires\": \"<string>\",\n \"projects\": [\n {\n \"id\": 123,\n \"service_account_ids\": [\n {}\n ]\n }\n ],\n \"service_account_ids\": [\n {}\n ]\n}"
response = http.request(request)
puts response.read_body