curl --request POST \
--url https://api.sandbox.brickken.com/prepare-transactions \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"method": "closeOffer",
"chainId": "aa36a7",
"signerAddress": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
"tokenizerEmail": "tokenizer@example.com",
"tokenSymbol": "EXMPL"
}
'import requests
url = "https://api.sandbox.brickken.com/prepare-transactions"
payload = {
"method": "closeOffer",
"chainId": "aa36a7",
"signerAddress": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
"tokenizerEmail": "tokenizer@example.com",
"tokenSymbol": "EXMPL"
}
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: 'closeOffer',
chainId: 'aa36a7',
signerAddress: '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
tokenizerEmail: 'tokenizer@example.com',
tokenSymbol: 'EXMPL'
})
};
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' => 'closeOffer',
'chainId' => 'aa36a7',
'signerAddress' => '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
'tokenizerEmail' => 'tokenizer@example.com',
'tokenSymbol' => 'EXMPL'
]),
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\": \"closeOffer\",\n \"chainId\": \"aa36a7\",\n \"signerAddress\": \"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\",\n \"tokenizerEmail\": \"tokenizer@example.com\",\n \"tokenSymbol\": \"EXMPL\"\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\": \"closeOffer\",\n \"chainId\": \"aa36a7\",\n \"signerAddress\": \"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\",\n \"tokenizerEmail\": \"tokenizer@example.com\",\n \"tokenSymbol\": \"EXMPL\"\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\": \"closeOffer\",\n \"chainId\": \"aa36a7\",\n \"signerAddress\": \"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\",\n \"tokenizerEmail\": \"tokenizer@example.com\",\n \"tokenSymbol\": \"EXMPL\"\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"
}
}closeOffer
Finalize an offering after its end date, releasing the raise or entering rollback.
curl --request POST \
--url https://api.sandbox.brickken.com/prepare-transactions \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"method": "closeOffer",
"chainId": "aa36a7",
"signerAddress": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
"tokenizerEmail": "tokenizer@example.com",
"tokenSymbol": "EXMPL"
}
'import requests
url = "https://api.sandbox.brickken.com/prepare-transactions"
payload = {
"method": "closeOffer",
"chainId": "aa36a7",
"signerAddress": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
"tokenizerEmail": "tokenizer@example.com",
"tokenSymbol": "EXMPL"
}
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: 'closeOffer',
chainId: 'aa36a7',
signerAddress: '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
tokenizerEmail: 'tokenizer@example.com',
tokenSymbol: 'EXMPL'
})
};
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' => 'closeOffer',
'chainId' => 'aa36a7',
'signerAddress' => '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
'tokenizerEmail' => 'tokenizer@example.com',
'tokenSymbol' => 'EXMPL'
]),
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\": \"closeOffer\",\n \"chainId\": \"aa36a7\",\n \"signerAddress\": \"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\",\n \"tokenizerEmail\": \"tokenizer@example.com\",\n \"tokenSymbol\": \"EXMPL\"\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\": \"closeOffer\",\n \"chainId\": \"aa36a7\",\n \"signerAddress\": \"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\",\n \"tokenizerEmail\": \"tokenizer@example.com\",\n \"tokenSymbol\": \"EXMPL\"\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\": \"closeOffer\",\n \"chainId\": \"aa36a7\",\n \"signerAddress\": \"0x742d35Cc6634C0532925a3b844Bc454e4438f44e\",\n \"tokenizerEmail\": \"tokenizer@example.com\",\n \"tokenSymbol\": \"EXMPL\"\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=closeOffer.
Finalizing is what unlocks claimTokens: until it runs, investors can neither receive their tokens nor be refunded.
The end date has to have passed
endDate has not yet passed — returning
0xffac9d14 IssuanceNotEnded(address,uint256). There is no administrative or time override,
in Sandbox or in production.endDate so you can exercise close and claim quickly.
Success or rollback
What finalization does depends on whether the raise reachedminRaiseUSD, the offering’s soft cap:
| Outcome | Condition | Effect |
|---|---|---|
| Successful | Amount raised reached the soft cap | The raise is withdrawn to the issuer, and investors can claim their tokens |
| Rollback | Amount raised fell short of the soft cap | Investors are refunded their payment token instead of receiving tokens |
claimTokens then refunds. To demonstrate a
successful claim, size the soft cap so the offering can actually reach it.Notes
- Only the issuer of the offering can close it.
- Existing investments remain valid throughout; nothing is lost by waiting for the window to end.
- Finalization is irreversible once the transaction is confirmed.
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 closeOffer for this endpoint.
closeOffer "closeOffer"
Required. Blockchain network identifier. Hex format is recommended, for example Sepolia aa36a7.
"aa36a7"
Required. Tokenizer wallet that signs the closure. On V2 tokens it also receives the withdrawn funds.
"0x742d35Cc6634C0532925a3b844Bc454e4438f44e"
Required. Email of the tokenizer that owns the offering.
"tokenizer@example.com"
Required. Symbol of the token whose ongoing offering is closed.
"EXMPL"
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