Two production-grade patterns ship today on the XRP Ledger. They solve different problems and live in different threat models. Knowing which is which is the whole game.
"Dynamic NFT" is a marketing word that hides two genuinely different mechanisms. Both are live on XRPL. Both produce metadata that changes after mint. They differ in who you trust and what it costs to update.
The NFT is minted with the tfMutable flag. The URI baked on-chain is stable; the JSON it points to is regenerated on every request by your server.
The issuer rewrites the NFT's URI on-chain by signing an NFTokenModify transaction. New URI is proven by consensus, not by the issuer's word.
| Concern | Pattern 1: Mutable URI | Pattern 2: NFTokenModify |
|---|---|---|
| Cost per update | ~0 (one HTTP request) | One XRPL transaction fee |
| Update latency | Instant | One ledger close (~3–5s) |
| Survives issuer downtime | No — server gone, metadata gone | Yes — URI lives in ledger state |
| Update history | Whatever the server logs | On-chain, queryable forever |
| Holder can verify state without issuer | No | Yes |
| Issuer can revoke past states | Yes (replace metadata) | No (history is permanent) |
| Right for: live game stats, profile cards, feed reactions | Yes | Overkill |
| Right for: provenance, regulated records, badges | Risky (no audit trail) | Yes |
All are on mainnet. Connect a wallet and the Dynamic NFTs sub-tab inside NFT Studio surfaces every mutable-flag NFT you hold, what's changed, and a path to modify the ones you issued.
Mints once, reflects your wallet's current state forever. Tier evolves as XRP balance crosses thresholds.
Updates as your account's Harvest-Now-Decrypt-Later score changes. Earned after rotating to multi-sig + master-disabled.
Capture a tweet as a Living NFT. Engagement tier (Bronze → Silver → Gold → Legendary) updates as likes accumulate.
Brewery-signed NFT for premium sake bottles. Each ageing/storage event becomes a new on-chain entry.
The /api/nft/card/:address, /api/nft/quantum/:address, and /api/nft/tweet/:tweetId endpoints all stamp a SHA-256 content hash onto every response and use it as the ETag. Image URLs auto-bust with ?v={hash} so wallets and marketplaces refresh their cached art the moment the metadata changes. Cache-Control is public, max-age=60, must-revalidate — clients pick up updates within ~1 minute, but no regenerate-on-every-request for hot wallets. If-None-Match short-circuits with 304 Not Modified when nothing has changed.
The shared dNftMutateService builds NFTokenModify transactions as pure functions. Validates the issuer r-address and the 64-character hex NFTokenID. Round-trips UTF-8 URI strings (Japanese-language URIs work). Emits the transaction JSON; signing stays with the wallet adapter (Crossmark, GemWallet, WalletConnect, Xaman). Kairo Vault never handles secret material.
Lists every mutable-flag NFT you hold, grouped by "issued by you" vs "held from other issuers". Per-NFT card surfaces taxon, flags, current URI, and previews the metadata. Refresh re-fetches Pattern-1 metadata; "Modify on-chain" opens a Pattern-2 form for NFTs you issued.
You don't need a fork of rippled, a sidechain, an oracle network, or an off-chain indexer to ship dynamic NFTs on XRPL. Both patterns above run on stock mainnet today. The only good reason to add infrastructure beyond what's described here is when your specific use case requires something neither pattern provides — and most don't.