curl --request POST \
--url https://calibri.io/api/v2/atlas/account/wallet/owners \
--header 'Content-Type: application/json' \
--header 'X-Auth-Apikey: <api-key>' \
--data '
{
"owner": "0x1631794cb5841002a7feaf0cc064a228c0db8e94",
"otp": "123456",
"remove": false
}
'import requests
url = "https://calibri.io/api/v2/atlas/account/wallet/owners"
payload = {
"owner": "0x1631794cb5841002a7feaf0cc064a228c0db8e94",
"otp": "123456",
"remove": False
}
headers = {
"X-Auth-Apikey": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-Auth-Apikey': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
owner: '0x1631794cb5841002a7feaf0cc064a228c0db8e94',
otp: '123456',
remove: false
})
};
fetch('https://calibri.io/api/v2/atlas/account/wallet/owners', 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://calibri.io/api/v2/atlas/account/wallet/owners",
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([
'owner' => '0x1631794cb5841002a7feaf0cc064a228c0db8e94',
'otp' => '123456',
'remove' => false
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Auth-Apikey: <api-key>"
],
]);
$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://calibri.io/api/v2/atlas/account/wallet/owners"
payload := strings.NewReader("{\n \"owner\": \"0x1631794cb5841002a7feaf0cc064a228c0db8e94\",\n \"otp\": \"123456\",\n \"remove\": false\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Auth-Apikey", "<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))
}HttpResponse<String> response = Unirest.post("https://calibri.io/api/v2/atlas/account/wallet/owners")
.header("X-Auth-Apikey", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"owner\": \"0x1631794cb5841002a7feaf0cc064a228c0db8e94\",\n \"otp\": \"123456\",\n \"remove\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://calibri.io/api/v2/atlas/account/wallet/owners")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Auth-Apikey"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"owner\": \"0x1631794cb5841002a7feaf0cc064a228c0db8e94\",\n \"otp\": \"123456\",\n \"remove\": false\n}"
response = http.request(request)
puts response.read_body{
"calls": [
{
"data": "0x095ea7b3…",
"hash": "0x9ab1…",
"nonce": 4,
"operation": 0,
"to": "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359"
}
],
"owners": [
"<string>"
],
"safe": "0x2b01…E22a"
}Add or remove a signing key on your wallet
Returns the Safe call authorising another address to sign for your wallet (or removing one, with remove: true). Sign it with your passkey and relay it — nothing changes until you do. An added key is a full owner: it can place orders, withdraw, redeem, and remove your passkey. Adding a key you already added returns no calls.
curl --request POST \
--url https://calibri.io/api/v2/atlas/account/wallet/owners \
--header 'Content-Type: application/json' \
--header 'X-Auth-Apikey: <api-key>' \
--data '
{
"owner": "0x1631794cb5841002a7feaf0cc064a228c0db8e94",
"otp": "123456",
"remove": false
}
'import requests
url = "https://calibri.io/api/v2/atlas/account/wallet/owners"
payload = {
"owner": "0x1631794cb5841002a7feaf0cc064a228c0db8e94",
"otp": "123456",
"remove": False
}
headers = {
"X-Auth-Apikey": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-Auth-Apikey': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
owner: '0x1631794cb5841002a7feaf0cc064a228c0db8e94',
otp: '123456',
remove: false
})
};
fetch('https://calibri.io/api/v2/atlas/account/wallet/owners', 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://calibri.io/api/v2/atlas/account/wallet/owners",
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([
'owner' => '0x1631794cb5841002a7feaf0cc064a228c0db8e94',
'otp' => '123456',
'remove' => false
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Auth-Apikey: <api-key>"
],
]);
$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://calibri.io/api/v2/atlas/account/wallet/owners"
payload := strings.NewReader("{\n \"owner\": \"0x1631794cb5841002a7feaf0cc064a228c0db8e94\",\n \"otp\": \"123456\",\n \"remove\": false\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Auth-Apikey", "<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))
}HttpResponse<String> response = Unirest.post("https://calibri.io/api/v2/atlas/account/wallet/owners")
.header("X-Auth-Apikey", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"owner\": \"0x1631794cb5841002a7feaf0cc064a228c0db8e94\",\n \"otp\": \"123456\",\n \"remove\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://calibri.io/api/v2/atlas/account/wallet/owners")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Auth-Apikey"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"owner\": \"0x1631794cb5841002a7feaf0cc064a228c0db8e94\",\n \"otp\": \"123456\",\n \"remove\": false\n}"
response = http.request(request)
puts response.read_body{
"calls": [
{
"data": "0x095ea7b3…",
"hash": "0x9ab1…",
"nonce": 4,
"operation": 0,
"to": "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359"
}
],
"owners": [
"<string>"
],
"safe": "0x2b01…E22a"
}Authorizations
HMAC-signed API key. Send X-Auth-Apikey, X-Auth-Nonce and X-Auth-Signature.
Body
The address to authorise (or, with remove, to revoke).
"0x1631794cb5841002a7feaf0cc064a228c0db8e94"
Your six-digit two-factor code. REQUIRED when adding a key — a key that can withdraw and replace your passkey is not something a hijacked session should be able to grant. Not needed to remove one.
"123456"
Set to remove this key instead of adding it. Your own passkey cannot be removed this way.
false
Response
The Safe call(s) to sign with your passkey and relay. EMPTY when the request is already satisfied — adding an address that already signs for the wallet changes nothing.
Show child attributes
Show child attributes
The owner set as it stands, before this change.
Your wallet (Safe) address.
"0x2b01…E22a"