curl --request POST \
--url https://api.kraken.com/v0/insto/custody/tasks/{task_id}/review \
--header 'Content-Type: application/json' \
--header 'api-key: <api-key>' \
--header 'api-nonce: <api-key>' \
--header 'api-sign: <api-key>' \
--data '
{
"type": "approve",
"comment": "Transaction approved by finance team"
}
'import requests
url = "https://api.kraken.com/v0/insto/custody/tasks/{task_id}/review"
payload = {
"type": "approve",
"comment": "Transaction approved by finance team"
}
headers = {
"api-key": "<api-key>",
"api-sign": "<api-key>",
"api-nonce": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'api-key': '<api-key>',
'api-sign': '<api-key>',
'api-nonce': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({type: 'approve', comment: 'Transaction approved by finance team'})
};
fetch('https://api.kraken.com/v0/insto/custody/tasks/{task_id}/review', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.kraken.com/v0/insto/custody/tasks/{task_id}/review"
payload := strings.NewReader("{\n \"type\": \"approve\",\n \"comment\": \"Transaction approved by finance team\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("api-key", "<api-key>")
req.Header.Add("api-sign", "<api-key>")
req.Header.Add("api-nonce", "<api-key>")
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))
}{
"state": "approved"
}{
"type": "tag:kraken.com,2025:BadRequest",
"status": 400,
"title": "Bad Request",
"data": {
"message": "type must be approve or deny"
},
"detail": "Request failed validation: type must be approve or deny.",
"instance": "https://debug.kraken.com/req/01HXYZABCDEF"
}{
"type": "tag:kraken.com,2025:PermissionDenied",
"status": 403,
"title": "Forbidden",
"data": {
"message": "caller has already voted on this task"
},
"detail": "Caller is not an assigned reviewer for this task.",
"instance": "https://debug.kraken.com/req/01HXYZABCDEF"
}{
"type": "tag:kraken.com,2025:gateway/ReadUpstream",
"status": 500,
"title": "Internal Server Error",
"data": "<unknown>",
"detail": "Failed to read upstream response from custody service.",
"instance": "https://debug.kraken.com/req/01HXYZABCDEF"
}{
"type": "tag:kraken.com,2025:gateway/Connect",
"status": 503,
"title": "Service Unavailable",
"data": "<unknown>",
"detail": "Failed to connect to upstream custody service.",
"instance": "https://debug.kraken.com/req/01HXYZABCDEF"
}Review task
Records the authenticated user’s review decision on a task. The decision is approve or deny, with an optional comment. The caller must be an assigned reviewer and must not already have voted; if either condition fails the request is rejected with a 403. The response returns the task’s new lifecycle state after the decision is applied. Identify the task with path id, the approval UUID. T-prefixed identifiers are not accepted.
Rate limit: 200 requests per 30 seconds per IP.
curl --request POST \
--url https://api.kraken.com/v0/insto/custody/tasks/{task_id}/review \
--header 'Content-Type: application/json' \
--header 'api-key: <api-key>' \
--header 'api-nonce: <api-key>' \
--header 'api-sign: <api-key>' \
--data '
{
"type": "approve",
"comment": "Transaction approved by finance team"
}
'import requests
url = "https://api.kraken.com/v0/insto/custody/tasks/{task_id}/review"
payload = {
"type": "approve",
"comment": "Transaction approved by finance team"
}
headers = {
"api-key": "<api-key>",
"api-sign": "<api-key>",
"api-nonce": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'api-key': '<api-key>',
'api-sign': '<api-key>',
'api-nonce': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({type: 'approve', comment: 'Transaction approved by finance team'})
};
fetch('https://api.kraken.com/v0/insto/custody/tasks/{task_id}/review', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.kraken.com/v0/insto/custody/tasks/{task_id}/review"
payload := strings.NewReader("{\n \"type\": \"approve\",\n \"comment\": \"Transaction approved by finance team\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("api-key", "<api-key>")
req.Header.Add("api-sign", "<api-key>")
req.Header.Add("api-nonce", "<api-key>")
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))
}{
"state": "approved"
}{
"type": "tag:kraken.com,2025:BadRequest",
"status": 400,
"title": "Bad Request",
"data": {
"message": "type must be approve or deny"
},
"detail": "Request failed validation: type must be approve or deny.",
"instance": "https://debug.kraken.com/req/01HXYZABCDEF"
}{
"type": "tag:kraken.com,2025:PermissionDenied",
"status": 403,
"title": "Forbidden",
"data": {
"message": "caller has already voted on this task"
},
"detail": "Caller is not an assigned reviewer for this task.",
"instance": "https://debug.kraken.com/req/01HXYZABCDEF"
}{
"type": "tag:kraken.com,2025:gateway/ReadUpstream",
"status": 500,
"title": "Internal Server Error",
"data": "<unknown>",
"detail": "Failed to read upstream response from custody service.",
"instance": "https://debug.kraken.com/req/01HXYZABCDEF"
}{
"type": "tag:kraken.com,2025:gateway/Connect",
"status": 503,
"title": "Service Unavailable",
"data": "<unknown>",
"detail": "Failed to connect to upstream custody service.",
"instance": "https://debug.kraken.com/req/01HXYZABCDEF"
}Authorizations
Path Parameters
Task identifier, an approval UUID (UUID v4). T-prefixed identifiers are not accepted or returned. Responses always emit lowercase. Requests accept any letter case.
"550e8400-e29b-41d4-a716-446655440000"
Body
Response
The task's lifecycle state after the decision was applied.
New lifecycle state of the task after the decision was applied. One of pending, approved, rejected, canceled, expired, failed, executed.
"approved"
Was this page helpful?