# Accounts

Group a customer's wallets under your own reference for that customer, find the account behind any address of your tenant, and create thousands of accounts at once.

## Overview

- **An account** is your tenant's container of wallets on any chain, with `customerRefId` — your own reference for the customer: 1 to 128 of `A–Z a–z 0–9 _ . : @ / + -`, starting with a letter or a digit, unique in your tenant and never changed once set —, a `name`, up to 20 `tags`, and `hidden` (left out of the default account lists of your own tools; nothing else changes).
- **Its users**: an `owner` — the user whose wallets it holds, at most one — and `viewer`s, users who may see it, all users of your tenant. A wallet is always a user's: the wallets an account holds are its owner's wallets, made and listed as that user's (they are also in the owner's own [List Wallets](https://docs.aureahub.com/docs/wallets-list.md)). For a customer who is not one of your users, name one of your tenant's users as the owner.
- **Nothing that exists changes.** Every wallet is in its user's **default account** until you put it in another, and every other route answers as before.
- **How your customers' coins are held** — each in its own account (segregated, every tenant's today), or swept from collection accounts to a treasury with a sub-ledger of each customer's claim (omnibus): [Account Structures](https://docs.aureahub.com/docs/guide-account-structures.md).
- The routes: [List](https://docs.aureahub.com/docs/accounts-list.md), [Create](https://docs.aureahub.com/docs/account-create.md), [Get](https://docs.aureahub.com/docs/account-get.md) and [Change](https://docs.aureahub.com/docs/account-update.md) an account, [Add a Wallet](https://docs.aureahub.com/docs/account-wallet-add.md), [Find by Address](https://docs.aureahub.com/docs/account-lookup.md), and the bulk creation ([Create in Bulk](https://docs.aureahub.com/docs/accounts-bulk-create.md), [List](https://docs.aureahub.com/docs/accounts-bulk-list.md), [Report](https://docs.aureahub.com/docs/accounts-bulk-get.md)).

```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": null,
      "isPrimary": false
    }
  ],
  "createdBy": "0d2f6b8a-4c1e-4a93-b7d5-2e9f1c3a8b60",
  "createdAt": "2026-10-07T09:12:40.511Z",
  "updatedAt": "2026-10-07T09:13:02.118Z"
}
```

## Who Calls the Routes

- **Your tenant's administrators, with their access token**, on your own tenant. Reading — the list, an account, the lookup, the bulk reports — is for the roles that read the tenant's transactions: `owner`, `tenantadmin`, `non_signing_admin`, `signer`, `approver`, `editor`, `viewer` and `auditor`. Creating, changing, adding a wallet and the bulk creation are for `owner`, `tenantadmin` and `non_signing_admin`, who manage your users ([Roles](https://docs.aureahub.com/docs/authentication.md)). Any other role, an end user's included: `403` `Tenant admin access required. Your role does not have permission to perform this action.`
- Only an access token opens them: your server calls them signed in as one of your administrators. The tenant signature and server tokens are not accepted here.
- **A request written wrong is refused whole**, never repaired: `400` `ACCOUNT_REQUEST_INVALID`, with each problem in `details.errors` (up to 50) as `field: reason`. A field the route does not take is refused too.

```json
{
  "statusCode": 400,
  "error": "BadRequestError",
  "message": "Invalid request",
  "details": {
    "code": "ACCOUNT_REQUEST_INVALID",
    "errors": [
      "customerRefId: 1 to 128 of A–Z a–z 0–9 _ . : @ / + -, starting with a letter or digit",
      "(body): Unrecognized key(s) in object: 'owner'"
    ]
  }
}
```

## The Default Account

- Every user of your tenant has one: **its id is the user's id**, its owner is the user (`isDefault` `true`), and it holds the user's wallets that are in no other account — on every chain, and as many EVM addresses as the user has.
- Nothing is stored for it until someone writes to it: it is computed when read, and the first change — a name, tags, `hidden`, a viewer, a `customerRefId` — stores it. Reading writes nothing. Its `createdAt` is the user's; `createdBy` is `null` until it is first written.
- [List Accounts](https://docs.aureahub.com/docs/accounts-list.md) shows a default account while it holds a wallet, or once it was written to; [Get an Account](https://docs.aureahub.com/docs/account-get.md) reads any user's default account by the user's id.
- Its owner is always its user (`400` `ACCOUNT_DEFAULT_OWNER`). Putting a wallet in another account takes it out of the default one; nothing else moves it, and no route takes a wallet out of an account.

## One EVM Key per Account

- An account you create holds **one EVM address per network, valid on every EVM chain** — the same address on each —, and one wallet per chain and network for Solana. Each of its wallets carries `family`: `evm` for an EVM chain, else the chain itself.
- Asking for a wallet on any EVM chain — `gnosis`, `base`, or `evm` itself — makes the account's EVM key once, stored on chain `evm`; asking again for any EVM chain answers `409` `ACCOUNT_CHAIN_TAKEN` with the key it holds (`details.walletId`, `details.address`). The mainnet key and the testnet key are two (`isTestnet`): a testnet key never signs on a mainnet.
- Requests made at the same time for the same account and chain make one wallet; the others answer `409` `ACCOUNT_CHAIN_TAKEN`.

## Wallets in an Account

[Add a Wallet](https://docs.aureahub.com/docs/account-wallet-add.md) takes one of two bodies. The account needs an owner first (`409` `ACCOUNT_OWNER_REQUIRED`):

- **`{ "chain", "isTestnet", "name" }` — Aurea makes it** for the account's owner, by the same path as [Create Wallet](https://docs.aureahub.com/docs/wallets-create.md), when your tenant's wallets are custodial (the platform holds their keys for your tenant). Where the keys are on the user's device or 2-of-3 MPC, Aurea makes none: `409` `ACCOUNT_WALLET_BY_CLIENT`, with `details.walletMode` `non_custodial` or `mpc`. The user's device makes the wallet as always — [Register Client Wallet](https://docs.aureahub.com/docs/wallets-client-register.md), or the [MPC key generation](https://docs.aureahub.com/docs/mpc-dkg-start.md) — and you put it in with the second body.
- **`{ "walletId" }` — put one of the owner's wallets in it**, one that is in no other account. An EVM wallet goes in with every wallet of the owner at the same address on the same network — one per EVM chain the address is registered on, the address compared without regard to case —, and a wallet registered later at that address joins it.
- The account lists each wallet it holds; for an EVM address registered on several EVM chains, one entry per chain, all with `family` `evm` and the same address. A deactivated wallet is not shown.

## Find the Account of an Address

A deposit arrives at one of your addresses: [Find by Address](https://docs.aureahub.com/docs/account-lookup.md) tells you whose it is.

```bash
curl "https://api.aureahub.com/v1/accounts/lookup?address=0x52908400098527886e0f7030069857d2e4169ee7&chain=base" \
  -H "Authorization: Bearer $TENANT_ADMIN_TOKEN"
```

- Every active wallet of your tenant at the address — one per chain and network it is registered on —, each with its account: the account that holds it, or its user's default account (`isDefault` `true`), and that account's `customerRefId`.
- An EVM address is compared without regard to case, a Solana address exactly. Anything else: `400` `ACCOUNT_ADDRESS_INVALID`; no wallet of your tenant there: `404` `ACCOUNT_ADDRESS_UNKNOWN`.
- `chain` (a slug, or a testnet's id) and `isTestnet` narrow it. An EVM chain matches the address's wallets on **every** EVM chain: a deposit seen on `base` to an address registered only on `gnosis` is found.

## Create Accounts in Bulk

- Up to **10,000 accounts** in one request, each with its `customerRefId` — required here: it is what makes the job safe to send again —, and optionally `wallets`, up to 20 `{ "chain", "isTestnet" }` made for every account. Every EVM chain named is the account's one EVM key; a family named twice is one wallet. The body may be up to 6 MiB.
- **Checked whole before anything is stored**: a `customerRefId` named twice (`400` `ACCOUNTS_BULK_DUPLICATE_REF`, the repeated ones in `details.customerRefIds`); with `wallets`, a custodial tenant (`409` `ACCOUNT_WALLET_BY_CLIENT`), chains a wallet can be made on (`400` `ACCOUNT_CHAIN_UNKNOWN`) and an owner for every account (`400` `ACCOUNT_OWNER_REQUIRED`, the accounts' places in `details.indexes`); every user named one of yours (`400` `ACCOUNT_USER_UNKNOWN`).
- **`202` with the job** (`jobId`, `status` `queued`, `total`): the accounts are made in the background, the oldest job first, each job in the order of its request; wallets are made one at a time.
- An account whose `customerRefId` your tenant already has is `skipped` (`reason` `ACCOUNT_REF_EXISTS`, `accountId` the one that holds it): sending the same request again makes nothing twice. A user gone meanwhile fails the account (`ACCOUNT_USER_UNKNOWN`); a wallet the wallet path refuses fails it with that path's code, and one that fails on Aurea's side is tried again, three tries in all.
- Follow it with [Bulk Creation Report](https://docs.aureahub.com/docs/accounts-bulk-get.md): the job's `status` (`queued`, `running`, `completed` once no account is pending), its `counts`, and each account in the request's order — `pending`, `created`, `skipped` or `failed`, with its `accountId` and `reason`.

## Freeze an Account

- Your tenant's freezers — `owner`, `tenantadmin`, `non_signing_admin` and `security_admin` — freeze an account with [Freeze](https://docs.aureahub.com/docs/freezes-create.md), `target` `account` and `id` the account's id — for a user's default account, the user's id.
- **Its wallets stop signing**: every route that would sign or send with a wallet it holds answers `423` `ACCOUNT_FROZEN` (`This wallet's account is frozen: its wallets cannot sign until the freeze is lifted.`), as a frozen wallet does — every wallet of your tenant at the address of a wallet the account holds, on every chain. Reads go on, and the user's wallets outside the account still sign. The account's `frozen` is `true`.
- Freezing an account you own, or your own default account, is allowed; lifting that freeze is not (`403` `FREEZE_SELF`). Another tenant's account: `404` `FREEZE_TARGET_NOT_FOUND` (`No such account here.`). More: [Freezes & Quarantines](https://docs.aureahub.com/docs/guide-freezes.md).

## Events

- `account.created` and `account.updated` — `data` the account as [Get an Account](https://docs.aureahub.com/docs/account-get.md) answers it —, and `account.wallet_added` — `data` `accountId`, `customerRefId`, `walletId`, `chain`, `family`, `isTestnet`, `address` and `how`: `created` (made for the account) or `attached` (one of the owner's wallets put in it).
- They reach only the [webhook endpoints](https://docs.aureahub.com/docs/webhook-endpoint-add.md) that name them — never an endpoint that names no type, never the webhook of an environment. An account's news goes to your production endpoints; a wallet's to the endpoints of its network (a testnet wallet's: sandbox).
- Each is queued with the change itself: no news of a change that did not happen, no change without its news ([Webhooks & Events](https://docs.aureahub.com/docs/guide-events.md)).

## Operations and the Audit Trail

- Every operation's answer carries `sourceAccountId`: the account of its wallet — the account that holds it, else its user's default account (the user's id) —, or `null` when it has no wallet ([Operations & Fees](https://docs.aureahub.com/docs/guide-operations.md)). The `operation.*` events do not carry it.
- The [audit trail](https://docs.aureahub.com/docs/audit-events.md), when on, records `account.created`, `account.updated` and `account.bulk_requested` (category `governance`), `account.wallet_created` and `account.wallet_attached` (category `keys`) — with ids, counts, chains and field names, never a `customerRefId`, a name, a tag or an address.

---

Web version: https://docs.aureahub.com/#guide-accounts
