curl --request GET \
--url https://api.apsio.io/v1/projects/{projectId}/rollout-check \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.apsio.io/v1/projects/{projectId}/rollout-check"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.apsio.io/v1/projects/{projectId}/rollout-check', 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.apsio.io/v1/projects/{projectId}/rollout-check",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$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://api.apsio.io/v1/projects/{projectId}/rollout-check"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.apsio.io/v1/projects/{projectId}/rollout-check")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.apsio.io/v1/projects/{projectId}/rollout-check")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"summary": "<string>",
"verdict": "consider_pausing",
"blocked": true,
"subject": {
"unit": "installs",
"untrusted": {
"release": "<string>",
"baseline": "<string>"
}
},
"windows": {
"release": {
"from": "2026-10-04T10:15:00.431000000Z",
"to": "2026-10-04T10:15:00.431000000Z"
},
"baseline": {
"from": "2026-10-04T10:15:00.431000000Z",
"to": "2026-10-04T10:15:00.431000000Z"
},
"same_age": true,
"age_hours": 123,
"data_through": "2026-10-04T10:15:00.431000000Z"
},
"evidence": {
"release": {
"bad": 123,
"installs": 123,
"sessions": 123,
"rate": 123
},
"baseline": {
"bad": 123,
"installs": 123,
"sessions": 123,
"rate": 123
},
"concurrent": {
"bad": 123,
"installs": 123,
"sessions": 123,
"rate": 123
},
"per_install": {
"rate_ratio": 123,
"interval": [
123,
123
]
},
"per_session": {
"rate_ratio": 123,
"interval": [
123,
123
]
},
"same_hours": {
"rate_ratio": 123,
"interval": [
123,
123
]
}
},
"sample": {
"bad_installs": 123,
"installs": 123,
"values_tested": 123,
"power": "too_few",
"needed": 123,
"estimated": true
},
"limits": [
{
"code": "young_release",
"text": "<string>"
}
],
"would_clear_it": "<string>",
"computed_at": "2026-10-04T10:15:00.431000000Z"
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"subject": "organization"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"subject": "organization"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"subject": "organization"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"subject": "organization"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"subject": "organization"
}
}Whether to recommend pausing a rollout
One release against the one before it at the same age, in installs with a crash: a recommendation to consider pausing the rollout, with its counts and the sample’s limits, or a plain answer that there is none, or that there are too few bad installs to say. Under 20 bad installs there is no verdict and no ratio. Worse means the interval’s lower end is above 1.5×, per install, per session, and against every other release in the same hours. Only the newest release of the app is checked, for 14 days from its first session from a store, or else its first that is not a development build. Apsio pauses nothing, holds no store key and cannot see how far a rollout has gone. For what the crashes have in common, read /projects/{projectId}/probable-cause with release and baseline.
curl --request GET \
--url https://api.apsio.io/v1/projects/{projectId}/rollout-check \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.apsio.io/v1/projects/{projectId}/rollout-check"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.apsio.io/v1/projects/{projectId}/rollout-check', 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.apsio.io/v1/projects/{projectId}/rollout-check",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$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://api.apsio.io/v1/projects/{projectId}/rollout-check"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.apsio.io/v1/projects/{projectId}/rollout-check")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.apsio.io/v1/projects/{projectId}/rollout-check")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"summary": "<string>",
"verdict": "consider_pausing",
"blocked": true,
"subject": {
"unit": "installs",
"untrusted": {
"release": "<string>",
"baseline": "<string>"
}
},
"windows": {
"release": {
"from": "2026-10-04T10:15:00.431000000Z",
"to": "2026-10-04T10:15:00.431000000Z"
},
"baseline": {
"from": "2026-10-04T10:15:00.431000000Z",
"to": "2026-10-04T10:15:00.431000000Z"
},
"same_age": true,
"age_hours": 123,
"data_through": "2026-10-04T10:15:00.431000000Z"
},
"evidence": {
"release": {
"bad": 123,
"installs": 123,
"sessions": 123,
"rate": 123
},
"baseline": {
"bad": 123,
"installs": 123,
"sessions": 123,
"rate": 123
},
"concurrent": {
"bad": 123,
"installs": 123,
"sessions": 123,
"rate": 123
},
"per_install": {
"rate_ratio": 123,
"interval": [
123,
123
]
},
"per_session": {
"rate_ratio": 123,
"interval": [
123,
123
]
},
"same_hours": {
"rate_ratio": 123,
"interval": [
123,
123
]
}
},
"sample": {
"bad_installs": 123,
"installs": 123,
"values_tested": 123,
"power": "too_few",
"needed": 123,
"estimated": true
},
"limits": [
{
"code": "young_release",
"text": "<string>"
}
],
"would_clear_it": "<string>",
"computed_at": "2026-10-04T10:15:00.431000000Z"
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"subject": "organization"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"subject": "organization"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"subject": "organization"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"subject": "organization"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"subject": "organization"
}
}Authorizations
Path Parameters
Query Parameters
Response
The recommendation, or why there is none.