Skip to main content

Set token price

Set a token's price on its own price feed, read it in another currency, and see when the platform refuses a stale price.
Open it fromAssetsAll assetsActionsSet priceRole:Permission managerConsole address: /token/assetClassSlug/templateSlug/tokenAddress/manage/action

Set a token's price by hand from its Actions menu. The price is held in the token's own price feed, an on-chain record of the latest price and the time it was observed. Valuations, portfolio totals, value history, the token price read of the Platform API and value-based compliance rules read that feed, with two exceptions How the platform reads the price describes: holdings value a bond from its face value and its denomination asset's price, and the on-chain price resolver can fall back to a base price claim. The platform reads the price in the currency a caller asks for, converts it through exchange-rate feeds, and refuses a price older than its feed's staleness window.

Four sources write to a token's price feed:

  • A holder of the token's “Permission manager” role sets the price by hand, as this page describes.
  • Issue asset seeds it when a token is created with a declared price.
  • A holder of the “Feeds manager” role publishes a value from the feed's row on Data feeds.
  • A price source publishes a provider's price after the platform checks it, as described in Price sources.

Feed registration and staleness windows are set on Data feeds, and the currencies a price can convert into are set on Exchange rates.

The “Edit token price” page with “Current price” above the “Price” and “Currency” fields.

On a token that already has a price, the page is titled “Edit token price” and shows “Current price” at the top, then the “Price” field, the “Currency” field and a Review button. On a token without a price, the page is titled “Set token price” and has no “Current price”.

Steps

Open the token's price form

Open “All assets” under “Assets”, select the token, then select Actions in the token header.

Select “Set price” for a token with no price yet, or “Edit price” for a token that has one. The page is titled “Set token price” or “Edit token price”, and it opens under the asset with a breadcrumb back to it. When the token already has a price, the page shows it as “Current price” at the top.

Enter the price and the currency

Enter the price per token in Price as a positive decimal number, for example 100.50. Zero, a blank and a negative number are refused with “Enter a price greater than zero, such as 100.50.” Use no more decimal places than the token's price feed stores: 8 for a feed the platform created, or the decimals a feeds manager chose for a feed registered on Data feeds. A longer price is refused beside the field, for example “Enter a price with at most 8 decimal places. The data feed stores no more.”, and “Review” stays closed until you shorten it. The platform does not round the price you enter.

Choose the currency in Currency. The form offers 12 currencies, USD, EUR, GBP, JPY, CHF, CAD, AUD, AED, SGD, SAR, MYR and ZAR. The form preselects the token's current currency, or USD for a token with no price.

Review and confirm

Select Review. The review step shows “Token” with its name and symbol, “Current price” when the token has one, and “New price”.

Select Confirm price and complete wallet verification.

The platform queues the price as a transaction, and the Console shows Setting price… while that transaction is queued or running. It shows “Token price updated successfully” only after the transaction completes on chain. If the transaction fails, the Console shows an error instead and no success message. If it has not settled when the Console stops watching, the Console shows “Still processing. Track progress in Actions.” and the price may not be set yet. Valuations read the new price after the indexer records it, so check it against the You should see list before you rely on it.

How a token's price is declared

The first price set for a token creates its price feed in the same request. The platform creates an issuer-signed feed, one that accepts a price only when a claim key of an identity that the trusted issuers registry trusts for the token's price topic signed it. The feed has 8 decimal places and the description SYMBOL / CURRENCY, for example NWC / USD. The part after the slash is the feed's currency. Every later price goes to that feed, and the feed keeps the currency it was created with.

The organisation's operations signer, the custody account the platform uses to sign on the organisation's behalf, signs every declared price under the organisation's on-chain identity. The platform checks that the person who sets the price holds the “Permission manager” role on the token, and asks for wallet verification. The feed itself checks only the signature, so a holder of a claim key on a trusted identity can publish to it without going through the platform.

Setting a price is a transaction that the platform queues. Valuations read the new price once the indexer, the platform service that records on-chain events, has recorded the feed update. Each set-price request is recorded on the organisation's Audit trail with the price and currency before the change and the price and currency requested.

A token created with a declared price gets its feed and first price at creation. For a precious-metal token the declared price is the weight per token times the spot price per unit. A token whose asset-type template requires the maturity redemption feature gets no price feed at creation. The template decides: a create request that sends maturity redemption settings for a template without the feature still gets its declared price published. If the organisation has no operations signer bound when the token is created, the token is created without a price.

How the platform reads the price

In the currency you ask for

The token price read answers in the currency you name, or in USD when you name none. In the feed's own currency it returns the price and the time of the observation. In another currency it converts the price through the organisation's exchange-rate feeds, using only rates that are inside their own staleness windows and at most three conversions. The answer lists each conversion: the currency pair, the rate, the exchange-rate feed's address, the rate's update time, and whether the rate was inverted.

