Skip to main content
An airdrop needs a fixed list: who held the token at a chosen ledger, and how much. The Assets API answers holders at a past ledger with as_of_ledger, so the list does not change while you compute allocations or when people move funds afterwards. Set these once in your terminal. The sample values are real Testnet data, so the read examples return real results.
Pick the snapshot ledger and the total amount to distribute:
as_of_ledger reads cover ledgers from read_view.bootstrap_ledger (5253887 on Testnet) up to a few minutes behind the tip. For an older ledger, use a snapshot job.

Check the ledger

One request shows the holder count at that ledger and confirms the history answers it:

Build the allocation

The script reads every holder at the ledger, keeps accounts (contracts such as pools and vaults are left out), and splits AIRDROP_TOTAL in proportion to balance with integer math. It writes airdrop.csv.
Output for Testnet BTC at ledger 5300000:
Each share rounds down, so the rows add up to slightly less than AIRDROP_TOTAL. Send the remainder (AIRDROP_TOTAL minus the sum of the airdrop column) to the largest holder, or keep it. Keep the snapshot ledger and the CSV together: anyone can recompute the list from the same ledger and get the same rows.

Rules for past-ledger reads

  • The answer is the state after the ledger closed. supply and as_of_closed_at are null at a past ledger; holder_count is the count at that ledger.
  • A ledger after the latest applied one is 400. A ledger the history cannot answer exactly (before bootstrap_ledger, or the last few minutes) is 409 history_unavailable; the message says which.
  • Assets with more than 100,000 current holders return 409; use a snapshot job.
  • Publishable (lum_pub_) keys cannot use as_of_ledger.

Older ledgers

For a ledger before bootstrap_ledger, or a token with more than 100,000 holders, start a snapshot job. It returns up to the top 10,000 holders at any ledger from 63 on. On Testnet the job is free (one request toward the daily Testnet cap):
Poll GET /snapshots/{id} until status is completed, then read result.records. If result.truncated is true, the token had more than 10,000 holders at that ledger and the list holds only the largest 10,000: the airdrop would leave out the smallest holders, so decide whether that is acceptable before you distribute. See Historical snapshots for the full job flow.

Credits

On Testnet these reads are free: the script above makes 2 requests toward the daily Testnet cap of 10,000. On Mainnet, as_of_ledger reads answer 501 not_implemented, so this recipe runs on Testnet only. See Limits and credits.

Next