curl --request POST \
--url https://api.sandbox.brickken.com/prepare-transactions \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"method": "whitelist",
"chainId": "aa36a7",
"signerAddress": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
"tokenSymbol": "EXMPL",
"userToWhitelist": [
{
"investorAddress": "0x1111111111111111111111111111111111111111",
"investorEmail": "investor@example.com",
"whitelistStatus": true
}
]
}
'import requests
url = "https://api.sandbox.brickken.com/prepare-transactions"
payload = {
"method": "whitelist",
"chainId": "aa36a7",
"signerAddress": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
"tokenSymbol": "EXMPL",
"userToWhitelist": [
{
"investorAddress": "0x1111111111111111111111111111111111111111",
"investorEmail": "investor@example.com",
"whitelistStatus": True
}
]
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
method: 'whitelist',
chainId: 'aa36a7',
signerAddress: '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
tokenSymbol: 'EXMPL',
userToWhitelist: [
{
investorAddress: '0x1111111111111111111111111111111111111111',
investorEmail: 'investor@example.com',
whitelistStatus: true
}
]
})
};
fetch('https://api.sandbox.brickken.com/prepare-transactions', 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.sandbox.brickken.com/prepare-transactions",
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([
'method' => 'whitelist',
'chainId' => 'aa36a7',
'signerAddress' => '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
'tokenSymbol' => 'EXMPL',
'userToWhitelist' => [
[
'investorAddress' => '0x1111111111111111111111111111111111111111',
'investorEmail' => 'investor@example.com',
'whitelistStatus' => true
]
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <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://api.sandbox.brickken.com/prepare-transactions"
payload := strings.NewReader("{\n \"method\": \"whitelist\",\n \"chainId\": \"aa36a7\",\n \"signerAddress\": \"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\",\n \"tokenSymbol\": \"EXMPL\",\n \"userToWhitelist\": [\n {\n \"investorAddress\": \"0x1111111111111111111111111111111111111111\",\n \"investorEmail\": \"investor@example.com\",\n \"whitelistStatus\": true\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<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://api.sandbox.brickken.com/prepare-transactions")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"method\": \"whitelist\",\n \"chainId\": \"aa36a7\",\n \"signerAddress\": \"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\",\n \"tokenSymbol\": \"EXMPL\",\n \"userToWhitelist\": [\n {\n \"investorAddress\": \"0x1111111111111111111111111111111111111111\",\n \"investorEmail\": \"investor@example.com\",\n \"whitelistStatus\": true\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sandbox.brickken.com/prepare-transactions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"method\": \"whitelist\",\n \"chainId\": \"aa36a7\",\n \"signerAddress\": \"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\",\n \"tokenSymbol\": \"EXMPL\",\n \"userToWhitelist\": [\n {\n \"investorAddress\": \"0x1111111111111111111111111111111111111111\",\n \"investorEmail\": \"investor@example.com\",\n \"whitelistStatus\": true\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"transactions": [
{
"from": "0x1234567890abcdef1234567890abcdef12345678",
"to": "0xabcdef1234567890abcdef1234567890abcdef12",
"value": "0x00",
"nonce": 3792,
"chainId": 11155111,
"data": "0xd362e8a70000000000000000000000000000000000000000000000000000000000000040...",
"type": 2,
"maxPriorityFeePerGas": "1150000",
"maxFeePerGas": "1156037",
"gasLimit": "0xccef"
}
],
"txId": "0x46adea7bdf49c576a760102e0d6bc9ecd650b3998588cd3d7f576a7973426aad",
"info": {
"tokenizerEmail": "tokenizer@example.com",
"tokenSymbol": "EXMPL",
"investorEmail": "investor@example.com"
}
}whitelist
Authorize a wallet to hold a token, creating the investor record if it does not exist.
curl --request POST \
--url https://api.sandbox.brickken.com/prepare-transactions \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"method": "whitelist",
"chainId": "aa36a7",
"signerAddress": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
"tokenSymbol": "EXMPL",
"userToWhitelist": [
{
"investorAddress": "0x1111111111111111111111111111111111111111",
"investorEmail": "investor@example.com",
"whitelistStatus": true
}
]
}
'import requests
url = "https://api.sandbox.brickken.com/prepare-transactions"
payload = {
"method": "whitelist",
"chainId": "aa36a7",
"signerAddress": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
"tokenSymbol": "EXMPL",
"userToWhitelist": [
{
"investorAddress": "0x1111111111111111111111111111111111111111",
"investorEmail": "investor@example.com",
"whitelistStatus": True
}
]
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
method: 'whitelist',
chainId: 'aa36a7',
signerAddress: '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
tokenSymbol: 'EXMPL',
userToWhitelist: [
{
investorAddress: '0x1111111111111111111111111111111111111111',
investorEmail: 'investor@example.com',
whitelistStatus: true
}
]
})
};
fetch('https://api.sandbox.brickken.com/prepare-transactions', 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.sandbox.brickken.com/prepare-transactions",
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([
'method' => 'whitelist',
'chainId' => 'aa36a7',
'signerAddress' => '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
'tokenSymbol' => 'EXMPL',
'userToWhitelist' => [
[
'investorAddress' => '0x1111111111111111111111111111111111111111',
'investorEmail' => 'investor@example.com',
'whitelistStatus' => true
]
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <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://api.sandbox.brickken.com/prepare-transactions"
payload := strings.NewReader("{\n \"method\": \"whitelist\",\n \"chainId\": \"aa36a7\",\n \"signerAddress\": \"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\",\n \"tokenSymbol\": \"EXMPL\",\n \"userToWhitelist\": [\n {\n \"investorAddress\": \"0x1111111111111111111111111111111111111111\",\n \"investorEmail\": \"investor@example.com\",\n \"whitelistStatus\": true\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<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://api.sandbox.brickken.com/prepare-transactions")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"method\": \"whitelist\",\n \"chainId\": \"aa36a7\",\n \"signerAddress\": \"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\",\n \"tokenSymbol\": \"EXMPL\",\n \"userToWhitelist\": [\n {\n \"investorAddress\": \"0x1111111111111111111111111111111111111111\",\n \"investorEmail\": \"investor@example.com\",\n \"whitelistStatus\": true\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sandbox.brickken.com/prepare-transactions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"method\": \"whitelist\",\n \"chainId\": \"aa36a7\",\n \"signerAddress\": \"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\",\n \"tokenSymbol\": \"EXMPL\",\n \"userToWhitelist\": [\n {\n \"investorAddress\": \"0x1111111111111111111111111111111111111111\",\n \"investorEmail\": \"investor@example.com\",\n \"whitelistStatus\": true\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"transactions": [
{
"from": "0x1234567890abcdef1234567890abcdef12345678",
"to": "0xabcdef1234567890abcdef1234567890abcdef12",
"value": "0x00",
"nonce": 3792,
"chainId": 11155111,
"data": "0xd362e8a70000000000000000000000000000000000000000000000000000000000000040...",
"type": 2,
"maxPriorityFeePerGas": "1150000",
"maxFeePerGas": "1156037",
"gasLimit": "0xccef"
}
],
"txId": "0x46adea7bdf49c576a760102e0d6bc9ecd650b3998588cd3d7f576a7973426aad",
"info": {
"tokenizerEmail": "tokenizer@example.com",
"tokenSymbol": "EXMPL",
"investorEmail": "investor@example.com"
}
}POST /prepare-transactions with method=whitelist.
Whitelisting is an on-chain, per-token permission. A wallet must be whitelisted before it can hold or receive that token, which makes this the standalone step to run before a transfer, a resale, or an investment — no minting required.
Fields
tokenSymbol, signerAddress (the tokenizer wallet), and userToWhitelist are required. Each entry
in userToWhitelist needs:
| Field | Required | Notes |
|---|---|---|
investorAddress | yes | The wallet being authorized |
investorEmail | yes | The identity the wallet is attached to |
whitelistStatus | yes | true to whitelist, false to blacklist |
needKyc | no | Defaults to true. false creates the investor with no KYC requirement, and is accepted in Sandbox only |
needKyc: false and skip identity verification entirely. The KYC flow
is a Sumsub verification with document upload, not something you need to prove your integration
works, and every test investor you create without it is one less manual step in your loop.Rehearse the real KYC flow once before you go live, since needKyc: false is rejected in
production with needKyc=false is only available in the sandbox environment.newInvestor object supplies profile defaults used when a record has to be created:
name, surname, middleName, secondSurname, and type (defaults to INVESTOR_PERSON).
{
"method": "whitelist",
"chainId": "aa36a7",
"signerAddress": "0x<tokenizer wallet>",
"tokenSymbol": "EXMPL",
"userToWhitelist": [
{
"investorAddress": "0x<investor wallet>",
"investorEmail": "investor@example.com",
"whitelistStatus": true,
"needKyc": false
}
],
"newInvestor": { "name": "Jane", "surname": "Doe", "type": "INVESTOR_PERSON" }
}
The investor record
The investor record is created during the prepare call, not when the transaction is mined. Two consequences matter:GET /get-balance-whitelist and newInvest both go on reporting Investor not found.Give every test investor its own email, separate from the account you issue with. In a real flow
the issuer and the investor are different parties anyway.investorAddress you pass to that record. An investor whose stored wallet differs from the one you
send is rejected with Investor <email> is already associated with a different wallet address — a
wallet address is set once and is not silently replaced.
Preparing is not sending
Preparing a whitelist only returns an unsigned transaction. The signed transaction must also be submitted, confirmed on-chain, and processed by the backend before the wallet counts as whitelisted. Verify the on-chain result before relying on it:curl --request GET \
--url 'https://api.sandbox.brickken.com/get-whitelist-status?tokenSymbol=EXMPL&address=0x<investor wallet>' \
--header 'x-api-key: YOUR_API_KEY'
Next step
Preparing does not touch the chain. The response gives youtxId and an array of unsigned transactions — you still have to sign and submit them.
Sign every returned transaction
signerAddress, or investorAddress for newInvest and claimTokens. It must be whitelisted by Brickken, and it needs native gas on the target chain.Submit the signed payloads
POST them to /send-transactions as { txId, signedTransactions } and Brickken broadcasts for you.If you would rather broadcast yourself, prepare with executionMode: "client-broadcast" and confirm afterwards with { txId, txHash } instead.Poll until it confirms
GET /get-transaction-status with the txId. A pending status means it is broadcast but not yet mined — do not resubmit.Authorizations
Body
Required. Operation to prepare. Must be whitelist for this endpoint.
whitelist "whitelist"
Required. Blockchain network identifier. Hex format is recommended, for example Sepolia aa36a7.
"aa36a7"
Required. Tokenizer wallet that signs the whitelist transaction.
"0x742d35Cc6634C0532925a3b844Bc454e4438f44e"
Required. Symbol of the token whose whitelist is updated.
"EXMPL"
Required. Users to whitelist or blacklist.
1Show child attributes
Show child attributes
[
{
"investorAddress": "0x1111111111111111111111111111111111111111",
"investorEmail": "investor@example.com",
"whitelistStatus": true
}
]
Optional. Default profile data used when creating missing investor users.
Show child attributes
Show child attributes
Response
Successful response
Array of unsigned transaction objects ready for signing
Show child attributes
Show child attributes
Unique identifier for this transaction batch (required for /send-transactions). This is NOT a blockchain transaction hash.
"0x46adea7bdf49c576a760102e0d6bc9ecd650b3998588cd3d7f576a7973426aad"
Metadata about the operation
Show child attributes
Show child attributes