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

# Register on Aster

> Register a VOOI-managed agent on Aster to trade through the VOOI API

Registration authorizes a VOOI-managed agent on Aster to trade on your behalf. Your funds remain in your own Aster account. The agent can read account data and place spot and perpetual orders; it cannot withdraw.

<Info>
  This guide assumes that you already have an active VOOI API token. See [API Tokens](/docs/tokens) for how to obtain one.
</Info>

## Do you need to register?

Check whether your VOOI account already has Aster credentials via [`GET /user-exchange`](/docs/api-reference/user-exchange/get-connected-exchanges):

<CodeGroup>
  ```bash Request theme={null}
  GET https://perps-api.vooi.io/user-exchange
  Authorization: Bearer <token>
  ```

  ```bash curl theme={null}
  curl https://perps-api.vooi.io/user-exchange \
    -H "Authorization: Bearer <token>"
  ```
</CodeGroup>

The response is an array of `{ exchange, valid }` objects.

* **An entry with `exchange: "aster"` is present and its `valid` is `true`** — your account is already connected. No action needed.
* **No `aster` entry is present, or the `aster` entry has `valid: false`** — follow the steps below. A present-but-`valid: false` entry means the existing credentials no longer work and you need to re-register.

Aster does not require a prior deposit before registering, so there is no eligibility check to run first.

## Prerequisites

* An EVM wallet
* An active VOOI API token

## 1. Prepare registration

Call [`POST /user-exchange/{exchange}/register/prepare`](/docs/api-reference/user-exchange/prepare-exchange-registration) with your wallet address.

