# Add a Wallet to an Account

Have Aurea make the account's wallet on a chain, or put one of its owner's wallets in it.

## Overview

- **`{ "chain", "isTestnet", "name" }`**: Aurea makes the wallet for the account's owner, by the same path as [Create Wallet](https://docs.aureahub.com/docs/wallets-create.md) — for a tenant whose wallets are custodial. Any EVM chain asked, or `evm`, makes the account's one EVM key, on chain `evm`, valid on every EVM chain; `solana` its Solana wallet. `isTestnet` defaults to `false`; `name` is the wallet's label, 1 to 100 characters.
- **`{ "walletId" }`**: one of the owner's wallets that is in no other account goes in it — an EVM wallet with every wallet of the owner at the same address on the same network.
- `201` with the account and its wallets. The account holds one EVM address per network and one wallet per chain and network for any other chain: what it holds already answers `409` `ACCOUNT_CHAIN_TAKEN`. How it works: [Accounts](https://docs.aureahub.com/docs/guide-accounts.md).
- For `owner`, `tenantadmin` and `non_signing_admin`, on their own tenant. With `account.wallet_added` to the endpoints that name it.

## Endpoint

### `POST /v1/accounts/{accountId}/wallets`

Authentication: bearer token required.

Makes the account's wallet on a chain, or puts one of its owner's wallets in it.

**Path parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `accountId` | string (uuid) | yes | The account's id; a user's id for that user's default account, which takes `{ chain }` only |

**Request body**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `chain` | string | no | To make one: an EVM chain slug, `evm`, `solana`, or a testnet's id |
| `isTestnet` | boolean | no | With `chain`; default `false` |
| `name` | string | no | With `chain`: the wallet's label |
| `walletId` | string (uuid) | no | Instead of `chain`: one of the owner's wallets to put in |

**Responses**

`201` Added

```json
{
  "id": "3b8f2c6e-1d4a-4e9b-8f7c-2a5d6e9b1c40",
  "customerRefId": "cust-00042",
  "name": "Savings, customer 42",
  "tags": ["retail", "eu"],
  "hidden": false,
  "isDefault": false,
  "frozen": false,
  "users": [
    { "userId": "5d2c1b0a-9e8f-4a7b-8c6d-5e4f3a2b1c0d", "access": "owner" }
  ],
  "wallets": [
    {
      "walletId": "7c1e9b24-3f5a-4d8e-9b6c-1a2f3e4d5c6b",
      "chain": "evm",
      "family": "evm",
      "isTestnet": false,
      "address": "0x52908400098527886E0F7030069857D2E4169EE7",
      "keyManagementScheme": "client_side",
      "label": "Customer 42",
      "isPrimary": false
    }
  ],
  "createdBy": "0d2f6b8a-4c1e-4a93-b7d5-2e9f1c3a8b60",
  "createdAt": "2026-10-07T09:12:40.511Z",
  "updatedAt": "2026-10-07T09:12:40.511Z"
}
```

`409` Chain taken

```json
{
  "statusCode": 409,
  "error": "ConflictError",
  "message": "The account holds its EVM key on this network already: one address, valid on every EVM chain.",
  "details": {
    "code": "ACCOUNT_CHAIN_TAKEN",
    "walletId": "7c1e9b24-3f5a-4d8e-9b6c-1a2f3e4d5c6b",
    "address": "0x52908400098527886E0F7030069857D2E4169EE7"
  }
}
```

`409` Keys on the device

```json
{
  "statusCode": 409,
  "error": "ConflictError",
  "message": "This tenant's wallets are made on the user's device (POST /v1/wallets/client): put it in the account with { walletId }.",
  "details": { "code": "ACCOUNT_WALLET_BY_CLIENT", "walletMode": "non_custodial" }
}
```

**Example request**

```bash
curl -X POST https://api.aureahub.com/v1/accounts/3b8f2c6e-1d4a-4e9b-8f7c-2a5d6e9b1c40/wallets \
  -H "Authorization: Bearer $TENANT_ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "chain": "base", "name": "Customer 42" }'
```

## Refusals

Nothing is made or moved. In the order they are checked:

- `404` `ACCOUNT_NOT_FOUND` — `No such account here.`
- `409` `ACCOUNT_OWNER_REQUIRED` — `The account has no owner: a wallet is its owner's. Name one first (users with access owner).`
- **Making one** (`chain`): `409` `ACCOUNT_WALLET_BY_CLIENT`, with `details.walletMode` — your tenant's keys are on the user's device (`non_custodial`: `This tenant's wallets are made on the user's device (POST /v1/wallets/client): put it in the account with { walletId }.`) or 2-of-3 (`mpc`: `This tenant's wallets are 2-of-3: the user's device makes the wallet (the MPC key generation), then puts it in the account with { walletId }.`); `400` `ACCOUNT_CHAIN_UNKNOWN` — `Not a chain a wallet can be made on: …`; `409` `ACCOUNT_CHAIN_TAKEN`, with `details.walletId` and `details.address` — `The account holds its EVM key on this network already: one address, valid on every EVM chain.`, or for Solana `The account holds a wallet on this chain and network already: one per chain.` Then any refusal of the wallet path itself, as [Create Wallet](https://docs.aureahub.com/docs/wallets-create.md) answers it — for example `503` `WALLET_KEY_STORE_UNAVAILABLE`.
- **Putting one in** (`walletId`): `400` `ACCOUNT_DEFAULT_ATTACH` — `A wallet in no account is already in its user's default account.`; `404` `ACCOUNT_WALLET_NOT_FOUND` — `No such wallet here.`; `409` `ACCOUNT_WALLET_NOT_OWNERS` — `Only a wallet of the account's owner can be put in it.`; `409` `ACCOUNT_WALLET_IN_ACCOUNT`, with `details.accountId` — `The wallet is in an account already.`, or `The wallet is in this account already.`; `409` `ACCOUNT_CHAIN_TAKEN` — the account already holds another EVM address on that network, or a wallet on that chain.
- `400` `ACCOUNT_REQUEST_INVALID` — a body that is neither of the two, or mixes them.

---

Web version: https://docs.aureahub.com/#account-wallet-add