When no path of fresh rates reaches the currency you asked for, the read returns the price in the feed's currency with convertible set to false, the reason no_fx_path, and availableCurrencies, the currencies the price can reach. Prices are exact decimals with 18 decimal places, and each conversion rounds down at the last place.

The read uses only the token's own price feed. It does not fall back to a last known price, to a value derived for a bond from its denomination asset, or to a base price stored as a claim on the token's on-chain identity.

A stale price is refused

A price is stale when its observation is older than the feed's staleness window. The window that applies is the feed's own window, or the global default when the feed has none. Both are set on Data feeds. A window can also be set to never expire.

The token price read refuses a stale price with DALP-0343, HTTP 503, and data.reason set to stale-feed. The same code answers every case where the token has no usable price, and data.reason names which one:

data.reason
What the platform found
What to do
no-feed
No price feed is registered for the token.
Set a price, or map the token in a price source.
feed-not-indexed
The feed is registered but the indexer has not recorded it.
Read again after the indexer catches up.
registration-date-missing
The indexed feed has no registration date.
Read again after the indexer catches up.
inactive-feed
The feed is not active.
Check the feed on Data feeds.
unsupported-quote
The feed's description does not name a fiat currency.
Replace the feed with one described as SYMBOL / CURRENCY.
unanswered-feed
The feed has never published a value.
Set a price.
stale-feed
The latest observation is older than the feed's staleness window.
Publish a fresh price.

On chain, the price resolver applies the same windows and reverts with DALP-1111, “Stale feed”. The error names the token, the price topic, the observation's update time and the window it was measured against. A value-based compliance rule that reads a stale feed price refuses the action. On a token with a capital-raise limit, a mint is refused with a compliance failure whose reason is a stale price, until a fresh price is published. These checks do not use the last known feed price.

The on-chain resolver has one path the API read does not. When a token has no price feed, the resolver can fall back to a base price stored as a claim on the token's on-chain identity. It accepts only a claim from an issuer that the trusted issuers registry trusts for the base price topic. A new resolver starts with this fallback on, and a feeds manager can turn it off. A claim carries no time, so no staleness window applies to it.

Valuations and history

The indexer records every change to a token's indexed price, with the price in its own currency and in the organisation's base currency. A change to a relevant exchange rate adds a new base-currency value. The price in effect at a moment is the last one recorded at or before that moment. Portfolio values and profit and loss at a past date, and the 24-hour price change of a holding, use this history.

Holdings value a bond, or a token with the maturity redemption feature, from its face value times the indexed price of the asset it redeems into. That derived value needs no price feed on the bond and follows its denomination asset's price and the relevant exchange rates. When you attach the maturity redemption feature to a token that already has its own price feed, the platform removes that feed after queueing the attach, so a feed that no longer prices the token does not stay active. If the removal fails, the attach still goes ahead and the platform logs a warning. The token price read still needs the bond's own price feed.

An external token that no DALP system issued records no price history, because each system that registers it prices it separately.

Troubleshooting

Set price cannot be selected in Actions

A greyed-out item means the role sits on another of your wallets, which the menu names: switch to that wallet. When the item is missing, none of your wallets holds Permission manager. Ask a holder of that role to grant it, or to set the price.

The price is refused after wallet verification

DALP-12353 means the wallet that signed does not hold the token's administrator role, shown in the Console as Permission manager. DALP-0345 means your account has no on-chain identity on the active network, or the organisation has no eligible operations signer for price declarations. DALP-0346 means the system has no price feed factory installed. Ask an administrator to install the price feed system. A retry alone clears none of these.

The price is refused for having too many decimal places

The token's price feed stores a fixed number of decimal places, 8 for a feed the platform created. The Console refuses a longer price beside the field, and the Platform API answers DALP-12245, HTTP 400. Shorten the price to the feed's decimal places and submit it again. Nothing was queued, so there is no failed transaction to clear.

A token shows no price

The Price card says “This token has no price feed.” when no price has ever been set or mapped. Set a price, or map the token's ISIN in a price source.

A price read or a mint fails because the price is stale

The latest observation is older than the feed's staleness window. Publish a fresh price, by hand or from the price source. Change the window on Data feeds only when the asset's pricing rules accept older prices.

The read answers in the feed's currency instead of the one I asked for

No chain of up to three fresh exchange rates links the two currencies. Check availableCurrencies in the answer for the currencies the price can reach, and check on Exchange rates that the currency you need is tracked and its rate is current.

The token is priced in the wrong currency

