curl --request GET \
--url https://api.apsio.io/v1/projects/{projectId}/issues/{issueId}/series \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.apsio.io/v1/projects/{projectId}/issues/{issueId}/series"
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}/issues/{issueId}/series', 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}/issues/{issueId}/series",
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}/issues/{issueId}/series"
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}/issues/{issueId}/series")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.apsio.io/v1/projects/{projectId}/issues/{issueId}/series")
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{
"id": "<string>",
"ends": [
"2026-10-04T10:15:00.431000000Z"
],
"occurrences": [
123
],
"sessions": [
123
],
"retention_days": 90,
"releases": [
{
"app_id": "<string>",
"release": "<string>",
"first_seen": "2026-10-04T10:15:00.431000000Z",
"occurrences": [
123
]
}
],
"other": [
123
]
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}An issue's occurrences per day
Occurrences and sessions of an issue in rolling 24-hour buckets ending now (APS-298): days of them, 14 by default, at most 90; buckets before the plan’s retention (D94) count nothing. With by=release, the occurrences of its 10 releases with the most of them, each with the time the release was first seen (its first session), and the rest summed in other, for a chart stacked by release. A merged-away id answers its issue (D102).
curl --request GET \
--url https://api.apsio.io/v1/projects/{projectId}/issues/{issueId}/series \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.apsio.io/v1/projects/{projectId}/issues/{issueId}/series"
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}/issues/{issueId}/series', 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}/issues/{issueId}/series",
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}/issues/{issueId}/series"
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}/issues/{issueId}/series")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.apsio.io/v1/projects/{projectId}/issues/{issueId}/series")
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{
"id": "<string>",
"ends": [
"2026-10-04T10:15:00.431000000Z"
],
"occurrences": [
123
],
"sessions": [
123
],
"retention_days": 90,
"releases": [
{
"app_id": "<string>",
"release": "<string>",
"first_seen": "2026-10-04T10:15:00.431000000Z",
"occurrences": [
123
]
}
],
"other": [
123
]
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}Authorizations
A project token (apsio_pt_v0...), which reads exactly one project, or an OAuth access token issued for the API, which reads what its user can. Access tokens issued for Apsio's MCP server are accepted only from the MCP server itself.
Path Parameters
^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"0192f3a4-0000-7000-8000-00000000a101"
The issue fingerprint.
^[A-Za-z0-9._:-]{1,128}$"3f9a0c2e7d1b4a6c8e0f1a2b3c4d5e6f"
Query Parameters
Only this app.
^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$1 <= x <= 90release Response
The series.
The issue: the one asked for, or merged into.
Each bucket's end, oldest first: 24-hour buckets ending at the request's time, the last one ending now.
RFC 3339 time in UTC with up to nanosecond precision.
How many days of crashes and release health the project's plan keeps (D94). Nothing older is returned, whatever the time range.
90
With by=release: most occurrences first.
Show child attributes
Show child attributes
With by=release: the other releases' occurrences, summed.