Address activity
GET/api/address/{address}/activity
What an address bought and sold (every marketplace), listed and cancelled on raresats.net, extracted, mined and moved, newest first, with filter facets and totals. Transfers and extractions come from the index's per-address history (from the ordinals era) where it has one, read as far as the pages asked for need it; else from the moves it keeps (about 4 weeks); before either, the address's held UTXOs. coverage says which and how far; summary.partial says when the totals cover only the history read so far. Pages follow next (pass it as before), which does not drift when newer activity arrives. Cacheable 15 s. The first page (no before, no to) leads with the address's pending items (pending: true, source: mempool), outside limit, total and the facets; pending=0 leaves them out. A sale here the index shows pending is listed once, as the index's.
Path parameters #
| Parameter | Type | Required | Description |
|---|---|---|---|
address | string | yes | A mainnet address. |
Query parameters #
| Parameter | Type | Required | Description |
|---|---|---|---|
types | string | no | Comma-separated activity types: bought, sold, listed, cancelled, extraction, mined, transfer_in, transfer_out, consolidation. |
row | string | no | Only activity of this row (collection) id. |
marketplace | string | no | Only sales and listings of this marketplace id (magisat, magic_eden, raresats, …). |
year | integer | no | Only activity of this UTC year. (min 2009) |
from | string | no | Only activity on or after this UTC day, YYYY-MM-DD. |
to | string | no | Only activity on or before this UTC day, YYYY-MM-DD. |
limit | integer | no | Page size, at most 200. Default: 50. (min 1, max 200) |
before | string | no | The previous page's next. |
pending | string | no | 0 leaves the pending (mempool) items out. One of: 0, 1. Default: 1. |
Example request #
curl 'https://raresats.net/api/address/bc1p5cyxnuxmeuwuvkwfem96lqzszd02n6xdcjrs20cac6yqjjwudpxqkedrcr/activity?types=bought,sold'const response = await fetch('https://raresats.net/api/address/bc1p5cyxnuxmeuwuvkwfem96lqzszd02n6xdcjrs20cac6yqjjwudpxqkedrcr/activity?types=bought,sold');
const data = await response.json();import requests
data = requests.get("https://raresats.net/api/address/bc1p5cyxnuxmeuwuvkwfem96lqzszd02n6xdcjrs20cac6yqjjwudpxqkedrcr/activity", params={"types": "bought,sold"}).json()Response 200 #
| Field | Type | Description |
|---|---|---|
address | string | The address. |
as_of | object | null | {height, time} of the index. |
explorer | string | null | Block explorer base URL. |
coverage | object | How complete each source is. |
coverage.sales | string | Sales: every one, from the sales index. One of: complete, loading, unavailable. |
coverage.transfers | string | since block N: transfers and extractions from block N on (the history's start, or the retained moves'), and before it only the held UTXOs; complete (a history from genesis, read whole); holdings (only the held UTXOs); or unavailable. |
coverage.transfers_since | integer | null | N of since block N; null when complete. |
coverage.source | string | null | Where transfers come from. One of: fork_history, moves_window, holdings, null. |
coverage.history_from | object | Where the per-address history begins (the ordinals era, the fork's address_history_from_height): {height, time}. |
coverage.history_from.height | integer | |
coverage.history_from.time | integer | null | |
coverage.history_complete | boolean | Whether the whole history has been read (the fork has no more pages). Until then the totals and facets cover the history read so far, and pages read further as they go. |
coverage.loaded_since | integer | null | While the history is read in part: the oldest block read so far. |
coverage.loaded_since_time | integer | null | Its time, unix seconds. |
coverage.market | string | raresats.net listings. One of: complete, off, unavailable. |
coverage.error | string | Set when the index could not be read: transfers may be missing. |
summary | object | Totals over all of the address's activity known (no filter): sales and listings whole, the history as far as read. |
summary.bought | object | |
summary.bought.count | integer | |
summary.bought.volume | integer | Sats. |
summary.sold | object | |
summary.sold.count | integer | |
summary.sold.volume | integer | Sats. |
summary.extractions | integer | |
summary.listed | integer | |
summary.transfers | integer | Transfers, consolidations and mined. |
summary.first_time | integer | null | Unix seconds of the first activity shown. |
summary.last_time | integer | null | Unix seconds of the last. |
summary.partial | boolean | True while the history is read in part: the extraction and transfer counts and the first activity cover the history read so far. |
facets | object | Counts for the filters, each under every other filter set, over the activity known (the history as far as read). |
facets.types | map of integer | By type. |
facets.rows | map of integer | By row id. |
facets.years | map of integer | By UTC year. |
facets.marketplaces | map of integer | By marketplace id. |
rows | map of object | The rows named on the page and in the facets: label and types. |
rows.<key>.label | string | |
rows.<key>.all_of | array of string | |
query | object | The filters applied. |
total | integer | Events matching the filters among those known (the history as far as read; see summary.partial). |
items | array of object | One page, newest first. |
items[].id | string | Stable id (the cursor names it). |
items[].type | string | What happened, from the address's side. One of: bought, sold, listed, cancelled, extraction, mined, transfer_in, transfer_out, consolidation. |
items[].time | integer | Unix seconds: the block's time, or the marketplace event's. |
items[].height | integer | null | Block height; null for an event off the chain (a listing). |
items[].tx_index | integer | null | Place in the block (null while pending). |
items[].txid | string | null | Transaction id; null for a listing. |
items[].tx_url | string | null | The transaction on the block explorer. |
items[].sat | object | null | The lead sat (the rarest moved, the first sold). |
items[].sat.sat | integer | |
items[].sat.types | array of string | |
items[].count | integer | null | Tracked sats involved. |
items[].row | string | null | The main row id (its rarest). |
items[].rows | array of string | Every row id the event counts toward (the category filter). |
items[].price | integer | null | Sale or listing price, sats. |
items[].unit_price | number | null | Price per sat of row, over the sold output's own value. |
items[].marketplace | string | null | Marketplace id, for sales and listings. |
items[].inscribed | boolean | null | A sale of an inscribed sat. |
items[].outlier | boolean | null | A sale far from its row's median. |
items[].secondary | map of integer | A sale's secondary rows: the market rows of the other sats it sold (not its own row, a row it is a sub-category of, or a label row), each with its sats, primary-first: {"black_omega": 1} for a black omega sold with an alpha uncommon; {} for none. A sale never counts in its secondary rows' markets (the primary-sat rule, in Concepts). |
items[].value | integer | null | Sats in the UTXOs received or sent, for a transfer. |
items[].extracted | boolean | null | The rare sats arrived in (or left) an extracted UTXO. |
items[].counterparty | string | null | The other side's main address: the seller of a purchase, the buyer of a sale, the sender or recipient of a transfer. |
items[].counterparties | integer | null | How many addresses were on the other side. |
items[].source | string | Where it comes from: the sales index, the marketplace, the per-address history, the retained moves, a held UTXO's creation, or the index's mempool overlay (pending). One of: sales, market, history, moves, holdings, mempool. |
items[].seq | integer | The sale's sequence number (sales only). |
items[].outpoint | string | null | The listed UTXO (listings only). |
items[].burn | boolean | A transfer_out to an unspendable output. |
items[].pending | boolean | Not yet in a block: a pending transaction (source: mempool, with first_seen and fee_rate, no height), or a sale bought or sold on raresats.net the index has not read yet (source: market). Only the first page lists the former, first. |
items[].first_seen | integer | null | When the transaction was first seen in the mempool (bitcoind's entry time), unix seconds. |
items[].fee_rate | number | null | Its fee rate, sat/vB (one decimal). |
next | string | null | The cursor of the next page (pass as before), or null at the end. While the history is read in part, a page may hold fewer events than limit, even none, with a next that reads further. |
pending_total | integer | Pending items leading items (first page only; outside total, the facets and the summary). |
Errors #
{error} (a message, no code):
| Status | When |
|---|---|
| 400 | Not an address, or a malformed parameter or cursor. |
| 404 | A retired row (uncommon_2009, rare_2009): its retired field names the row and years to ask for instead. |
| 503 | Too many lookups at once. |
The address page's Activity tab reads this route. One list, newest first, merges:
| Type | From | Complete |
|---|---|---|
bought, sold | the sales index (every marketplace) | yes |
listed, cancelled | raresats.net | yes |
extraction, mined, transfer_in, transfer_out, consolidation | the index's per-address history, else the moves it keeps | see coverage |
A transaction that is one of the address's sales is shown once, as the sale; a sale of a bundle names its secondary rows (the other sats sold with its row). A raresats.net purchase shows as pending until its block is read.
Pending. The first page (no before, no to) leads with the address's transactions still in the mempool: sales it is selling or buying, transfers in and out, extractions. Each has pending: true, source: "mempool", first_seen, fee_rate, and no height. They match the type, row and date filters but sit outside limit, total, the facets and summary (pending_total counts them); once mined they come back as ordinary items. A raresats.net purchase the index already shows pending is listed once, as the index's item. pending=0 leaves them out. See Pending.
coverage.transfers is since block N: transfers and extractions are whole from block N, where the index's per-address history starts (the ordinals era, coverage.history_from). Before block N, only the UTXOs the address still holds are listed, as transfer_in items with source: "holdings". Until the index serves the history, transfers cover the moves it keeps, about 4 weeks.
A busy address has tens of thousands of entries, so the history is read lazily: each page reads as much of it as it needs, newest first. Until all of it has been read, coverage.history_complete is false, coverage.loaded_since says how far back it goes so far, and summary.partial is true. In that case the extraction and transfer counts, the facets and total cover the history read so far. Sales and listings are always whole. Type, row and date filters are passed down to the index, so a filtered page skips what cannot match.
facets count each filter's values under the other filters, so a chip can say what choosing it would show. summary totals everything known, whatever the filters.
To page, pass next as before with the same filters. The cursor names the last event shown, so newer activity arriving at the top shifts nothing. While the history is still being read, a page may hold fewer events than limit, even none, with a next that reads further. Keep following next until it is null.
curl 'https://raresats.net/api/address/bc1p5cyxnuxmeuwuvkwfem96lqzszd02n6xdcjrs20cac6yqjjwudpxqkedrcr/activity?types=bought,sold&limit=20'