curl --request POST \
--url https://api.kraken.com/v0/insto/custody/tasks \
--header 'Content-Type: application/json' \
--header 'api-key: <api-key>' \
--header 'api-nonce: <api-key>' \
--header 'api-sign: <api-key>' \
--data '
{
"instructions": [
{
"type": "update_subquorum",
"version": 123,
"vault_id": "<string>",
"groups": [
{
"required": 123,
"members": [
"<string>"
],
"id": "<string>"
}
]
}
],
"org_iiban": "ABCD EFGH IJKL MNOP",
"duration_seconds": 86400
}
'import requests
url = "https://api.kraken.com/v0/insto/custody/tasks"
payload = {
"instructions": [
{
"type": "update_subquorum",
"version": 123,
"vault_id": "<string>",
"groups": [
{
"required": 123,
"members": ["<string>"],
"id": "<string>"
}
]
}
],
"org_iiban": "ABCD EFGH IJKL MNOP",
"duration_seconds": 86400
}
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({
instructions: [
{
type: 'update_subquorum',
version: 123,
vault_id: '<string>',
groups: [{required: 123, members: ['<string>'], id: '<string>'}]
}
],
org_iiban: 'ABCD EFGH IJKL MNOP',
duration_seconds: 86400
})
};
fetch('https://api.kraken.com/v0/insto/custody/tasks', 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"
payload := strings.NewReader("{\n \"instructions\": [\n {\n \"type\": \"update_subquorum\",\n \"version\": 123,\n \"vault_id\": \"<string>\",\n \"groups\": [\n {\n \"required\": 123,\n \"members\": [\n \"<string>\"\n ],\n \"id\": \"<string>\"\n }\n ]\n }\n ],\n \"org_iiban\": \"ABCD EFGH IJKL MNOP\",\n \"duration_seconds\": 86400\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))
}{
"id": "550e8400-e29b-41d4-a716-446655440000"
}{
"type": "tag:kraken.com,2025:BadRequest",
"status": 400,
"title": "Bad Request",
"data": {
"message": "instructions must not be empty"
},
"detail": "Request failed validation: instructions must not be empty.",
"instance": "https://debug.kraken.com/req/01HXYZABCDEF"
}{
"type": "tag:kraken.com,2025:PermissionDenied",
"status": 403,
"title": "Forbidden",
"data": {
"message": "api key lacks access to the requested vault"
},
"detail": "Caller lacks access to the requested vault or organization.",
"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"
}Create task
Creates an approval task from one or more instructions. Each instruction describes a single change, such as a withdrawal, a sub-quorum update, or a user removal. The task is created in a pending state and its instructions take effect asynchronously once the task is approved. The response returns id, the approval UUID. It does not return task_id or approval_id. T-prefixed identifiers are not returned.
Rate limit: 200 requests per 30 seconds per IP.
curl --request POST \
--url https://api.kraken.com/v0/insto/custody/tasks \
--header 'Content-Type: application/json' \
--header 'api-key: <api-key>' \
--header 'api-nonce: <api-key>' \
--header 'api-sign: <api-key>' \
--data '
{
"instructions": [
{
"type": "update_subquorum",
"version": 123,
"vault_id": "<string>",
"groups": [
{
"required": 123,
"members": [
"<string>"
],
"id": "<string>"
}
]
}
],
"org_iiban": "ABCD EFGH IJKL MNOP",
"duration_seconds": 86400
}
'import requests
url = "https://api.kraken.com/v0/insto/custody/tasks"
payload = {
"instructions": [
{
"type": "update_subquorum",
"version": 123,
"vault_id": "<string>",
"groups": [
{
"required": 123,
"members": ["<string>"],
"id": "<string>"
}
]
}
],
"org_iiban": "ABCD EFGH IJKL MNOP",
"duration_seconds": 86400
}
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({
instructions: [
{
type: 'update_subquorum',
version: 123,
vault_id: '<string>',
groups: [{required: 123, members: ['<string>'], id: '<string>'}]
}
],
org_iiban: 'ABCD EFGH IJKL MNOP',
duration_seconds: 86400
})
};
fetch('https://api.kraken.com/v0/insto/custody/tasks', 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"
payload := strings.NewReader("{\n \"instructions\": [\n {\n \"type\": \"update_subquorum\",\n \"version\": 123,\n \"vault_id\": \"<string>\",\n \"groups\": [\n {\n \"required\": 123,\n \"members\": [\n \"<string>\"\n ],\n \"id\": \"<string>\"\n }\n ]\n }\n ],\n \"org_iiban\": \"ABCD EFGH IJKL MNOP\",\n \"duration_seconds\": 86400\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))
}{
"id": "550e8400-e29b-41d4-a716-446655440000"
}{
"type": "tag:kraken.com,2025:BadRequest",
"status": 400,
"title": "Bad Request",
"data": {
"message": "instructions must not be empty"
},
"detail": "Request failed validation: instructions must not be empty.",
"instance": "https://debug.kraken.com/req/01HXYZABCDEF"
}{
"type": "tag:kraken.com,2025:PermissionDenied",
"status": 403,
"title": "Forbidden",
"data": {
"message": "api key lacks access to the requested vault"
},
"detail": "Caller lacks access to the requested vault or organization.",
"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
Body
The atomic instructions to bundle into the task. Each entry describes a single change and is one of the variants below, identified by its type field.
A single atomic instruction. The type field selects the variant and determines which other fields are required.
- update_subquorum
- update_vault_user
- update_vault_policy
- request_withdrawal
- remove_org_user
- update_withdrawal_address
- request_transfer_to_spot
Show child attributes
Show child attributes
Organization IIBAN the task is created under.
"ABCD EFGH IJKL MNOP"
Optional task expiry, in seconds from creation.
86400
Response
Task created successfully. The instructions take effect asynchronously once the task is approved.
Task identifier, an approval UUID (UUID v4). T-prefixed identifiers are not returned. Responses always emit lowercase. Requests accept any letter case.
"550e8400-e29b-41d4-a716-446655440000"
Was this page helpful?