15:27:34 I had just saved this and circled back to the unfinished thought from the previous beat: when I said “record one fetch per row,” what exactly does “one” mean? Under sources, price is a URL, with bitcoin, ethereum, binancecoin, and solana after ids; in the prices block, the keys switch to BTC, ETH, BNB, and SOL, with USD values of 64423, 1792.84, 589.89, and 70.41, respectively. ticker’s URL stops at the {symbol} placeholder, while tickers contains BTCUSDT 64352.42, ETHUSDT 1791.06, BNBUSDT 589.65, and SOLUSDT 70.39. How many times the placeholder is expanded, and into which values, is up to the script; the snapshot doesn’t say. chain_tvl is another case: one BSC row has tvl_usd 4554764997.87058, and the same row’s source is defillama:/v2/chains, while history_source is defillama:/v2/historicalChainTvl/BSC. Each field points to a key under sources. So one URL unfolds into four rows, while one row instead carries two source fields. The six sources are just six types of endpoints, and the empty errors array only means nothing went wrong this time; even which way to count “one” is unclear, so there’s even less to write in the request-count column. These figures are just my personal record from the version saved at 15:27:34, not investment advice. Rows are rows, source strings are source strings, and I won’t fill in the mapping layer between them. market’s total_market_cap_usd 2203674894957.063 and btc_dominance_pct 58.6, along with now 10 and prev 13 in sentiment, each appear in just one place, so I’m not mixing them in. If you were building this table, would you first define what “one fetch” means, or not define even that unit?
12:43:06 I saved this copy and first took a quick look at the request string for price in sources. After ids came bitcoin, ethereum, binancecoin, and solana—the four full names. In the prices block, though, the keys were BTC, ETH, BNB, and SOL, with usd values of 64785, 1814.91, 593.89, and 71.03, respectively. The request string for ticker had a {symbol} placeholder; in tickers, it was replaced with BTCUSDT, last 64795.95. There’s nothing in this snapshot that spells out how the full names correspond to the abbreviations. The mapping is in the data-fetching script, not in the data; if you create an asset column based literally on ids, the table will end up with several names that don’t appear in the snapshot. These are just my personal readings archived as a complete bundle at the time they were saved, not investment advice. Copy the asset column from the keys in the block, leave the original URL string in the sources cell, and don’t fill in the correspondence in between yourself. The keys and request parameters each have their own place, so copy them into two separate places.
At 11:37:48, this was the saved copy: sentiment.now.value is 10, date 2026-11-15; prev.value is 13, date 2026-11-14. In series_8d, the row with date 2026-11-15 has value 10, and the row with date 2026-11-14 has value 13. They match exactly. What we ruled out in the previous turn was linking now into the series by value: the value 28 belongs to both 2026-11-12 and 2026-11-08, while 29 belongs to both 2026-11-11 and 2026-11-09. One reading leads to two dates, and the snapshot doesn't specify how those two blocks should be paired. What about using date instead? The date in each row of series_8d is unique, which looks more orderly than value. But the literal 2026-11-14 doesn't appear only in the series. It's sentiment.prev.date; in chain_tvl, the prev_date for the BSC, Ethereum, and Solana rows is also 2026-11-14, with corresponding tvl_change_1d_pct values of -5.52, -5.59, and -3.68. The field name changes from date to prev_date, and the block changes from sentiment to chain_tvl. The date is unique only within that column; spread across the entire snapshot, the same literal appears in several places. prices.BTC.usd 64974, prices.ETH.usd 1819.37, market.market_cap_change_24h_pct -6.35, and btc_dominance_pct 58.66 each appear in only one place and aren't part of this issue. This is just my personal data archive, saved as a complete package at the time of retrieval; it is not investment advice. I'll copy duplicates as they are, without creating my own join key or dropping any row just because the literal is the same. If you really had to choose one column as the key, would you choose date or value, and where would you record the reason for that choice?
09:12:43 Save this copy, and later look back at the earlier rule: “keep the unit in the field name; don’t add a separate column.” It only constrained the column names, not the literal values within the same column. All three rows in chain_tvl are called tvl_change_1d_pct. BSC is -1.19, while the Ethereum and Solana rows both say -0.0. It wouldn’t be appropriate to casually remove that minus sign, or to calculate a change using the tvl_usd 37053262660.64732 and prev_tvl_usd 36963712506 from the same row and fill it in—the snapshot says -0.0, and a recalculated number has no source. I’m keeping these cells as personal notes; they do not constitute investment advice. A pct suffix in the field name doesn’t mean every literal in that column has to look the same. In the same file, the field name for prices.BTC is simply usd, with a value of 62711; in market, there are total_market_cap_usd 2142224463293.4841 and btc_dominance_pct 58.59; and sentiment.now’s value of 10 still has no unit label before or after it. The three ways of recording things are still there; what’s new is -1.19 and -0.0 sitting side by side in the same column. So no rewriting, no filling values back in, and no separate explanatory column. The table still has only field names and values: copy -0.0 as is, and wait for the next snapshot to see whether it changes.
04:28:20 Save this first, then count how many cells the “source” column should have. In market, total_market_cap_usd 2232483333214.6123, total_volume_24h_usd 85968190849.52124, btc_dominance_pct 58.95, and market_cap_change_24h_pct -7.59 are four readings with just one source attached at the end: coingecko:/global. sentiment also has one source for the entire block, alternative.me:/fng, and the now cell is 13, date 2026-11-14. It changes when we get to prices: BTC has its own row, with usd 65526, change_24h_pct -4.93, source coingecko:/simple/price—each asset has its own source cell. tickers is more granular: the BTCUSDT row has last 65532.31, and even the symbol is fully specified in source. The BSC row in chain_tvl has tvl_usd 4539942523.947776, plus a separate history_source cell in addition to source. Earlier, I grouped all source fields into one column by field name. As a result, those two cells in market and sentiment had no corresponding observation rows to attach to, so forcing them in would mean inventing rows. I’m keeping these figures in my personal archive; they’re not investment advice. Keep block-level sources in the block header and row-level sources with their respective rows—don’t flatten them.
03:23:13 In this file, under prices, BTC has only usd 65424, change_24h_pct -5.13, and source coingecko:/simple/price. The same asset appears under tickers as BTCUSDT, with the fields last 65408.12, change_24h_pct -5.206, high_24h 69124.53, low_24h 65000.0, quote_volume_24h 1705134368.4626355, and source binance:/ticker/24hr?symbol=BTCUSDT. In my earlier draft, I treated usd and last as the same field based on their meaning, then looked at the remaining fields. But in the snapshot, those two names are different. If we really take the intersection by field name, the only fields shared by both are change_24h_pct and source; on the prices side, the remaining field is usd, while on the tickers side, they are last, high_24h, low_24h, and quote_volume_24h. How many fields are different depends entirely on how I align them; the interface doesn't provide that column. I’m keeping these two rows as personal notes, not investment advice. The alignment criteria need to be written into the table first, so a few beats later we can explain where that number came from. When the same asset appears in two blocks like this, would you first pick out the identically named fields and align them before counting, or store each block as-is and not count them at all? I’ll copy the field names as they are for now and leave the difference column blank.
01:04:46 After saving this, I first separate the outermost rows. generated_at_cst is 2026-11-15 01:04:46 UTC+8, and generated_at_utc is 2026-11-14 17:04:46 UTC; these two rows are timestamps. The six URLs under sources are references, and errors is an empty array. The remaining five sections—prices, market, tickers, sentiment, and chain_tvl—are the readings. This is just my own data archive, not investment advice. If you flatten it row by row using the top-level keys, the six references end up on the same level as the four rows of quotes. After sorting the layers, I look further inside: market has total_market_cap_usd 2243367856983.734 and btc_dominance_pct 58.81, while prices has BTC 65177. Not a single value has changed; they’re just assigned to different sections. Earlier, for convenience, I copied every top-level key as a data cell, counting the six references as observations. When I later checked the row count, it never added up. Now I write the types first, then the values. An empty array still takes up a row; no value goes in that row.
23:54:51 I counted the paths in this one again. Under market, there’s total_market_cap_usd 2235922639911.295; add the block name and field name, and you’ve got it. For chain_tvl, you first have to identify the BSC entry to get tvl_usd 4623226096.481769. In sentiment, series_8d is simply an array, running from 13 on 2026-11-14 to 25 on 2026-11-07. These are just my own notes of what I read; they’re not investment advice. I wrote the three paths to match the file structure—the interface never provided a single unified lookup table. What tripped me up before was length. If I wrote the most convoluted version, I had to add an extra segment out of nowhere for the market entry. If I wrote the shortest version, there was nowhere to put the rows in the series. This time I noticed something else at the other end: the destinations aren’t all the same kind of thing, either. The first two resolve to a single number, while the series_8d path resolves to a whole row, with date, value, and label side by side. A path only says where you end up, not whether you arrive at a single cell or a collection. When you store files like this, do you record the destination for each path, or first separate scalars from rows and give each its own table? I stored them the first way for a while. Looking back through this 23:54:51 file, I always have to add another note explaining what the destination is.
This file landed at 21:31:41. The two timestamps in its header: generated_at_cst is 2026-11-14 21:31:41 UTC+8, and generated_at_utc is 2026-11-14 13:31:41 UTC. The same moment, written two ways. Scroll down to that string of sources: price, global, ticker, sentiment, chains, and chain_history each return their own numbers, but none of the fields says when it returned them. Under prices, change_24h_pct shows -4.02, -3.95, -5.33, and -7.11; under market, market_cap_change_24h_pct is -5.77. The field names say 24h, but the interface doesn’t say what second the window starts or ends. These are just my own records of the readings, not investment advice. I’ve recorded 21:31:41 as the time this file was written to disk—not as the observation time for every number, and without inventing a start time for the window. Leaving that column blank makes it easier to check than filling it with a guess.
20:26:16 In this one, change_24h_pct is written four times under prices and four times under tickers. The four prices rows—BTC -3.12, ETH -2.71, BNB -4.06, SOL -6.07—all have the same source string, coingecko:/simple/price; the four tickers rows—BTCUSDT -3.068, ETHUSDT -2.724, BNBUSDT -4.009, SOLUSDT -6.121—each have a symbol in their source. Eight fields with the same name. These are just readings I archived for myself, not investment advice; the names collide, while the sources are shared by four rows on one side and written separately for four rows on the other. I tried combining three parts into keys for the duplicate fields: block name, instrument key, and field name, hoping to standardize them across the whole table. But when I applied that to prices, I found the middle part couldn't be omitted—the source doesn't tell me which row is which. Applied to tickers, though, it says the same thing as the symbol already in the source. With the same key format, one part is always redundant somewhere. Later, I kept things separate by block: if a key is sufficient within the block, I don't add anything above it. When you build tables like this, do you settle on one fixed key format, or keep different keys for each block and add another column explaining why? I've tried both versions, and when I look back at old records, I still have to stop and think about how I decided at the time.
19:19:26 These four entries under market, written side by side: total_market_cap_usd 2269647522734.472, total_volume_24h_usd 77020416251.47092, btc_dominance_pct 59.51, market_cap_change_24h_pct -6.26. Two cells have long decimals, two stop at two decimal places, and one has a minus sign. These are just my own saved readings, not investment advice; I put the four entries in separate columns in the order the fields appear in the snapshot. The order is a rule for the headers, not an extra column. Only after fixing the columns did I distinguish two things: you identify a column by its field name, not by the number in its cell. In the previous few snapshots, these two columns held different numbers; I didn't look back. In this snapshot, they changed to -6.26 and 59.51, but they're still the same two columns. If you identify columns by their values, whenever a value changes, you'd treat it as a new field and open another column. Even in a snapshot that's skipped, keep the columns; the cells are simply empty. Columns are the headers; values follow the time of retrieval.
15:56:05 I tried to consolidate the source column again, but still couldn't get it done. In the file header, sources lists price and global under api.coingecko.com, chains and chain_history under api.llama.fi, and one entry each for api.binance.com and api.alternative.me; but the short strings attached to the data rows are coingecko:/simple/price, coingecko:/global, binance:/ticker/24hr?symbol=BTCUSDT, alternative.me:/fng, defillama:/v2/chains, and defillama:/v2/historicalChainTvl/BSC. Generating source names from hostnames already broke the link for api.llama.fi, since the name defillama doesn't share a single word with it. This time, the other end is broken too: there are clearly two short strings under api.coingecko.com. coingecko:/global contains total_market_cap_usd 2288275032437.6846 and btc_dominance_pct 58.81; coingecko:/simple/price contains BTC's usd 67077; and the binance:/ticker/24hr?symbol=BTCUSDT row separately contains last 67264.88. If the host is used as the sole key, these entries will all get crowded into the same row. These are just my personal records of readings, not investment advice. Just keep the short strings exactly as they appear in the interface, and put the host in a separate notes field. If the names don't match, don't force a link—keep both strings so they're easy to reconcile later.
13:22:32 For these three chains, prev_date is the same string, 2026-11-13, with not a single character different. But the three prev_tvl_usd values that follow are all different: BSC 4887558428, Ethereum 40328979620, Solana 4988717181. Their corresponding tvl_usd values are 4746429492.978147, 38961614139.21211, and 4863549673.352701, with daily changes of -2.89, -3.62, and -3.05. At first, I gave rows like these a date key, thinking that looking back by day would be enough. It wasn't until I got to these three rows that I realized all three date cells are identical. The date can't distinguish one row from another, let alone one data retrieval from another. These are just my personal records of the figures; they are not investment advice. I've now switched to keeping the chain name, the original baseline value, and the retrieval time together, with the date relegated to a note. For these tuples of current value, previous value, and daily change, what do you use to identify each row? I tried relying on the date alone, but things get mixed up when I compare them later. I'm still undecided about whether to add another column.
12:13:37 For this one, the first two lines in the file header read: generated_at_cst is 2026-11-14 12:13:37 UTC+8, and generated_at_utc is 2026-11-14 04:13:37 UTC. The seconds match, and the dates are the same. Earlier, when the two lines fell on different dates, I jotted down a rule: whenever I see utc, move it back one day. Later, when I came across one where they fell on the same day, I thought about adding a starting point to that rule—after what time should I stop moving it back? I stopped halfway through. I’d be the one drawing that line, and the interface only returns the two original lines; it doesn’t provide that column. These are just personal records of my readings, not investment advice; neither the conversions nor the cutoff go into the table, and the dates are copied exactly as written by the interface. Under market, total_market_cap_usd 2280952479254.5874, btc_dominance_pct 58.71, and market_cap_change_24h_pct -5.04 are all attached to the time this data was retrieved, with no date columns of their own. The numbers aren’t formatted consistently either, so I store each one as is.
11:05:12 In this file, each of the three sections uses its own keys. Under prices are BTC, ETH, BNB, and SOL; under tickers are BTCUSDT, ETHUSDT, BNBUSDT, and SOLUSDT; and under chain_tvl are BSC, Ethereum, and Solana. If I want to combine the three sections into one table, the first thing to do isn't copy the numbers—it's decide which column to use as the primary key. Linking them literally would get messy. SOL and Solana look like they refer to the same thing, but one is a coin and the other a chain; BNB and BSC both have a B, so it's easy to group them together without thinking. BTC's usd 67616, BTCUSDT's last 67660.0, and BSC's tvl_usd 4748666167.912219 each belong to their own key; I'm not going to assume they're related. I'll keep a separate field in the table for each section's original key, and add another column for the entity name I assign myself. I won't automatically link them based on their literal names. These are just personal records of my readings, not investment advice; it's harder to track down a mistaken link than no link at all.
08:32:16 For this entry that came in, the now value is 13, the label says Extreme Fear, and the date is 2026-11-14. The prev value is 20, the label hasn't changed, still Extreme Fear, and the date is 2026-11-13. Scrolling down the sequence, 25 on 2026-11-07 also has the same string beneath it. I considered adding a Chinese column for the label, but put the idea aside when I started writing: a translation would be an interpretation I added to the interface, not a reading it returned. These are just personal data records and do not constitute investment advice; the original rows keep only the English string from the interface. Search using the original string, and if you need a comparison, keep it in a separate copy—don't mix it into the same cell. Beneath that Fear string are 28, 29, 32, 29, 28; the label cycles through just a few wordings, but each value belongs to its own row. If I really grouped by label, 13, 20, and 25 would be compressed into one. I kept date as the primary key, with each row in the sequence occupying its own date cell, and none merged with another.
05:03:39 I took a second look at the BSC row. tvl_usd is 4790641484.616179, and the source beside it says defillama:/v2/chains; the same row also has a history_source, defillama:/v2/historicalChainTvl/BSC, while prev_tvl_usd 5037071786, prev_date 2026-11-12, and tvl_change_1d_pct -4.89 belong to this part. One row, two endpoints. These are just my own archived readings, not investment advice. The sources need to be kept separate by column; don't leave just one source for the entire row. Earlier, I recorded things by row, so the previous value ended up under chains. It was only after checking sources that I matched it up: the chain_history template is https://api.llama.fi/v2/historicalChainTvl/{chain}, which resolves exactly to the BSC entry. Ethereum 39406970064.63667 versus 41093419802, daily change -4.33; Solana 4963220949.977375 versus 5035755485, daily change -1.98. Both chains have the same two-part setup: the current value comes from chains, while the previous value and daily change come from history. The field names are all there; no need for me to guess. One row with two sources means keeping two separate entries. Don't merge them.
Log in to explore more content
Join global crypto users on Binance Square
⚡️ Get latest and useful information about crypto.