Support tax-loss harvesting
Find lots that would sell at a loss, show them to the account owner, and sell exactly the lots they pick.
Part of Show tax data in your app. Tax loss harvesting means selling lots that are worth less than they cost, so the realized loss offsets gains. To support it, your app shows the account owner which lots would sell at a loss at today's price and lets them sell those lots specifically.
Before you begin
- A bearer token. See Authenticate.
- Current inventory for the account. See Know when inventory and gains are current.
- Current prices from your platform for the assets the account holds.
List the account's assets
Call GET /v1/inventory/summaries for the assets the account holds, as in Retrieve inventory. Each entry names an asset to check.
Price each asset's lots
For each asset, call GET /v1/inventory with its asset_code and your current price. The examples continue Send transactions and read gains: the account holds 1.5 ETH bought at $3,250, and ETH is now $2,900.
curl -G $BASE_URL/v1/inventory \
-H "Authorization: Bearer $TOKEN" \
--data-urlencode "account_id=acct_5f2e7d10" \
--data-urlencode "asset_code=ETH" \
--data-urlencode "price=2900"{
"data": {
"asset": { "code": "ETH", "name": "Ethereum", "type": "Crypto", "uuid": "b7a005b5-f4d5-44ea-ae80-d4f9e8313558" },
"lots": [
{
"id": "b72696f9-0f10-5827-94c3-289b6366a599",
"acquisition_datetime": "2026-02-14T16:20:11Z",
"term": "short-term",
"quantity": "1.5",
"fiat_asset_code": "USD",
"cost": "4875.00",
"unit_cost": "3250.00",
"current_value": "4350.00",
"unrealized_gain_loss": "-525.00",
"percent_unrealized_gain_loss": "-0.10769"
}
],
"lots_ordered_by": "HIFO"
}
}Lots with a negative unrealized_gain_loss would sell at a loss. Show them with their term and keep their id, which the sale needs. Lots with missing_cost_basis: true have no cost to compare with, so leave them out.
Sell the chosen lots
When the account owner sells, send the sale with disposition_method set to SPECID and the chosen lots in inventory_lots on the sent line item, keyed by lot id. Here the account owner sells 0.5 ETH from the February lot:
curl -X POST $BASE_URL/v1/transactions/external-id \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"id": "trade_88230",
"account_id": "acct_5f2e7d10",
"type": "trade",
"datetime": "2026-09-22T15:12:00Z",
"disposition_method": "SPECID",
"sent": [{
"asset_amount": { "amount": "0.5", "asset": { "code": "ETH", "type": "Crypto" } },
"rates": [{ "amount": "2900.00", "asset": { "code": "USD", "type": "Fiat" } }],
"inventory_lots": {
"b72696f9-0f10-5827-94c3-289b6366a599": { "quantity": "0.5" }
}
}],
"received": [{
"asset_amount": { "amount": "1450.00", "asset": { "code": "USD", "type": "Fiat" } },
"rates": [{ "amount": "1.00", "asset": { "code": "USD", "type": "Fiat" } }]
}]
}'The lot quantities must add up to the line item's amount. Cost-basis method reference lists every SPECID rule. Once inventory has caught up, Retrieve gains shows the sale as a $175 short-term loss: 0.5 ETH sold for $1,450 against a cost of $1,625.
Where to go next
- Choose a cost-basis method: how SPECID fits with the account's default method.
- Back to Show tax data in your app.
Updated 12 days ago