The feed keeps the currency it was created with, so a new price with another currency does not change it. A feeds manager can replace the token's price feed with one described in the right currency, from the feed's row on Data feeds. Everything that read the price before the replacement read it in the old currency.

API routes

The Platform API offers three routes for a token's price:

  • POST /api/v2/tokens/{assetId}/price sets the price, with price as a decimal string, currencyCode and walletVerification. The platform answers 202 with the queued transaction by default. Send Prefer: wait=<seconds> to wait for settlement. An empty transaction hash means the feed already held that price. A retry with the same idempotency key does not create a second feed or publish twice. A price with more decimal places than the token's price feed stores is refused with DALP-12245, HTTP 400, before anything is queued. The platform judges it against the decimals of the feed already registered for the token, or the 8 decimal places of the feed a first price creates, and never rounds it.
  • GET /api/v2/tokens/{assetId}/price?currency=EUR reads the price in the named currency, with each conversion step.
  • GET /api/v2/tokens/{assetId}/price-history?preset=trailing1Month reads the price over a window. preset is one of allTime, ytd, trailing12Months, trailing6Months, trailing3Months, trailing1Month, trailing7Days and trailing24Hours. Each point carries the price in the base currency in force at that time, and null where the price was cleared. The series is empty when the token had no price in the window, and the time before its first price is left out rather than reported as zero. The route answers token not found for a token issued to another organisation, as the token read does.

Set a price

The request body carries the price, the currency and the wallet verification. The PIN in this example is illustrative:

{
  "price": "100.50",
  "currencyCode": "EUR",
  "walletVerification": { "verificationType": "PINCODE", "secretVerificationCode": "482913" }
}

Without a Prefer header the platform answers 202 with a handle. Poll statusUrl, also sent as Location, and do not resend the request:

{
  "transactionId": "0198f1a2-3c4d-7e8f-9a0b-1c2d3e4f5a6b",
  "status": "QUEUED",
  "statusUrl": "/api/v2/transaction-requests/0198f1a2-3c4d-7e8f-9a0b-1c2d3e4f5a6b"
}

With Prefer: wait=30, a write that settles in time answers 200 with the feed, the transaction hash, the price and the currency:

{
  "data": {
    "feedAddress": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0",
    "txHash": "0x2a8f0d4c1b6e39a7c05d8f21b4e7a63c9d0f5b18e24a7c36d91b0f8e5a3c7d24",
    "price": "100.50",
    "currencyCode": "EUR"
  },
  "meta": {
    "txHashes": ["0x2a8f0d4c1b6e39a7c05d8f21b4e7a63c9d0f5b18e24a7c36d91b0f8e5a3c7d24"]
  },
  "links": { "self": "/api/v2/tokens/0x71C7656EC7ab88b098defB751B7401B5f6d8976F/price" }
}

Read a converted price

price is a whole number scaled by decimals. In this answer to GET …/price?currency=USD, the feed holds 100 AED, the AED to USD rate is 0.2723, and 27230000000000000000 with 18 decimals is 27.23 USD:

{
  "data": {
    "tokenAddress": "0x71C7656EC7ab88b098defB751B7401B5f6d8976F",
    "price": "27230000000000000000",
    "currency": "USD",
    "decimals": 18,
    "source": "feed",
    "sourceCurrency": "AED",
    "convertible": true,
    "updatedAt": "2026-08-14T09:30:00.000Z",
    "conversionPath": [
      {
        "from": "AED",
        "to": "USD",
        "rate": "272300000000000000",
        "feedAddress": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0",
        "updatedAt": "2026-08-14T09:30:00.000Z",
        "inverse": false
      }
    ]
  },
  "links": { "self": "/api/v2/tokens/0x71C7656EC7ab88b098defB751B7401B5f6d8976F/price" }
}

When no chain of fresh rates reaches the currency, the answer keeps the feed's currency and lists the currencies it can reach. This answer to GET …/price?currency=JPY is illustrative:

{
  "data": {
    "tokenAddress": "0x71C7656EC7ab88b098defB751B7401B5f6d8976F",
    "price": "100000000000000000000",
    "currency": "AED",
    "decimals": 18,
    "source": "feed",
    "sourceCurrency": "AED",
    "convertible": false,
    "targetCurrency": "JPY",
    "reason": "no_fx_path",
    "message": "No conversion path from AED to JPY exists in the configured price feeds directory.",
    "availableCurrencies": ["EUR", "USD"],
    "updatedAt": "2026-08-14T09:30:00.000Z",
    "conversionPath": []
  },
  "links": { "self": "/api/v2/tokens/0x71C7656EC7ab88b098defB751B7401B5f6d8976F/price?currency=JPY" }
}

Was this page helpful?