Query API
Retention
Query retention and frequency data
GET
/
api
/
query
/
retention
Retention
curl --request GET \
--url https://mixpanel.com/api/query/retentionimport requests
url = "https://mixpanel.com/api/query/retention"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://mixpanel.com/api/query/retention', 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/query/retention",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://mixpanel.com/api/query/retention"
req, _ := http.NewRequest("GET", url, nil)
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/query/retention")
.asString();require 'uri'
require 'net/http'
url = URI("https://mixpanel.com/api/query/retention")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_body{
"data": {
"counts": [
{}
],
"first": 123
}
}Query Retention
Retrieve retention metrics including birth retention, compounded retention, and frequency data.Query Retention Report
integer
required
Your Mixpanel project ID
integer
The workspace ID
string
required
Start date in
YYYY-MM-DD formatstring
required
End date in
YYYY-MM-DD formatstring
Type of retention analysis.Options:
birth (first time retention) or compounded (recurring retention)Default: birthstring
The first event a user must do to be counted in a birth retention cohort. Required when
retention_type is birth.string
The event to generate returning counts for. Applies to both birth and compounded retention.
string
Expression to filter born_events by
string
Expression to filter return events by
integer
The number of units per bucketed interval. Default is
1.integer
The number of individual buckets/intervals returned. Default is
1.string
The interval unit.Options:
day, week, monthDefault: dayboolean
Accumulate retention values from right to left. When
true, day N equals users who retained on day N and any day after.Default: falsestring
Property to segment retention by
integer
Maximum number of property values to return when segmenting
Example Request
curl "https://mixpanel.com/api/query/retention?project_id=123&from_date=2024-01-01&to_date=2024-01-31&retention_type=birth&born_event=Signed%20Up&event=App%20Open" \
-u SERVICE_ACCOUNT_USERNAME:SERVICE_ACCOUNT_SECRET
import requests
from requests.auth import HTTPBasicAuth
response = requests.get(
'https://mixpanel.com/api/query/retention',
auth=HTTPBasicAuth('SERVICE_ACCOUNT_USERNAME', 'SERVICE_ACCOUNT_SECRET'),
params={
'project_id': 123,
'from_date': '2024-01-01',
'to_date': '2024-01-31',
'retention_type': 'birth',
'born_event': 'Signed Up',
'event': 'App Open',
'unit': 'day',
'interval_count': 30
}
)
data = response.json()
print(data)
Response
object
{
"2024-01-01": {
"counts": [50, 45, 42, 40, 38],
"first": 50
},
"2024-01-02": {
"counts": [75, 68, 63, 59, 55],
"first": 75
},
"2024-01-03": {
"counts": [60, 55, 51, 48, 45],
"first": 60
}
}
Use Cases
Calculate Retention Rates
import requests
from requests.auth import HTTPBasicAuth
def calculate_retention_rates(project_id):
"""Calculate Day 1, Day 7, Day 30 retention rates"""
response = requests.get(
'https://mixpanel.com/api/query/retention',
auth=HTTPBasicAuth('USERNAME', 'SECRET'),
params={
'project_id': project_id,
'from_date': '2024-01-01',
'to_date': '2024-01-31',
'retention_type': 'birth',
'born_event': 'Signed Up',
'event': 'App Open',
'interval_count': 30
}
)
data = response.json()
# Calculate average retention rates
day1_rates = []
day7_rates = []
day30_rates = []
for date, cohort in data.items():
first = cohort['first']
counts = cohort['counts']
if len(counts) > 0:
day1_rates.append(counts[0] / first)
if len(counts) > 6:
day7_rates.append(counts[6] / first)
if len(counts) > 29:
day30_rates.append(counts[29] / first)
print(f"Day 1 Retention: {sum(day1_rates)/len(day1_rates):.1%}")
print(f"Day 7 Retention: {sum(day7_rates)/len(day7_rates):.1%}")
print(f"Day 30 Retention: {sum(day30_rates)/len(day30_rates):.1%}")
calculate_retention_rates(123)
Retention
curl --request GET \
--url https://mixpanel.com/api/query/retentionimport requests
url = "https://mixpanel.com/api/query/retention"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://mixpanel.com/api/query/retention', 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/query/retention",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://mixpanel.com/api/query/retention"
req, _ := http.NewRequest("GET", url, nil)
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/query/retention")
.asString();require 'uri'
require 'net/http'
url = URI("https://mixpanel.com/api/query/retention")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_body{
"data": {
"counts": [
{}
],
"first": 123
}
}