curl --request POST \
--url https://staging.apimonaco.xyz/api/v1/sweeper/register \
--header 'Content-Type: application/json' \
--header 'X-Monaco-Signature: <api-key>' \
--data '
{
"depositTarget": "MARGIN"
}
'import requests
url = "https://staging.apimonaco.xyz/api/v1/sweeper/register"
payload = { "depositTarget": "MARGIN" }
headers = {
"X-Monaco-Signature": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-Monaco-Signature': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({depositTarget: 'MARGIN'})
};
fetch('https://staging.apimonaco.xyz/api/v1/sweeper/register', 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://staging.apimonaco.xyz/api/v1/sweeper/register",
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([
'depositTarget' => 'MARGIN'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Monaco-Signature: <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://staging.apimonaco.xyz/api/v1/sweeper/register"
payload := strings.NewReader("{\n \"depositTarget\": \"MARGIN\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Monaco-Signature", "<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://staging.apimonaco.xyz/api/v1/sweeper/register")
.header("X-Monaco-Signature", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"depositTarget\": \"MARGIN\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://staging.apimonaco.xyz/api/v1/sweeper/register")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Monaco-Signature"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"depositTarget\": \"MARGIN\"\n}"
response = http.request(request)
puts response.read_body{
"status": "registered",
"sweeperAddress": "0xcf1eF339798914EF7Ee4984Ed45BD141D63a65C9",
"initialSweepCheck": false
}Register a deposit address for monitoring
Register a deposit address for monitoring.
Every (application, user, deposit target) triple has a deterministic
deposit address — the SAME address on every supported chain. This
registers the caller’s own address so the sweeper service watches it on
every chain it is configured for (get_sweeper_chains lists the set) and
automatically forwards every supported deposit into the exchange,
crediting the caller under the application. One registration covers all
supported chains — there is nothing chain-specific to choose.
Authenticated, and the whole identity comes from the session: the
application is the one login established the session under, and the
credited address is the session’s own. Neither is a request parameter, so a
caller can only ever register their own address under their own
application. The body carries only which ledger to aim at.
Registration also runs a one-time initial check in the background: any balance already sitting on the address, on any supported chain, is swept without waiting for a new transfer. The response returns immediately with the derived address; it does not wait for that check.
Idempotent and safe to retry: re-registering an existing triple returns
already_registered with the same address and never re-triggers the
initial check.
Globally rate-limited: registration creates durable state, so the endpoint
admits a bounded number per minute across all callers and answers 429
beyond it.
curl --request POST \
--url https://staging.apimonaco.xyz/api/v1/sweeper/register \
--header 'Content-Type: application/json' \
--header 'X-Monaco-Signature: <api-key>' \
--data '
{
"depositTarget": "MARGIN"
}
'import requests
url = "https://staging.apimonaco.xyz/api/v1/sweeper/register"
payload = { "depositTarget": "MARGIN" }
headers = {
"X-Monaco-Signature": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-Monaco-Signature': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({depositTarget: 'MARGIN'})
};
fetch('https://staging.apimonaco.xyz/api/v1/sweeper/register', 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://staging.apimonaco.xyz/api/v1/sweeper/register",
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([
'depositTarget' => 'MARGIN'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Monaco-Signature: <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://staging.apimonaco.xyz/api/v1/sweeper/register"
payload := strings.NewReader("{\n \"depositTarget\": \"MARGIN\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Monaco-Signature", "<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://staging.apimonaco.xyz/api/v1/sweeper/register")
.header("X-Monaco-Signature", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"depositTarget\": \"MARGIN\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://staging.apimonaco.xyz/api/v1/sweeper/register")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Monaco-Signature"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"depositTarget\": \"MARGIN\"\n}"
response = http.request(request)
puts response.read_body{
"status": "registered",
"sweeperAddress": "0xcf1eF339798914EF7Ee4984Ed45BD141D63a65C9",
"initialSweepCheck": false
}Authorizations
Ed25519 session-key request signing. Every authenticated request carries three headers: X-Monaco-PublicKey (64-char lowercase-hex session public key), X-Monaco-Timestamp (Unix milliseconds, within 30s of server time), and X-Monaco-Signature (hex ed25519 signature). The signature is over METHOD\npath?query\ntimestamp_ms\nSHA256_hex(body), where the body hash is the SHA-256 of the empty byte string when there is no body. Obtain the session keypair from POST /api/v1/auth/challenge followed by POST /api/v1/auth/verify.
Body
Which ledger swept deposits are requested to be credited to. SPOT (the default when omitted) credits the spot wallet; MARGIN asks for the parent margin account's collateral, skipping the separate collateral transfer. The target is part of the address derivation, so SPOT and MARGIN yield two different deposit addresses for the same pair, and each address carries its own request. MARGIN is a routing request rather than a guarantee: a deposit the matching engine cannot route to collateral — an unsupported collateral asset, or a margin account that fails validation — is credited to the spot wallet instead, so funds are never stranded. A SPOT address is never credited to margin.
SPOT, MARGIN "MARGIN"
Response
OK
registered when the triple was added, already_registered when it was known before this call
registered, already_registered "registered"
The deposit address for this (application, user, deposit target) triple. Stable, and valid to publish and fund before any contract exists there.
"0xcf1eF339798914EF7Ee4984Ed45BD141D63a65C9"
Whether the one-time registration balance check has completed. false right after a fresh registration; it runs in the background and flips once every pre-existing balance has been swept.
false
Was this page helpful?

