curl --request POST \
--url https://api.apsio.io/v1/projects/{projectId}/issues/{issueId}/handoff \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"destination_id": "<string>"
}
'import requests
url = "https://api.apsio.io/v1/projects/{projectId}/issues/{issueId}/handoff"
payload = { "destination_id": "<string>" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({destination_id: '<string>'})
};
fetch('https://api.apsio.io/v1/projects/{projectId}/issues/{issueId}/handoff', 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}/handoff",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'destination_id' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"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://api.apsio.io/v1/projects/{projectId}/issues/{issueId}/handoff"
payload := strings.NewReader("{\n \"destination_id\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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.post("https://api.apsio.io/v1/projects/{projectId}/issues/{issueId}/handoff")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"destination_id\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.apsio.io/v1/projects/{projectId}/issues/{issueId}/handoff")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"destination_id\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"destination_id": "<string>",
"provider": "github",
"state": "claimed",
"ref": "<string>",
"url": "<string>",
"error_code": "<string>",
"rule_id": "<string>",
"created_by": "<string>",
"created_at": "2026-10-04T10:15:00.431000000Z",
"opened_at": "2026-10-04T10:15:00.431000000Z",
"pull_request": {
"number": 123,
"url": "<string>",
"state": "draft"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}Hand the issue off to the team's coding agent
Opens a GitHub or Linear issue for it through one of the organization’s handoff destinations, as an alert’s handoff would (the destination must be on; its daily cap counts), audited as issue.handoff. Once per destination: handing it off again answers the handoff made before. From a console session only. Send Content-Type: application/json.
curl --request POST \
--url https://api.apsio.io/v1/projects/{projectId}/issues/{issueId}/handoff \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"destination_id": "<string>"
}
'import requests
url = "https://api.apsio.io/v1/projects/{projectId}/issues/{issueId}/handoff"
payload = { "destination_id": "<string>" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({destination_id: '<string>'})
};
fetch('https://api.apsio.io/v1/projects/{projectId}/issues/{issueId}/handoff', 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}/handoff",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'destination_id' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"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://api.apsio.io/v1/projects/{projectId}/issues/{issueId}/handoff"
payload := strings.NewReader("{\n \"destination_id\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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.post("https://api.apsio.io/v1/projects/{projectId}/issues/{issueId}/handoff")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"destination_id\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.apsio.io/v1/projects/{projectId}/issues/{issueId}/handoff")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"destination_id\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"destination_id": "<string>",
"provider": "github",
"state": "claimed",
"ref": "<string>",
"url": "<string>",
"error_code": "<string>",
"rule_id": "<string>",
"created_by": "<string>",
"created_at": "2026-10-04T10:15:00.431000000Z",
"opened_at": "2026-10-04T10:15:00.431000000Z",
"pull_request": {
"number": 123,
"url": "<string>",
"state": "draft"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>"
}
}{
"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 id.
^[A-Za-z0-9._:-]{1,128}$Body
^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$Response
The handoff.
github, linear claimed: being opened; opened; failed (error_code).
claimed, opened, failed What people call it: #12, ENG-12.
The alert rule that handed it off; null from the issue page.
RFC 3339 time in UTC with up to nanosecond precision.
"2026-10-04T10:15:00.431000000Z"
RFC 3339 time in UTC with up to nanosecond precision.
"2026-10-04T10:15:00.431000000Z"
GitHub: the pull request of the same repository that references the issue last, from its timeline (refreshed at most every 10 minutes); null when none, and for Linear.
Show child attributes
Show child attributes