> ## Documentation Index
> Fetch the complete documentation index at: https://docs.brickken.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Tokenize an asset and run an STO

> The full Dapp API lifecycle, from creating a token to distributing dividends.

Every step below is the same three moves: **prepare** an unsigned transaction, **sign** it with your whitelisted wallet, **send** it. The examples target Sepolia (`aa36a7`) on sandbox, so nothing here moves real value.

## Before you start

<Steps>
  <Step title="Get an API key">
    [Request one](/get-started/request-api-key). Every call below needs `x-api-key`.
  </Step>

  <Step title="Get your signer whitelisted">
    Brickken must whitelist the wallet you pass as `signerAddress` before any prepare call accepts it. Ask for it in the same request as the key.
  </Step>

  <Step title="Fund that wallet with native gas">
    You broadcast the transactions, so the signer pays the gas — Sepolia ETH here.
  </Step>
</Steps>

<Note>
  The wallet that performs the first `newTokenization` becomes the **tokenizer** for that token. Only the tokenizer can mint it, whitelist its investors, or distribute its dividends. Transfers and burns can come from any wallet. Your API key is also scoped to the symbols it tokenized — anything else returns `Unauthorized token symbol`.
</Note>

## The sign-and-send loop

You will repeat this after every prepare, so it is worth writing once. Prepare returns `{ txId, transactions }`:

```bash theme={null}
curl --request POST 'https://api.sandbox.brickken.com/send-transactions' \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: YOUR_BRICKKEN_API_KEY' \
  --data '{
    "txId": "0xPreparedTransactionId",
    "signedTransactions": ["0xSignedRawTransaction"]
  }'
```

Signing, with ethers:

```ts theme={null}
import { Wallet } from "ethers";

const wallet = new Wallet(process.env.PRIVATE_KEY!);
const signedTransactions = await Promise.all(
  prepared.transactions.map((tx) => wallet.signTransaction(tx))
);
```

Then poll until it confirms:

```bash theme={null}
curl 'https://api.sandbox.brickken.com/get-transaction-status?txId=0xPreparedTransactionId' \
  --header 'x-api-key: YOUR_BRICKKEN_API_KEY'
```

`pending` means broadcast but not yet mined. Do not resubmit — you would pay gas twice.

<Tip>
  **Already run your own broadcasting?** Add `"executionMode": "client-broadcast"` to any prepare below, submit the signed transaction to the chain yourself, then confirm with `{ txId, txHash }` instead of `{ txId, signedTransactions }`. Brickken reconciles your hash so the transaction still appears in `get-transaction-status` and in the dApp. See [Send Transactions](/api-reference/endpoint/send).
</Tip>

## 1. Create the tokenized asset

```bash theme={null}
curl --request POST 'https://api.sandbox.brickken.com/prepare-transactions/newTokenization' \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: YOUR_BRICKKEN_API_KEY' \
  --data '{
    "method": "newTokenization",
    "signerAddress": "0xYourWhitelistedWallet",
    "chainId": "aa36a7",
    "tokenizerEmail": "issuer@example.com",
    "name": "Example Asset",
    "tokenSymbol": "EXMPL",
    "tokenType": "EQUITY",
    "supplyCap": "1000000",
    "url": "https://example.com/token-docs"
  }'
```

The field is `name`, not `tokenName`. `tokenType` accepts `EQUITY`, `DEBT`, `BILL_FACTORING`, `ICO`, `STABLECOIN`, `REVENUE_SHARE`, `RWA_TOKEN`, or `PROFIT_SHARING`, and defaults to `EQUITY`. `supplyCap` defaults to `0`, which means uncapped — set it deliberately.

Sign and send, then confirm the token exists:

```bash theme={null}
curl 'https://api.sandbox.brickken.com/get-token-info?chainId=aa36a7&tokenSymbol=EXMPL' \
  --header 'x-api-key: YOUR_BRICKKEN_API_KEY'
```

Every field, with the request and response schema, is on the [`newTokenization` reference](/api-reference/endpoint/prepare-newTokenization).

## 2. Whitelist your investors

A security token only moves between whitelisted wallets. Whitelist before you mint or accept investment.

```bash theme={null}
curl --request POST 'https://api.sandbox.brickken.com/prepare-transactions/whitelist' \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: YOUR_BRICKKEN_API_KEY' \
  --data '{
    "method": "whitelist",
    "signerAddress": "0xYourWhitelistedWallet",
    "chainId": "aa36a7",
    "tokenSymbol": "EXMPL",
    "userToWhitelist": [
      {
        "investorAddress": "0x1111111111111111111111111111111111111111",
        "investorEmail": "investor@example.com",
        "whitelistStatus": true
      }
    ]
  }'
```

`whitelistStatus: false` removes an investor. Verify with [`GET /get-whitelist-status`](/api-reference/endpoint/get-whitelist-status).

## 3. Mint tokens

```bash theme={null}
curl --request POST 'https://api.sandbox.brickken.com/prepare-transactions/mintToken' \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: YOUR_BRICKKEN_API_KEY' \
  --data '{
    "method": "mintToken",
    "signerAddress": "0xYourWhitelistedWallet",
    "chainId": "aa36a7",
    "tokenSymbol": "EXMPL",
    "userToMint": [
      {
        "investorEmail": "investor@example.com",
        "investorAddress": "0x1111111111111111111111111111111111111111",
        "amount": "100",
        "needWhitelist": true
      }
    ]
  }'
```

