Get Retention
Returns cohort-based retention analysis data. Users are grouped into cohorts based on their first visit, and retention is tracked over subsequent time periods.
A user joins a cohort only if the requested time range contains their first visit. Anyone seen in the 90 days before the range starts counts as a returning visitor and is left out. Returns are counted up to the end of the range. Filters select users by their first visit, and any later activity counts as a return.
GET /api/sites/:site/retentionReturns cohort-based retention analysis data. Users are grouped into cohorts based on their first visit, and retention is tracked over subsequent time periods.
Path Parameters
Prop
Type
Query Parameters
Accepts all Common Parameters plus the following:
Prop
Type
A range longer than 53 weeks (weekly) or 92 days (daily) is cut to its most recent periods, and truncated is true in the response.
Response
Prop
Type
RetentionData Object
Prop
Type
CohortData Object
Prop
Type
curl -X GET "https://app.onyxmetric.com/api/sites/1/retention?mode=week&range=90" \
-H "Authorization: Bearer your_api_key_here"const response = await fetch(
'https://app.onyxmetric.com/api/sites/1/retention?mode=week&range=90',
{
headers: {
'Authorization': 'Bearer your_api_key_here'
}
}
);
const data = await response.json();import requests
response = requests.get(
'https://app.onyxmetric.com/api/sites/1/retention',
params={
'mode': 'week',
'range': 90
},
headers={
'Authorization': 'Bearer your_api_key_here'
}
)
data = response.json()$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://app.onyxmetric.com/api/sites/1/retention?mode=week&range=90');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer your_api_key_here'
]);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);require 'net/http'
require 'json'
uri = URI('https://app.onyxmetric.com/api/sites/1/retention?mode=week&range=90')
req = Net::HTTP::Get.new(uri)
req['Authorization'] = 'Bearer your_api_key_here'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
data = JSON.parse(res.body)req, _ := http.NewRequest("GET", "https://app.onyxmetric.com/api/sites/1/retention?mode=week&range=90", nil)
req.Header.Set("Authorization", "Bearer your_api_key_here")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
var data map[string]interface{}
json.NewDecoder(resp.Body).Decode(&data)let client = reqwest::Client::new();
let res = client
.get("https://app.onyxmetric.com/api/sites/1/retention?mode=week&range=90")
.header("Authorization", "Bearer your_api_key_here")
.send()
.await?;
let data: serde_json::Value = res.json().await?;HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://app.onyxmetric.com/api/sites/1/retention?mode=week&range=90"))
.header("Authorization", "Bearer your_api_key_here")
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer your_api_key_here");
var response = await client.GetAsync("https://app.onyxmetric.com/api/sites/1/retention?mode=week&range=90");
var data = await response.Content.ReadAsStringAsync();{
"data": {
"cohorts": {
"2024-01-01": {
"size": 1250,
"percentages": [100, 45.2, 32.08, 28.48, 12.4],
"counts": [1250, 565, 401, 356, 155]
},
"2024-01-08": {
"size": 1420,
"percentages": [100, 48.52, 35.21, 14.08, null],
"counts": [1420, 689, 500, 200, null]
},
"2024-01-15": {
"size": 1380,
"percentages": [100, 46.81, 15.94, null, null],
"counts": [1380, 646, 220, null, null]
},
"2024-01-22": {
"size": 1510,
"percentages": [100, 17.02, null, null, null],
"counts": [1510, 257, null, null, null]
},
"2024-01-29": {
"size": 540,
"percentages": [100, null, null, null, null],
"counts": [540, null, null, null, null]
}
},
"maxPeriods": 4,
"mode": "week",
"range": 31,
"periods": ["2024-01-01", "2024-01-08", "2024-01-15", "2024-01-22", "2024-01-29"],
"windowStart": "2024-01-01T00:00:00.000Z",
"windowEnd": "2024-01-31T14:05:00.000Z",
"timeZone": "UTC",
"firstPeriodPartial": false,
"lastPeriodPartial": true,
"lastPeriodInProgress": true,
"truncated": false,
"lookbackDays": 90
}
}In this example the range ends on a Wednesday, so the week of Jan 29 is still in progress. The last value of every cohort (the one that falls in that week) is not final.
Understanding Retention Data
The retention data shows how many users from each cohort return in subsequent periods:
- Period 0: Always 100% (the cohort's first visit)
- Period 1: Users who returned 1 week later
- Period 2: Users who returned 2 weeks later
- etc.
A null value means the period falls after the end of the range for that cohort. A value of 0 means the period was observed and nobody came back.
Visualization Example
const { cohorts, maxPeriods } = data.data;
// Headers: Cohort, Size, Week 0, Week 1, Week 2, ...
const headers = ['Cohort', 'Size',
...Array(maxPeriods + 1).fill(0).map((_, i) => `Week ${i}`)
];
// Rows
Object.entries(cohorts).forEach(([date, cohort]) => {
const row = [
date,
cohort.size,
...cohort.percentages.map(p => p !== null ? `${p}%` : '-')
];
console.log(row.join(' | '));
});