# Add a Token

Add a custom token to your tenant's token list. For the `owner`, `tenantadmin`, `non_signing_admin` and `editor` roles, on their own tenant.

## Endpoint

### `POST /v1/admin/tenants/{tenantId}/tokens`

Authentication: bearer token required.

Creates a token for the tenant. An EVM address is checked before anything is stored: see Address checks below.

**Path parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `tenantId` | string | yes | Your tenant's id |

**Request body**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `symbol` | string | yes | Token symbol (e.g. USDC) |
| `name` | string | yes | Token name |
| `chain` | string | yes | Chain slug. An EVM token is stored under its chain's slug with the network of `chainId`: a testnet row id such as `celo-sepolia` is stored as `celo` with `isTestnet` true, and another EVM chain's slug answers `400` |
| `chainId` | integer | yes | Chain ID |
| `isTestnet` | boolean | no | Test network (default false); on an EVM chain, `chainId` decides it |
| `decimals` | integer | yes | Decimals (0–18) |
| `address` | string | no | Contract address (an EVM address or a Solana mint); omit it for the native token. An EVM address is stored in its EIP-55 form |
| `isNative` | boolean | yes | Native chain token |
| `logoUri` | string | no | Logo image URL |
| `coingeckoId` | string | no | Price-feed id, for pricing |

**Responses**

`201` Created

```json
{
  "id": "uuid",
  "symbol": "XAUT",
  "name": "Tether Gold",
  "chain": "ethereum",
  "isTestnet": false,
  "chainId": 1,
  "decimals": 6,
  "isNative": false,
  "isActive": true,
  "address": "0x68749665FF8D2d112Fa859AA293F07A622782F38",
  "logoUri": null,
  "coingeckoId": null,
  "createdAt": "2026-10-06T09:48:24.870Z",
  "updatedAt": "2026-10-06T09:48:24.870Z"
}
```

`400` Bad Request

```json
{
  "error": "BadRequestError",
  "message": "The token address has a wrong EIP-55 checksum: check it for a typo, or send it in lower case",
  "details": { "code": "TOKEN_ADDRESS_CHECKSUM_INVALID", "field": "address" }
}
```

`404` Not Found

```json
{ "error": "NotFoundError", "message": "Tenant not found" }
```

`409` Conflict

```json
{
  "error": "ConflictError",
  "message": "Token with address 0x68749665FF8D2d112Fa859AA293F07A622782F38 already exists on ethereum"
}
```

`422` Unprocessable Entity

```json
{
  "error": "ValidationError",
  "message": "No contract exists at this address on chain 1",
  "details": { "code": "TOKEN_ADDRESS_NOT_A_CONTRACT", "field": "address", "chainId": 1 }
}
```

`503` Service Unavailable

```json
{
  "error": "ServiceUnavailableError",
  "message": "The token address cannot be checked: the node for chain 137 did not answer",
  "details": { "code": "TOKEN_ADDRESS_UNVERIFIED", "chainId": 137, "retryable": true }
}
```

**Example request**

```bash
curl -X POST https://api.aureahub.com/v1/admin/tenants/TENANT_ID/tokens \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"symbol":"XAUT","name":"Tether Gold","chain":"ethereum","chainId":1,"decimals":6,"isNative":false,"address":"0x68749665ff8d2d112fa859aa293f07a622782f38"}'
```

## Address checks

An EVM address (`0x` and 40 hex digits) is checked when a token is created, and when an update changes it. Nothing is stored when a check fails.

- **All lower case or all upper case:** accepted, and stored in its EIP-55 (mixed-case checksum) form.
- **Mixed case with a wrong EIP-55 checksum:** `400` with `details.code` `TOKEN_ADDRESS_CHECKSUM_INVALID`. Almost always a typo: check the address, or send it in lower case.
- **No contract at the address on the token's chain:** `422` with `details.code` `TOKEN_ADDRESS_NOT_A_CONTRACT`.
- **The chain's node did not answer the check:** `503` with `details.code` `TOKEN_ADDRESS_UNVERIFIED` and `details.retryable` true. Retry later.

A Solana mint and a native token (no address) are not checked this way. A token added from Aurea's catalogue keeps the catalogue's address and is not checked again.

---

Web version: https://docs.aureahub.com/#admin-tokens-create