The optional `referralCode` field binds a referral code to the new account at registration. Omit it and the VOOI code is applied; it cannot be changed afterwards. See [Points & rewards](/docs/points#referral-code).

The response contains:

* a short-lived `registrationToken`
* `signData` — a **two-item array** of EIP-712 typed data objects. You sign each one in order: `[0]` registers and approves the VOOI API agent (read, spot-trade, and perp-trade permissions; withdrawals disabled), `[1]` approves the VOOI builder used for order-time fee attribution.

<CodeGroup>
  ```bash Request theme={null}
  POST https://perps-api.vooi.io/user-exchange/aster/register/prepare
  Authorization: Bearer <token>
  Content-Type: application/json

  {
    "address": "0xYourWalletAddress"
  }
  ```

  ```bash curl theme={null}
  curl -X POST https://perps-api.vooi.io/user-exchange/aster/register/prepare \
    -H "Authorization: Bearer <token>" \
    -H "Content-Type: application/json" \
    -d '{"address": "0xYourWalletAddress"}'
  ```
</CodeGroup>

Response shape:

```jsonc theme={null}
{
  "exchange": "aster",
  "registrationToken": "<opaque-token>",
  "signData": [
    { /* EIP-712 typed data — primaryType "Message" (registers and approves the VOOI API agent) */ },
    { /* EIP-712 typed data — primaryType "ApproveBuilder" (approves the VOOI builder) */ }
  ]
}
```

Each `signData` item has `domain`, `message`, `primaryType`, and `types` — pass each through to an EIP-712 signer (see step 2). The two items differ: `[0]` uses `primaryType: "Message"` (its `message.msg` carries the agent-registration parameters), `[1]` uses `primaryType: "ApproveBuilder"`. Both domains use `chainId: 56` (BSC). See the API reference for the full schema.

The first signature grants VOOI an API agent with read, spot-trade, and perp-trade permissions; withdrawals are disabled.

The agent is valid for 90 days by default. To choose a different expiry, pass `agentExpiry` (milliseconds since the Unix epoch) in the prepare request — it sets the expiry of the agent registered by the `[0]` signature.

The `registrationToken` expires in 10 minutes. If it expires before you complete registration, call this endpoint again to get a new token.

### Customize the builder approval

The second signature (`[1]`, `ApproveBuilder`) approves a builder address that VOOI uses when routing orders on Aster, along with a maximum builder fee rate. Defaults are server-side: a VOOI-controlled builder, name `VOOI`, and a `0.0003` (3 bps) cap. To override any of these, pass them in the prepare body:

| Field | Type | Description |
| - | - | - |
| `builderAddress` | EVM address | Builder address carried in the builder approval. |
| `builderName` | string | Builder display name. |
| `maxFeeRate` | decimal string | Cap on the per-order builder fee, as a decimal (not bps). `"0.0003"` = 3 bps. |

`builderName` and `maxFeeRate` may only be sent together with `builderAddress` — sending either one alone returns `400`. Once approved, this cap is enforced on every Aster order: the per-order [`broker.feeBps`](/docs/trading-orders) you submit cannot exceed it. Re-running registration with a different cap replaces the previous approval.

## 2. Sign both messages

Sign each `signData` object as EIP-712 typed data, in the same order as the response.

Both messages use `chainId: 56` (BSC). Many end-user wallet apps warn or refuse to sign typed data whose domain `chainId` does not match the active network — if you prompt an end-user wallet to sign, switch it to BSC first. Signing with a raw private key has no network to match against.

```typescript theme={null}
import { type Hex } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';

async function signRegistration(
  walletPrivateKey: Hex,
  signData: PrepareResponse['signData'],
): Promise<[Hex, Hex]> {
  const account = privateKeyToAccount(walletPrivateKey);

  const sign = (item: (typeof signData)[number]) =>
    account.signTypedData({
      domain: {
        ...item.domain,
        chainId: Number(item.domain.chainId),
        verifyingContract: item.domain.verifyingContract as Hex,
      },
      message: item.message,
      primaryType: item.primaryType,
      types: item.types,
    });

  return [await sign(signData[0]), await sign(signData[1])];
}
```

This step returns two signatures that will be used in the next request to complete registration.

## 3. Execute registration

Submit your wallet address, the `registrationToken`, and both signatures to [`POST /user-exchange/{exchange}/register/execute`](/docs/api-reference/user-exchange/execute-exchange-registration).

VOOI submits the signed messages to Aster on your behalf — you do **not** broadcast them yourself. No on-chain transaction is required.

The `signatures` array must contain exactly two entries, in the same order as the `signData` items from the prepare response: index 0 is the agent registration-and-approval signature, index 1 is the builder-approval signature.

<CodeGroup>
  ```bash Request theme={null}
  POST https://perps-api.vooi.io/user-exchange/aster/register/execute
  Authorization: Bearer <token>
  Content-Type: application/json

  {
    "address": "0xYourWalletAddress",
    "registrationToken": "<opaque-token>",
    "signatures": ["0x<sig0>", "0x<sig1>"]
  }
  ```

  ```bash curl theme={null}
  curl -X POST https://perps-api.vooi.io/user-exchange/aster/register/execute \
    -H "Authorization: Bearer <token>" \
    -H "Content-Type: application/json" \
    -d '{"address": "0xYourWalletAddress", "registrationToken": "<opaque-token>", "signatures": ["0x<sig0>", "0x<sig1>"]}'
  ```
</CodeGroup>

Response on success:

```json theme={null}
{ "exchange": "aster", "valid": true }
```

**Possible errors:**

| Status | Message | Cause |
| - | - | - |
| `400 Bad Request` | `Registration token has expired` | The token from step 1 expired. Call the prepare endpoint again to get a new one. |
| `400 Bad Request` | `Agent approval failed: ...` | Aster rejected the agent-registration signature (`[0]`). Confirm you signed the exact `signData` objects returned in step 1 and passed them in the correct order. |

A failed builder approval (`[1]`) does not fail registration — the connection still completes with `valid: true`; only the agent-registration signature failing is fatal.

Your wallet is now connected to Aster through VOOI.

## Aster account configuration

Trading through VOOI expects your Aster account to be in:

* **Cross-margin** mode
* **Multi-asset margin** enabled
* **One-way position** mode

Configure these in the Aster UI before trading. VOOI does not change these settings for you, and other modes are not supported by the abstracted trading endpoints.

## Next steps

<CardGroup cols={2}>
  <Card title="Start trading on Aster" icon="bolt" href="/docs/trading-orders">
    Place your first order
  </Card>

  <Card title="Connect your wallet to Hyperliquid" icon="plug" href="/docs/register-hyperliquid">
    Register on Hyperliquid
  </Card>

  <Card title="Connect your wallet to Extended" icon="plug" href="/docs/register-extended">
    Register on Extended
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.