`needWhitelist: true` whitelists the recipient as part of the same mint, which collapses step 2 into step 3 when you are onboarding a new investor.

## 4. Launch the offering

```bash theme={null}
curl --request POST 'https://api.sandbox.brickken.com/prepare-transactions/newSto' \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: YOUR_BRICKKEN_API_KEY' \
  --data '{
    "method": "newSto",
    "signerAddress": "0xYourWhitelistedWallet",
    "chainId": "aa36a7",
    "tokenizerEmail": "issuer@example.com",
    "tokenSymbol": "EXMPL",
    "tokenAmount": "1000",
    "offeringName": "Series A",
    "startDate": "2026-09-01T00:00:00.000Z",
    "endDate": "2026-12-31T23:59:59.000Z",
    "acceptedCoin": "USDT",
    "minRaiseUSD": "10000",
    "maxRaiseUSD": "100000",
    "minInvestment": "100",
    "maxInvestment": "10000"
  }'
```

Every one of those fields is required. Dates are ISO 8601. `acceptedCoin` is a payment token symbol — `USDT`, `USDC`, or `BKN`.

Once it is live, list your offerings and keep the `uuid`:

```bash theme={null}
curl 'https://api.sandbox.brickken.com/get-stos?chainId=aa36a7&tokenSymbol=EXMPL' \
  --header 'x-api-key: YOUR_BRICKKEN_API_KEY'
```

## 5. Take an investment

Note there is no `signerAddress` in the required set — the **investor** signs this one, not the tokenizer.

```bash theme={null}
curl --request POST 'https://api.sandbox.brickken.com/prepare-transactions/newInvest' \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: YOUR_BRICKKEN_API_KEY' \
  --data '{
    "method": "newInvest",
    "chainId": "aa36a7",
    "tokenSymbol": "EXMPL",
    "investorEmail": "investor@example.com",
    "investorAddress": "0x1111111111111111111111111111111111111111",
    "investmentAmount": "1000",
    "paymentTokenSymbol": "USDT"
  }'
```

The investor needs the payment token in their wallet, and the prepare response may contain **two** transactions — an ERC-20 `approve` followed by the investment. Sign and send both, in order.

Track progress with [`GET /get-investments-by-sto-id`](/api-reference/endpoint/get-investments-by-sto) and [`GET /get-sto-balance`](/api-reference/endpoint/get-sto-balance).

## 6. Let investors claim their tokens

```bash theme={null}
curl --request POST 'https://api.sandbox.brickken.com/prepare-transactions/claimTokens' \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: YOUR_BRICKKEN_API_KEY' \
  --data '{
    "method": "claimTokens",
    "chainId": "aa36a7",
    "tokenSymbol": "EXMPL",
    "investorEmail": "investor@example.com",
    "investorAddress": "0x1111111111111111111111111111111111111111"
  }'
```

The investor signs this too.

## 7. Close the offering

```bash theme={null}
curl --request POST 'https://api.sandbox.brickken.com/prepare-transactions/closeOffer' \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: YOUR_BRICKKEN_API_KEY' \
  --data '{
    "method": "closeOffer",
    "signerAddress": "0xYourWhitelistedWallet",
    "chainId": "aa36a7",
    "tokenSymbol": "EXMPL",
    "tokenizerEmail": "issuer@example.com"
  }'
```

## 8. Distribute dividends

```bash theme={null}
curl --request POST 'https://api.sandbox.brickken.com/prepare-transactions/dividendDistribution' \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: YOUR_BRICKKEN_API_KEY' \
  --data '{
    "method": "dividendDistribution",
    "signerAddress": "0xYourWhitelistedWallet",
    "chainId": "aa36a7",
    "tokenSymbol": "EXMPL",
    "amount": "1000"
  }'
```

Only the tokenizer can do this. Read the result with [`GET /get-dividend-distribution`](/api-reference/endpoint/get-dividend-distribution).

## When something fails

| Response                             | What it means                                                          |
| ------------------------------------ | ---------------------------------------------------------------------- |
| `401` / `400 API key is missing`     | No `x-api-key`, or this endpoint needs one and did not get it          |
| `Unauthorized token symbol`          | Your key did not tokenize that symbol                                  |
| `Out of credits for <method>`        | Your plan's balance for that specific method is exhausted              |
| `429` + `Retry-After: 60`            | Rate limited on `prepare-transactions`                                 |
| Prepare rejects your `signerAddress` | The wallet is not whitelisted yet                                      |
| Send reverts on-chain                | Usually an unwhitelisted recipient, an unapproved allowance, or no gas |

Each write method has its own credit balance, so exhausting `mintCredits` does not block `newSto`. See [Authentication](/get-started/authentication) for plans, scoping, and the full error reference.

## Doing this without writing HTTP

<CardGroup cols={2}>
  <Card title="MCP server" icon="plug" href="/mcp/introduction">
    The same lifecycle as agent tools — `create_tokenization`, `create_sto`, `mint_tokens` — driven by an AI agent with just your API key.
  </Card>

  <Card title="Postman collection" icon="download" href="/api-reference/postman">
    Every request above, ready to run.
  </Card>
</CardGroup>
