Documentation Index
Fetch the complete documentation index at: https://docs.moralis.com/llms.txt
Use this file to discover all available pages before exploring further.
Question it answers
“Give me the USD / native mark price history for token 0x…, newest first — and the freshest mark right now so I can value a position that hasn’t traded recently.”Token Prices is the valuation join target across Data Feeds. Any “what is this worth in USD” question — a transfer’s value, a portfolio’s worth, a trade’s notional — joins a token’s mark at a given block from this feed.
What you get
The recipe lands one row per in-block price update — Moralis’ continuous mark for each(token, pair, protocol) at the block it changed. A token traded across several pairs or protocols produces several marks per block; the table keeps them all, keyed for by-token lookups.
| Column | Description |
|---|---|
token_address | The token the mark prices |
pair_address | The pair the mark was observed on |
protocol | The DEX/protocol that produced the mark |
usd_price | USD mark, carried as text for full precision — cast at read time |
native_price | Native-asset mark (e.g. ETH), text for full precision |
block_number, event_ts | When the mark was set (block height and block time) |
tx_hash | Transaction the price update came from |
chain_id | Chain the mark belongs to |
latest_token_price_dict dictionary keeps the freshest mark per (chain_id, token_address) for O(1) carry-forward valuation of tokens that haven’t updated recently.
Source
The transform reads one per-block array —tokenPriceUpdates — and lands one row per entry. Each entry is Moralis’ mark for a (token, pair, protocol) at that block. There is no read-time join: every mark is already a row keyed by token.
Destination
| Destination | Table | Read pattern |
|---|---|---|
| ClickHouse (first-class) | fact_token_price_update (+ latest_token_price_dict) | Prefix scan on (chain_id, token_address, event_ts); read with FINAL or sum(sign) |
| Postgres | token_price_updates | Index on (token_address, block_number DESC) |
| MySQL | token_price_updates | Index on (token_address, block_number) |
latest_token_price_dict dictionary holds the carry-forward mark for quiet positions.
Full schema
Below is the complete read table this recipe produces. It’s a starting point: keep the columns you need and drop the rest (see Schema & flexibility).usd_price and native_price are carried as text to preserve full precision across many orders of magnitude — cast at read time.
ClickHouse — fact_token_price_update
ClickHouse — fact_token_price_update
sign column drives reorg collapsing — read with FINAL or sum(sign). A single-node setup can use CollapsingMergeTree(sign) without the replication path. Inside the dictionary the WHERE sign = 1 is safe (not the bare-WHERE anti-pattern) because FINAL has already collapsed the ±1 reorg pairs.Postgres — token_price_updates
Postgres — token_price_updates
DECIMAL(38,18) for the price columns. position is the block-level cursor used during backfill. The explicit NUMERIC(38,18) precision keeps room for marks that span many orders of magnitude.Example reads
A token’s price history, newest first (ClickHouse):Modes
Shipped defaults: ClickHousehybrid (backfill → realtime), Postgres / MySQL historical (one-shot backfill). For live/reorg-safe ingestion, use ClickHouse — see the overview.
The realtime reorg path needs a single-column
UNIQUE on the position column, but position is block-level — many price updates share one block — so the array-expanded rows can only carry a composite unique. Run realtime/hybrid on ClickHouse, where the collapsing log table corrects reorgs per-block. The Postgres / MySQL configs are intended for historical backfill.Multichain
The recipe is chain-parametrized via thechain setting — point it at any supported EVM chain or Solana. On Solana, the same logIndex can be assigned to multiple events in one instruction, so the event identity is widened with pairAddress (or protocol) to keep marks distinct; the price feed it produces is identical in shape.
Fidelity and valuation notes
- Precision.
usd_priceandnative_priceare carried as strings end-to-end to preserve full precision; cast at read time (toDecimal*on ClickHouse, theNUMERIC/DECIMALcolumns on Postgres / MySQL). - Multiple marks per block. A token priced on several pairs/protocols lands one row per
(pair, protocol)per block. Pick a venue (filterpair_address/protocol) or aggregate (argMax) depending on whether you want a specific venue’s mark or a representative one. - Carry-forward staleness. The
latest_token_price_dictrefreshes every 30–60s, so a quiet token’s mark is at most ~a minute stale without needing a fresh price event — but it does not interpolate between updates.
Related
Token Transfers
The per-token transfer ledger you value against these marks.
Portfolio Tracking
Token Prices is the valuation join target behind portfolio worth.

