# Tokenized Assets

> Coming soon, upon request — this feature is turned on for your tenant by the Aurea team. [Contact us](https://www.aureahub.com/contact)

Tokenized shares, ETFs and portfolios, and a yield-bearing dollar token, for your users: the catalogue and its market data, each user's eligibility and documents, binding quotes executed on chain, limit orders and corporate actions — through one API, whatever provider issues them.

## Overview

The routes under `/v1/tokenized-assets` let your users hold tokenized shares, ETFs and portfolios — tokens on a public chain, each standing for shares of an underlying instrument — the stablecoins they settle in, and a yield-bearing dollar token, through one API whatever provider issues them. Aurea integrates two providers; you never call them, and no answer or error names them.

- **The catalogue and market data:** the assets your tenant offers, their prices, candles, market data, dividends, shares multiplier and status, and for some assets their supply, reserves, price feeds and corporate-action calendar.
- **Eligibility and documents:** your tenant, as the authorised entity, supplies each user's eligibility; the user accepts each asset's documents before trading it.
- **Trading:** a binding quote executed on chain, a limit order, the yield token, and buying or selling on the secondary market — from and to the user's own wallet.
- **Operations:** every trade is an operation to follow.

> Note: Tokenized assets are set up and switched on per tenant by Aurea. [Contact us for details](https://www.aureahub.com/contact).

## Setting Up

Tokenized assets are off for every tenant until Aurea sets them up for it, in each environment — production and the test environment apart. Until then every route answers:

- `403` `TOKENIZED_ASSETS_NOT_CONFIGURED` — `Tokenized assets are not set up for this tenant on mainnet. Contact Aurea to set them up.` (`testnet` in the test environment), with `details.isTestnet`: no access to a provider is set up for your tenant there;
- `403` `TOKENIZED_ASSETS_OFF` — `This tenant does not offer tokenized assets on mainnet.`: set up, but not switched on.

What Aurea sets for your tenant, per environment, at your request:

- **What you offer:** the product lines (`stock`, `etf`, `portfolio`, `settlement_token`, `yield_token`), every asset of them or a selection, and whether the assets for professional investors only are kept out. For the assets the issuer issues and redeems directly, leveraged and inverse ETFs and the assets not listed in the US are kept out unless you ask otherwise.
- **Where the tokens are held:** in your users' own wallets — Aurea has each of them registered for trading on each chain. Holding them in your tenant's wallet for its users is coming (Coming, below).
- **Your limits:** per order, per order of an asset, per user over 24 hours (US dollars); your fee, 0 to 500 basis points, added to a buy and taken from a sale; whether you trade outside the regular session; whether your binding quotes are short or long (a wallet its owner signs for needs long ones).
- **The secondary market** ([Secondary Quote](https://docs.aureahub.com/docs/tok-secondary-quote.md)) is off until switched on for your tenant (`403` `TOKENIZED_ASSETS_SECONDARY_ROUTE_OFF`).
- **The documents** your users accept before trading are published by Aurea ([Asset Documents](https://docs.aureahub.com/docs/tok-documents.md)).
- **Each asset's investor class** — whether retail investors may buy it, or professional investors only — is set by Aurea from the issuer's documents, asset by asset (`investorClass` in [the asset list](https://docs.aureahub.com/docs/tok-assets-list.md)). Until Aurea classifies an asset it is `null`, and your retail clients are refused it.

## Coming

Not usable in production yet, and listed under [Feature Availability](https://docs.aureahub.com/docs/feature-availability.md) › Coming: holding the tokens in your tenant's wallet for its users, the issuer's own flows for the assets it issues and redeems directly, and the tokenized assets on Solana. Their routes are not documented until they are.

In the **test environment**: no wallet can be registered for trading, so binding quotes, limit orders and the yield token answer `409` `TOKENIZED_ASSETS_WALLET_NOT_REGISTERED`, and the contracts are not known there (`409` `TOKENIZED_ASSETS_EXECUTION_UNAVAILABLE`, the yield token's price too); the issuer's data answers `503` `TOKENIZED_ASSETS_PROVIDER_UNAVAILABLE`; the secondary market is for production only. The market data of the assets traded with quotes, eligibility, documents and indicative quotes work there. [Contact us for details](https://www.aureahub.com/contact).

## Calling the Routes

- Every route needs **both** the user's access token (`Authorization: Bearer …`) and your tenant's request signature (`x-tenant-api-key`, `x-timestamp`, `x-signature` — [Authentication](https://docs.aureahub.com/docs/authentication.md)). The API secret stays on your server: call them from there, on the user's behalf. A [server token](https://docs.aureahub.com/docs/guide-server-credentials.md) in `X-Aurea-Server-Token` may take the place of the three signature headers, with the user's access token still in `Authorization`; a tenant on the institutional security profile must use one (`401` `SERVER_TOKEN_REQUIRED`).
- **Who:** every role of your tenant reads; trading — accepting a document, a binding quote and its execution, a limit order, the yield token, the secondary market — is for `user`, `owner`, `tenantadmin` and `signer`, for themselves; `owner`, `tenantadmin` and `non_signing_admin` read and supply your users' eligibility ([Roles](https://docs.aureahub.com/docs/authentication.md)). A user acts on its own quotes and operations only.
- **The environment:** `isTestnet` — `"true"` in the query of a GET, `true` in the body of a POST — picks the test environment; anything else is production. Every answer says which (`isTestnet`).
- **Amounts** are decimal strings in the unit the field names — tokens, US dollars, a stablecoin — not in smallest units: `"2"` is two tokens, `"250"` 250 US dollars. At most 18 digits after the point (6 for USDC).
- **Symbols** are the tokens' own, as their contracts name them, and case matters (`^[A-Za-z0-9.-]{1,32}$`).
- **Rate limits:** the POST routes allow 10 to 60 requests a minute, the eligibility supply 120 ([Rate Limits](https://docs.aureahub.com/docs/rate-limiting.md)). They count per calling IP address: from your server, your users share them.

## Answers Every Route Can Give

| Status | details.code | When |
| --- | --- | --- |
| 401 | — | No valid access token (`Authentication required`), or no valid signature ([Signature Errors](https://docs.aureahub.com/docs/authentication.md)). |
| 403 | — | The caller's role may not call the route: `Your role does not have permission to perform this action.` (for the eligibility of your users: `Tenant admin access required. Your role does not have permission to perform this action.`). |
| 403 | TOKENIZED_ASSETS_NOT_CONFIGURED | Not set up for your tenant in this environment ([Setting Up](https://docs.aureahub.com/docs/guide-tokenized-assets.md)). |
| 403 | TOKENIZED_ASSETS_OFF | Set up, but your tenant does not offer tokenized assets in this environment. |
| 423 | TENANT_FROZEN, USER_FROZEN | The tenant or the user is frozen ([Freezes](https://docs.aureahub.com/docs/guide-freezes.md)). |
| 422 | — | A field does not fit: `Validation Error`, `Request validation failed`. `details` lists each problem — `[ { "path": "chainId", "message": "chainId must be 1 or 56" } ]`. The checks above come first, so a request that does not fit is answered 403 while the module is not set up. (The list of assets answers a query that does not fit with `400`, before anything else.) |
| 429 | — | `Rate limit exceeded, retry in 1 minute`. |

Refusals carry their code in `details.code`, with what they are about beside it; the error is the class of the status (`BadRequestError`, `ForbiddenError`, `NotFoundError`, `ConflictError`, `LockedError`, `ServiceUnavailableError`). No answer or message names a provider.

```json
{
  "statusCode": 403,
  "error": "ForbiddenError",
  "message": "Tokenized assets are not set up for this tenant on mainnet. Contact Aurea to set them up.",
  "details": { "code": "TOKENIZED_ASSETS_NOT_CONFIGURED", "isTestnet": false }
}
```

## Two Kinds of Assets

Assets come from two providers, and some routes serve one kind of asset only; another asset answers `409` `TOKENIZED_ASSETS_NOT_SUPPORTED_FOR_ASSET`.

|  | Assets traded with quotes | Assets the issuer issues and redeems directly |
| --- | --- | --- |
| How to tell | `details: null` in [Get an Asset](https://docs.aureahub.com/docs/tok-asset-get.md) | `details` in Get an Asset |
| Chains | `1` (Ethereum), `56` (BNB Chain) | `1`, `56`, `10` (Optimism), `42161` (Arbitrum) |
| Market data | Market status, prices, tickers, paused assets, candles, market data, dividends | Multipliers per chain, supply, reserves, price feeds, corporate-action calendar |
| Both | Price, shares multiplier, status, documents, requirements | the same |
| Trading | Binding quotes, limit orders, the yield token, the secondary market | Coming (Coming, above) |
| Corporate actions | [Corporate Actions](https://docs.aureahub.com/docs/tok-asset-corporate-actions.md) | [Calendar](https://docs.aureahub.com/docs/tok-asset-ca-calendar.md) |

## Eligibility and Documents

Your tenant is the authorised entity: it supplies what makes each user eligible, and Aurea refuses a trade the user may not make. Supply each user's items with [Supply Eligibility](https://docs.aureahub.com/docs/tok-user-eligibility-supply.md) — residence (country, and region where a region of the country is excluded), the Regulation S declaration, the client's classification (`retail` or `professional`) and the appropriateness test's outcome — and have the user accept the asset's documents ([Asset Documents](https://docs.aureahub.com/docs/tok-documents.md), [Accept a Document](https://docs.aureahub.com/docs/tok-document-accept.md)). [Requirements](https://docs.aureahub.com/docs/tok-requirements.md) says, for a user and an asset, whether a trade is possible and what is missing.

- **Refused:** a resident of an excluded country or region, or of a country that serves no individuals (`TOKENIZED_ASSETS_COUNTRY_EXCLUDED`); a US person (`TOKENIZED_ASSETS_US_PERSON`); a user the appropriateness test found it not appropriate for (`TOKENIZED_ASSETS_NOT_APPROPRIATE`); a retail client, for an asset for professional clients — or not classified yet (`investorClass: null`) — or in a country open to professional clients only, or where your tenant does not sell to retail clients (`TOKENIZED_ASSETS_PROFESSIONAL_ONLY`); an asset whose prospectus has expired (`TOKENIZED_ASSETS_PROSPECTUS_EXPIRED`). The countries depend on the asset's issuer: ask Aurea for the list.
- **Documents:** the prospectus and the final terms, and the key information document for a client who is not professional; for the assets the issuer issues and redeems directly also four risk disclosures, a leverage one for leveraged and inverse ETFs, and a prospectus supplement once one is published. A new version asks the user again.
- Every binding quote, order, execution, broadcast and secondary-market step reads them again: `403` with the refusal's code, or `TOKENIZED_ASSETS_ELIGIBILITY_INCOMPLETE` with `details.missing`.

## Trading with a Binding Quote

1. **Show what is offered and what it costs:** [List Assets](https://docs.aureahub.com/docs/tok-assets-list.md), the market data, [Trading Limits](https://docs.aureahub.com/docs/tok-limits.md) and an [indicative quote](https://docs.aureahub.com/docs/tok-quote-indicative.md).
2. **Make sure the user may trade it:** [Requirements](https://docs.aureahub.com/docs/tok-requirements.md); supply what is missing and have the documents accepted.
3. **Get a binding quote:** [Binding Quote](https://docs.aureahub.com/docs/tok-quote-create.md) holds its terms until `expiresAt`.
4. **Execute it:** [Execute a Quote](https://docs.aureahub.com/docs/tok-quote-execute.md) answers the operation — carried out at once for a wallet Aurea signs for, or with the `steps` to sign for a wallet its owner signs for.
5. **Sign, when the wallet is the user's own:** [Send Signatures](https://docs.aureahub.com/docs/tok-operation-broadcast.md) before `signingExpiresAt`.
6. **Follow it:** [Get an Operation](https://docs.aureahub.com/docs/tok-operation-get.md) until it is `completed`, `failed` or `expired`.

A wallet its owner signs for may also place a [limit order](https://docs.aureahub.com/docs/tok-limit-order.md), filled later at its price or better.

## Who Signs

| Wallet | What happens |
| --- | --- |
| Custodial (the platform holds the key for your tenant) | `signer: "server"`. Aurea signs and sends every step at once; the operation is answered `submitted`, `completed` or `failed`. |
| Non-custodial (`client_side`) or MPC (`mpc_tss`) | `signer: "client"`. The operation is answered with `steps`: sign each step's `txHashToSign` with the wallet — a raw secp256k1 signature of that hash — and send the signatures, in the order of the steps, to [Send Signatures](https://docs.aureahub.com/docs/tok-operation-broadcast.md) before `signingExpiresAt`. Aurea checks each against the wallet and sends the transactions exactly as it built them: you never send a transaction. |

Each step says what it is (`purpose`: `approve_reset`, `approve`, `mint`, `redeem`, `limit_order`, `subscribe`, `yield_redeem`, `wrap`, `unwrap`, `transfer`), with its transaction's `to`, `data`, `value`, `nonce`, gas and fees. An approval is of exactly the amount, and only when the allowance does not cover it; an allowance left at another amount is first reset to zero (`approve_reset`). The wallet pays the network fee in the chain's native token.

## The Operation

Every trade, order and yield-token operation is an operation, answered the same way by every route that makes or moves one:

- `kind`: `trade` (a binding quote), `limit_order`, `yield_subscribe`, `yield_redeem`, `yield_wrap`, `yield_unwrap`.
- `symbol`, `chainId`, `side` (`buy`, `sell` or `null`), `tokenAmount`, `valueUsd`, `paymentToken` (`USDC`, `USDT`, `USDon`, `USDG`) and `paymentAmount` — decimal strings in their unit; `unit`: `token`, `shares` (the rebasing yield token, counted in yield tokens' worth of shares) or `base` (tokens counted before their multiplier).
- `wallet`: `own` (the user's own wallet); `signer`: `server` or `client`; `quoteId`; `order` (a limit order's `orderId`, `limitPrice`, `expiresAt`, `filledTokenAmount`).
- `steps` and `signingExpiresAt` while it waits for the client's signatures (`steps` is empty otherwise); `txHashes`; `received` — what the wallet received, once completed: the yield token or its shares, or the USDC of a redemption; `failureCode`; `createdAt`, `updatedAt`.

```text
quoted | attested → submitted → completed
                    ↘ failed
quoted | attested → expired                            (not signed or carried out in time)
```

`quoted` or `attested`: built — waiting for the client's signatures when `signer` is `client`. `submitted`: the first transaction was accepted; a limit order stays `submitted` until it is filled. `failed` carries `failureCode` — a refusal read again before the signatures were sent, a revert (`TOKENIZED_ASSETS_PRICE_MOVED`, `…_TRANSACTION_REVERTED`, `…_OUT_OF_GAS`…), `…_BROADCAST_REFUSED`, `…_SIGNING_FAILED` or `…_TRANSACTION_DROPPED`. `expired`: nothing happened — `…_SIGNING_EXPIRED`, `…_NOT_SENT`, `…_QUOTE_EXPIRED`, `…_ORDER_EXPIRED` or `…_ORDER_CANCELLED`. A route that carries an operation out answers it in the state it reached: a `201` may be `failed`.

## Following an Operation

Aurea follows every operation that is `quoted`, `attested` or `submitted` in the background, about once a minute — completed, failed, expired, a limit order filled or lapsed —, and marks expired a binding quote that ran out of time. An operation also moves when its own request runs (receipts are awaited for about a minute), when its signatures are sent, and when it is read: [Get an Operation](https://docs.aureahub.com/docs/tok-operation-get.md) reads the chain and moves it at once. [The list](https://docs.aureahub.com/docs/tok-operations-list.md) answers operations as stored.

## The Yield Token

A yield-bearing dollar token on Ethereum (`USDY`), and its rebasing form (`rUSDY`), whose balance grows instead of its price. Read its [price](https://docs.aureahub.com/docs/tok-yield-price.md), [buy](https://docs.aureahub.com/docs/tok-yield-subscribe.md) it with USDC, [sell](https://docs.aureahub.com/docs/tok-yield-redeem.md) it for USDC, or [convert](https://docs.aureahub.com/docs/tok-yield-convert.md) one form into the other. Buying and selling are at the oracle's price, within 0.1%: a chain that gives less reverts, and the operation is `failed` with `TOKENIZED_ASSETS_PRICE_MOVED`. For a tenant that offers the `yield_token` line.

## Corporate Actions

Dividends are reinvested: each token stands for a growing number of shares of its underlying — its multiplier ([Shares Multiplier](https://docs.aureahub.com/docs/tok-asset-multiplier.md), and per chain [Multipliers per Chain](https://docs.aureahub.com/docs/tok-asset-multipliers.md)). An issuer's announced actions — dividends, splits, mergers, a closure — are in its [calendar](https://docs.aureahub.com/docs/tok-asset-ca-calendar.md). [Corporate Actions](https://docs.aureahub.com/docs/tok-asset-corporate-actions.md) records the states and actions Aurea reads — paused, resumed, a new dividend, a new multiplier. While an asset is paused on a chain, its quotes, their execution and the yield token there are refused (`409` `TOKENIZED_ASSETS_ASSET_PAUSED`).

## The Secondary Market

Buying and selling an asset on the market, through third-party liquidity, from and to one of the user's own wallets: a [quote](https://docs.aureahub.com/docs/tok-secondary-quote.md) kept five minutes, an [approval](https://docs.aureahub.com/docs/tok-secondary-approve.md) of exactly the amount paid when needed, the [swap](https://docs.aureahub.com/docs/tok-secondary-execute.md), and for a wallet its owner signs for each step [signed and sent](https://docs.aureahub.com/docs/tok-secondary-broadcast.md). The same eligibility, documents and limits as a binding quote apply. Tokens bought this way cannot be redeemed from their issuer: show the user each answer's `disclosure`. Turned on per tenant [Coming soon, upon request](https://docs.aureahub.com/docs/feature-availability.md), in production only, for the assets traded with quotes.

## Retries

The routes that make, sign or send an operation, a step or an order take an optional `Idempotency-Key` header, required for a tenant on the institutional security profile (`400` `IDEMPOTENCY_KEY_REQUIRED`) — [Idempotency](https://docs.aureahub.com/docs/idempotency.md):

- the same key with the same request answers the first answer again (`idempotency-replayed: true`), as it was then; nothing is signed or sent twice;
- the same key with another request answers `409` `IDEMPOTENCY_KEY_REUSED`; while the first is running, `IDEMPOTENCY_IN_PROGRESS`; a key that is not one, `400` `IDEMPOTENCY_KEY_INVALID`;
- a request refused once something was signed or sent — a node refusing the transaction, a signing failure — leaves its key unusable (`409` `IDEMPOTENCY_OUTCOME_UNKNOWN`): read the operation, then retry with a new key.

Keys last 24 hours. On these routes a tenant's policy never holds an operation for approval: an institutional tenant's policy allows it or refuses it ([Policy Sets](https://docs.aureahub.com/docs/guide-policy-sets.md)).

## Events

An endpoint that names them receives `tokenized_asset.operation.quoted`, `.submitted`, `.completed`, `.failed` and `.expired` as an operation moves — with the operation as answered, without `steps`, and with its `userId` — sent when the move happens, during a request or as Aurea follows the operation in the background (Following an Operation, above). `tokenized_asset.paused`, `.resumed` and `.corporate_action` tell a pause on a chain, a resumption, a new dividend or a new shares multiplier of an asset your tenant offers, as [Corporate Actions](https://docs.aureahub.com/docs/tok-asset-corporate-actions.md) lists it. A testnet operation's or asset's events go to your sandbox endpoints, a mainnet one's to your production ones ([Event Types](https://docs.aureahub.com/docs/guide-events.md)). An endpoint with no `eventTypes` receives none of them: name them ([Webhooks & Events](https://docs.aureahub.com/docs/guide-events.md)).

## Provider Errors

What a provider answers is translated into Aurea's codes and words:

| Status | details.code | message |
| --- | --- | --- |
| 409 | TOKENIZED_ASSETS_MARKET_CLOSED | `The market is closed: try again when it opens.` |
| 409 | TOKENIZED_ASSETS_MARKET_PAUSED | `Trading is paused for the moment: try again shortly.` |
| 409 | TOKENIZED_ASSETS_ASSET_PAUSED | `Trading in this asset is paused.` |
| 409 | TOKENIZED_ASSETS_ASSET_LIMITED | `Trading in this asset is limited for the moment.` |
| 409 | TOKENIZED_ASSETS_ASSET_CLOSED_FOR_SESSION | `This asset does not trade in the current session.` |
| 409 | TOKENIZED_ASSETS_ASSET_SELL_ONLY | `This asset can only be sold.` |
| 409 | TOKENIZED_ASSETS_LIMIT_REACHED | `The order is above what can be traded now.` |
| 409 | TOKENIZED_ASSETS_SESSION_LIMIT_REACHED | `The order is above what can be traded in this session.` |
| 409 | TOKENIZED_ASSETS_TOO_MANY_OPEN_QUOTES | `Too many quotes are open: wait for one to be used or to expire.` |
| 409 | TOKENIZED_ASSETS_AFTER_HOURS_LIMIT_REACHED | `The after-hours limit of this asset has been reached.` |
| 409 | TOKENIZED_ASSETS_INSUFFICIENT_LIQUIDITY | `There is not enough liquidity for this order now.` |
| 409 | TOKENIZED_ASSETS_WALLET_NOT_REGISTERED | `The wallet that would hold the tokens is not registered for trading.` |
| 409 | TOKENIZED_ASSETS_CHAIN_PAUSED | `Trading on this chain is paused.` |
| 400 | TOKENIZED_ASSETS_INVALID_REQUEST | `The request is not valid.` |
| 400 | TOKENIZED_ASSETS_INVALID_AMOUNT | `The amount is not valid: a decimal above zero, within the limits.` |
| 400 | TOKENIZED_ASSETS_ORDER_TOO_SMALL | `The order is too small: its network costs are above its value.` |
| 400 | TOKENIZED_ASSETS_CHAIN_UNSUPPORTED | `This chain is not supported for this request.` |
| 404 | TOKENIZED_ASSETS_ASSET_NOT_FOUND | `There is no such asset.` |
| 404 | TOKENIZED_ASSETS_PROVIDER_NOT_FOUND | `Not found.` |
| 503 | TOKENIZED_ASSETS_PROVIDER_AUTHENTICATION_FAILED | `Tokenized assets are not available for this tenant at the moment.` |
| 503 | TOKENIZED_ASSETS_PROVIDER_READ_ONLY_KEY | `Binding quotes are not available for this tenant at the moment.` |
| 503 | TOKENIZED_ASSETS_PROVIDER_RATE_LIMITED | `Too many requests for this tenant at the moment: try again shortly.` |
| 503 | TOKENIZED_ASSETS_PROVIDER_UNAVAILABLE | `Market data and quotes are unavailable at the moment.` (also when no answer came within 10 seconds) |
| 503 | TOKENIZED_ASSETS_PROVIDER_UNEXPECTED_RESPONSE | `Market data and quotes are unavailable at the moment.` |
| 503 | TOKENIZED_ASSETS_PROVIDER_ERROR | `The request could not be completed.` |

A failure is never kept: the next request asks again. [Contact us for details](https://www.aureahub.com/contact).

---

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