A price source connects one price provider, such as a custodian's end-of-day file, a market-data vendor or a trading counterparty, to the price feeds of your tokens. The platform fetches the provider's prices, checks each one, and publishes the prices that pass to the token's price feed.
The organisation's operations signer, the custody account the platform uses to sign on the organisation's behalf, signs each published price. Use this page to add a source, map its instruments, decide held prices and act when a feed goes stale.
Use Token pricing to set a price by hand, and Data feeds for feed registration and staleness windows.
A source works with ISINs. An ISIN, short for International Securities Identification Number, is the 12-character code that identifies a security. The provider names each price by ISIN, and you map each ISIN to the token whose feed receives the price. A token that has no price feed gets one when you map it, quoted in the mapping's currency.
The “Sources” tab lists each source with its protocol, the number of mapped instruments, the time of its last delivery and its status, and an “Add source” button.
Steps
Add the source
On the “Sources” tab, select Add source. It opens the “Add source” page, which reads “Connect a vendor price source. It is saved inactive.”
Under How the source delivers prices, choose one method:
- File for a file on an SFTP server. A file source then asks for its “File format”, “CSV” or “ISO 20022 reda.001”.
- FIX for a FIX market data session.
- REST for a vendor request. A vendor request then asks for its “Vendor”, “Bloomberg Data License” or “LSEG DataScope Select”.
The fields that follow match that choice, in the sections “Source”, “Protocol”, “Prices”, “Credential”, “Publishing” and “Timing”. Connection fields lists them.
A source keeps its delivery method for its whole life, because its credential and connection fields follow from it. To change the method later, add a new source and map the ISINs again.
These values decide when a price reaches the feed:
- Publish after a move of (bps) sets how far a price must move from the last published price before it is published. A basis point, bps, is one hundredth of a percent.
- Or at least every (hours) is the heartbeat: a newer price is published after this interval even when it moved less than the threshold. A heartbeat never re-stamps an old price. Leave it empty for no heartbeat.
- Hold above (percent) sets how far a price may move before it is held.
- Expected every (hours) is how often the provider delivers.
- Expected lag (hours) is how long after its observed time a price normally arrives.
- Stale after (hours) is the age at which a price counts as stale. It applies only when the feed's staleness window, its own or the global default on Data feeds, is set to never expire.
The heartbeat plus the expected interval plus the expected lag must be shorter than the staleness bound. The bound is the feed's staleness window, its own or the global default, when that window is finite, else “Stale after”. Otherwise the form refuses the source with “The heartbeat plus the expected interval plus the expected lag comes to <total>, which is not shorter than the <bound> staleness bound. Shorten one of them or raise Stale after.” The form fills <total> and <bound> with the two durations. The rule keeps the feed from going stale between two deliveries.
The form refuses a host that is a loopback, private or metadata address, and a FIX session without TLS outside the deployment's endpoint allow list. Use the provider's public host name.
Enter the credential and select Add source. A “Confirm the credential” dialog asks for your PIN. The credential is stored in the platform secret store and is never shown again. The source is saved as “Draft”.
If the source was saved but the credential was not, the page says “The source was added without its credential”. Enter the credential again and select Save credential, or select “Open source” and add it there.
Test the connection
Open the source and select the “Connection” tab. Test connection opens a session with the source and checks that it answers. It fetches and publishes nothing. The result says “The source answered” or “The connection failed” with the reason, and names the egress IP address the provider saw, so you can give it to the provider to allow.
For an SFTP source, a host key the server offers that is not trusted yet shows its fingerprint. Compare it with the fingerprint your provider published, select Trust this host key only if the two match, and confirm with your PIN.
Map the instruments
Open the “Instruments” tab and select Map instrument. The sheet asks for five values:
- ISIN, the code the provider names the price by.
- Token, the token whose feed receives the price.
- Price field, the field that holds the price in a delivery.
- Price basis is “Per unit” or “Percent of par”. “Percent of par” needs the “Par amount”, the value one token stands for in the price currency. The token price is then the quoted price times the par amount divided by 100. A quote of 98.50 with a par amount of 1,000 gives a token price of 985.
- Currency, the three-letter ISO code of the price currency, such as EUR.
The sheet shows whether the platform creates a feed for the token, the token's face value, and the price per token that the latest delivery of the ISIN would give. Confirm with your PIN. When the source is active and the platform already holds a delivery for the ISIN, that price goes through the checks as the feed's first price. Otherwise the feed waits for the next delivery.
The currency must match the currency of the token's existing price feed, and the platform refuses a different one with DALP-14712. A token whose feed another source already maps cannot be mapped again, and the platform refuses it with DALP-14710. One ISIN can feed several tokens. An active FIX source requests prices for a new mapping within about 10 seconds, and the provider's snapshot then prices the feed.
The table has the columns “ISIN”, “Token”, “Price field”, “Basis”, “Currency”, “Price”, “Last seen” and “Actions”. With nothing mapped it reads “No instruments mapped” and “Map an ISIN to a token to publish its price to a feed.”
Unmatched ISINs lists the ISINs that arrived without a mapping, and “Map” on a row opens the sheet with the ISIN filled in. With none it reads “No unmatched ISINs”.
Unmap ends a mapping after a confirmation that prices for the ISIN stop reaching the token's feed from this source. The feed keeps its last price, an open held price on that feed is cancelled, and an open stale-feed case for it is resolved.
Activate the source
Select Activate and confirm with your PIN. The source needs a saved credential, or the page says “Add a credential on the Connection tab to activate.” After activation, the source fetches on its schedule and publishes the prices that pass the checks.
If a mapped token has nobody who can approve a held price, a callout says “Some tokens have no one who can approve a held price” and names the tokens. Grant the “Feeds manager” role to another person, or the “Governance” role on the token, before a price is held. Without one, a held price waits with nobody able to decide it.
Decide a held price
A held price appears in two places. The Held prices tab of the source lists it, with the number of open held prices in the tab label and the columns “Instrument”, “Last published”, “Received” and “Reason”. With none it reads “No held prices”.
The Actions page shows a row that names the ISIN and the source, with “Review held price”, for each price you may decide. A held price with nobody eligible to decide it reads “No one can approve this yet”.
Open it to see the Review held price sheet. It shows the “Source”, the “Received price”, the “Last published” price, the “Change” against the source's hold tolerance, the “Price field”, the “Observed” time and the “Reason held”, which reads “Moved past tolerance” or “Correction”.
The Evidence section shows the record, its sequence number, when it was recorded and the evidence digest, and “Show the raw payload” opens the provider's message.
Compare “Received price” with “Last published” and the “Reason held”. Select Approve to publish the price, or “Reject” and give a reason. Both ask for your PIN. A price you may not decide says “This price needs another approver.”
If the platform refuses your decision, the sheet names the reason and shows the current state: “A newer price was published”, “The price changed since you opened it”, “This price is past its bound”, “Someone already decided this price”, “This price changed while you were deciding”, “The source is paused” or “The source has stopped”. Read the sheet again before you decide a second time. A paused source can still have a held price rejected, and cannot have one approved.
Review deliveries
The Deliveries tab lists each delivery with the time it was “Received”, its “Status”, its “Records”, and how its prices settled: “Rejected”, “Accepted”, “Dropped”, “Held” and “Published”. “Status” reads “Received”, “Failed validation”, “Malformed file”, “Evidence lost” or “Blocked egress”.
Select Load older deliveries for earlier ones. With none the tab reads “No deliveries yet” and “Run Test connection on the Connection tab to see the egress IP to allow.”
Fetch, pause and resume a source
The source page header shows “Instruments”, “Published today”, “Held” and “Last delivery”. “Published today” counts from 00:00 UTC.
- Fetch now asks an active SFTP, Bloomberg or LSEG source to fetch at once instead of waiting for its schedule. It asks for no PIN. The button reads “Fetching” while it runs, then says how many deliveries the fetch produced, or “Nothing new from the provider”. A FIX source streams its prices and offers no “Fetch now”. The person who requests a fetch cannot decide a price it holds.
- Source actions holds “Pause”, “Resume” and “Rotate credential”. A paused source publishes nothing. “Resume” asks for your PIN.
Replace or remove the credential
Choose “Source actions” › Rotate credential. It opens the “Replace credential” sheet, which reads “Enter the new credential. The previous one stays in use until the provider accepts the new one.”
Select Replace credential. The Console confirms “Credential replaced”. Rotating the credential does not exclude you from deciding held prices.
On the “Connection” tab, the credential panel shows the last characters the saved credential ends in and its version, never the credential. It offers “Replace”, “Add credential” and Remove. “Remove” deletes the credential after your PIN, and an active source refuses the removal, so pause it first.
The settings panels on the “Connection” tab edit the connection, the publishing values and the timing. Save asks for your PIN.
Retire a source
Retire source, on the “Connection” tab, ends the source for good after a confirmation. The source stops fetching, its feed and ISIN mappings are freed for another source, it cannot be activated again, and its held prices still waiting for a decision are cancelled. A retired source keeps its settings read-only.
Read the source list
The Sources tab lists each source with “Source”, “Protocol”, “Instruments”, “Last delivery” and “Status”, and “Search sources” filters it by name. A source that has delivered nothing reads “No delivery yet”. An empty list says “No price sources yet”.
“Status” reads “Draft”, “Active”, “Paused”, “Retired”, “Retrying” or “Needs attention”. “Retrying” means the last fetch failed and the source tries again on its own. “Needs attention” carries the reason: the provider refused the credential, a connection setting needs a change, or the last delivery could not be read.
Connection fields
The Source section holds the “Name”. The fields in the other sections follow the delivery method:
The Credential section asks for a “Credential type”, “Password” or “Private key”, with “Password” or “Private key” and “Passphrase (optional)” to match, or for a vendor “Logon username”, “Client ID” and “Client secret”. The credential is stored in the platform secret store, is write-only and is never shown again. Select “Cancel” to leave the page without saving.
Held prices and the second approver
A price that moves further from the last published price than the source's hold tolerance, or that corrects a price the source already delivered for the same instrument, price type and observed time, is a held price. What happens to it depends on the organisation's Prices approval rule, in the “Approvals” section of General:
- With “Prices” set to Second person required, the price waits in a queue and nothing is published until a second person approves it. This maker-checker control covers held prices only.
- With “Prices” set to Not required, the platform publishes the price without a second person and records it as not approved by a second person. Actions shows it as “No second approval (approval off)”.
Every approval rule starts off in a new organisation, so turn Prices on before you activate a source if held prices must be reviewed.
When the rule is on, a feeds manager or a governor of the token decides the held price. A person who set up the source, changed its settings, mapped or unmapped an instrument, trusted its host key, or requested the delivery with Fetch now cannot decide it. Rotating the credential does not exclude you. This rule keeps one person from deciding a held price on a source they control. It does not cover a value published by hand on Data feeds or Token pricing, which a trusted issuer publishes with no second person, or a price that moves less than the hold threshold.
What the platform checks before it publishes
Every delivered price becomes an observation with its ISIN, price, currency, price type, observed time and source. The raw delivery is kept off chain as evidence with its hash. The checks run in this order, and the first that applies decides the outcome:
- A repeat of a price already recorded, with the same value, is dropped as a duplicate.
- A price at or below zero is refused as invalid.
- A price for an ISIN with no mapping is recorded as unmapped and listed under Unmatched ISINs.
- A token price, after the price basis is applied, that the feed's decimals cannot hold exactly is refused as invalid.
- A currency other than the feed's currency is refused as a currency mismatch. It is not held.
- An observed time earlier than the feed's latest is refused as out of order, and its time is not moved forward. A time more than 60 seconds ahead of the chain is refused as future dated. A time up to 60 seconds ahead waits until chain time reaches it.
- A different value for the same instrument, price type and observed time is a correction and is held. A FIX message with a higher sequence number than each earlier price that differs from it is not a correction.
- A move from the last published price beyond Hold above (percent) is held.
- The first price of a feed, a move of at least the publish threshold, or a newer price after the heartbeat interval is published. Any other price is skipped.
A held price then follows the organisation's Prices approval rule, as described in Held prices and the second approver.
A feed has at most one open held price. A later price that would also be held attaches to it as the latest candidate, and an approval publishes that newest candidate. A later price that passes the checks replaces the held price. Freshness counts from the provider's observed time, not from the moment of publishing, so a late approval does not make a feed look fresher than the provider's price is.
When a feed goes stale
The platform checks every mapped feed once a minute against the chain's time. A feed is stale when its latest observed price is older than the staleness bound: the feed's staleness window, its own or the global default, when that window is finite, else the source's Stale after. A feed with no price yet counts from the time it was mapped. A feed with neither bound is not judged. A paused source is still judged, and a retired one is not.
For each stale episode the platform opens one operations case. The “Cases” tab of Custody lists it as Stale price feed. Only an organisation owner or a platform administrator sees that tab, whether or not the custody books are turned on. The case detail names the token, the bound, since when the feed is stale, the source and the cause:
- The source is paused.
- The source is failing with a transient, credential, configuration or data failure.
- A price is held awaiting review.
- A price is awaiting custody approval before it is published.
- Deliveries since the last publish were dropped as older than the feed's newest price.
- The latest delivery could not be published.
- The latest delivery was refused by the checks.
- The latest delivery has been received but not processed yet.
- The source has delivered no price since the last publish.
The case resolves when a fresh price lands, when the feed is unmapped, or when the source is retired. A feed that turns fresh and then stale again reopens it. Platform operators also get a stale-feed metric and alert rule, described in Price source prerequisites.
Troubleshooting
A source needs attention
Open the source and read the status. If the provider refused the credential, replace it from Source actions. If a connection setting needs a change, the “Connection” tab names it. Check the timing too: the heartbeat, the expected interval and the expected lag together must stay shorter than the staleness bound. If the last delivery could not be read, open “Deliveries” and check the status of the latest one. A source stopped by a credential or configuration failure publishes nothing until you change the cause, then select “Pause” and then “Resume” in “Source actions”.
A delivery shows “Blocked egress”
The provider refused the platform's outbound address. Run Test connection on the “Connection” tab to see the egress IP, and ask the provider to allow it.
A price that moved past the tolerance was published without review
The organisation's “Prices” approval rule is Not required. Turn it on in the “Approvals” section of General. Prices delivered after that wait for a second person.
Nobody can approve a held price
The row on the Held prices tab reads “No one can approve this yet”, and its review sheet reads “No eligible approver”. Only a feeds manager or a governor of the token can approve a held price, and never a person who set up the source or requested the delivery. Grant the “Feeds manager” role to another person, or the “Governance” role on the token. Then open the price again.
An ISIN arrives but no price reaches the feed
Check Unmatched ISINs on the “Instruments” tab: an ISIN with no mapping publishes nothing. Check that the source is active, because a draft or paused source publishes nothing. Check that the mapping's currency matches the currency of the token's feed. Then check “Deliveries” for how the prices settled.
I cannot approve a price I expected to decide
You set up the source, changed its settings, mapped or unmapped an instrument, trusted its host key, or requested the delivery. Any of these puts you in the group that cannot decide its held prices. Ask another feeds manager, or the governor of the token, to decide it.
The “Price” card shows “Stale”
The price is older than the feed's staleness window on chain time. Open the Stale price feed case on the “Cases” tab of Custody, which names the cause. A held price waits for review, a paused source publishes nothing, and a source that stopped delivering needs its provider checked.
API routes
The same work is available through the Platform API under /api/v2/price-sources and /api/v2/held-prices. A feeds manager uses them with a signed-in session or an API key, and a governor reads and decides the held prices of their own tokens. Activating a source, editing its settings, setting or removing its credential, trusting a host key, mapping instruments and deciding a held price need a signed-in session and wallet verification, so an API key is refused for them. Read and submit price feeds lists the routes and their error codes.