# List an address's wallet transfers

`GET /api/market/transfers`

The transfers built with the wallet tools that an address took part in (as payment or ordinals address), newest first. Each names only that address's part (`owner_role`).

#### Query parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `address` | string | yes | A payment or ordinals address. |
| `status` | string | no | `pending` (what you still have to watch: in the mempool, not yet known, or dropped in a chain of replacements that pays someone else, which a cancel voids) or `all` (default). One of: `pending`, `all`. |
| `limit` | integer | no | 1-100, default 20. (min 1, max 100) |

#### Example request

```bash title="cURL"
curl 'https://raresats.net/api/market/transfers?address=bc1p5cyxnuxmeuwuvkwfem96lqzszd02n6xdcjrs20cac6yqjjwudpxqkedrcr&status=all&limit=5'
```
```js title="JavaScript"
const response = await fetch('https://raresats.net/api/market/transfers?address=bc1p5cyxnuxmeuwuvkwfem96lqzszd02n6xdcjrs20cac6yqjjwudpxqkedrcr&status=all&limit=5');
const data = await response.json();
```
```python title="Python"
import requests

data = requests.get("https://raresats.net/api/market/transfers", params={"address": "bc1p5cyxnuxmeuwuvkwfem96lqzszd02n6xdcjrs20cac6yqjjwudpxqkedrcr", "status": "all", "limit": 5}).json()
```

#### Response `200`

| Field | Type | Description |
| --- | --- | --- |
| `transfers` | array of object | Newest first. |
| `transfers[].id` | string | The prepared transfer's id. |
| `transfers[].txid` | string | Its transaction id (what `/tx/{txid}` shows). |
| `transfers[].kind` | string | One of: `extract`, `send`, `send_n`, `chop`, `consolidate`, `multisend`, `speedup`, `cancel`. |
| `transfers[].status` | string | `pending` in the mempool; `confirmed` in a block; `replaced` by a speed-up or cancel built here (`replaced_by`); `conflicted`: a block spent its inputs and it was provably not mined (its own outputs never appeared within six blocks); `dropped`: in no mempool and its inputs unspent (it may still resurface until voided); `unknown`: the broadcast's outcome is not known yet; `rejected`: bitcoind refused it, so it was never sent and cannot resurface. |
| `transfers[].created_at` | integer | Unix seconds. |
| `transfers[].updated_at` | integer | Unix seconds. |
| `transfers[].owner` | object | The owner's addresses (one transfer's read). |
| `transfers[].owner.payment_address` | string | Paid the fees. |
| `transfers[].owner.ordinals_address` | string | The ordinals address. |
| `transfers[].owner_role` | string | The queried address's part in it (a list read). One of: `payment`, `ordinals`, `both`. |
| `transfers[].destination` | string \| null | Where the moved sats went (`null` for a multisend). |
| `transfers[].fee_rate` | number | sat/vB. |
| `transfers[].network_fee` | integer | Sats. |
| `transfers[].tools_fee` | integer | The flat raresats.net fee it paid, in sats. |
| `transfers[].vsize` | integer | Its size in vbytes. |
| `transfers[].replaces` | string \| null | The transfer it replaced (speed-up, cancel). |
| `transfers[].replaced_by` | string \| null | The transaction that replaced it. |
| `transfers[].block_height` | integer \| null | The block it confirmed in. |
| `transfers[].outputs` | array of object | Its outputs. |
| `transfers[].outputs[].index` | integer | vout. |
| `transfers[].outputs[].address` | string \| null | Who it pays. |
| `transfers[].outputs[].value` | integer | Sats. |
| `transfers[].outputs[].role` | string | `dest`, `return`, `plain_return`, `tools_fee` or `change`. |
| `transfers[].actions` | object | What its owner can do now. |
| `transfers[].actions.speedup` | boolean | It is pending: a speed-up can replace it. |
| `transfers[].actions.cancel` | boolean | It could still confirm (pending, unknown, dropped) and its chain of replacements pays someone else: a cancel (or a void) sends its sources back. It never hides a cancel the prepare would allow; the prepare decides with the mempool (409 nothing_to_cancel). |
| `total` | integer | How many transfers match without `limit` (with `status=pending`: everything you still have to watch). |

```json title="Response"
{
  "transfers": [
    {
      "id": "6baec47455bf8df8",
      "txid": "a1edadb9e3b45097d272621ea8adcbee697281bd4d611462db134292d4e1cf9c",
      "kind": "extract",
      "status": "pending",
      "created_at": 1791428236,
      "updated_at": 1791428236,
      "owner_role": "ordinals",
      "destination": "bc1p5cyxnuxmeuwuvkwfem96lqzszd02n6xdcjrs20cac6yqjjwudpxqkedrcr",
      "fee_rate": 3,
      "network_fee": 1059,
      "tools_fee": 1000,
      "vsize": 352,
      "replaces": null,
      "replaced_by": null,
      "block_height": null,
      "outputs": [
        {
          "index": 0,
          "address": "bc1p5cyxnuxmeuwuvkwfem96lqzszd02n6xdcjrs20cac6yqjjwudpxqkedrcr",
          "value": 388,
          "role": "return"
        },
        {
          "index": 1,
          "address": "bc1p5cyxnuxmeuwuvkwfem96lqzszd02n6xdcjrs20cac6yqjjwudpxqkedrcr",
          "value": 330,
          "role": "dest"
        },
        {
          "index": 2,
          "address": "37VucYSaXLCAsxYyAPfbSi9eh4iEcbShgf",
          "value": 9282,
          "role": "plain_return"
        },
        {
          "index": 3,
          "address": "bc1p4hefchfnn06cn2xmk6fq6xcw5ew260q2dptc4c35fcazgedmzlcqkxf057",
          "value": 1000,
          "role": "tools_fee"
        },
        {
          "index": 4,
          "address": "37VucYSaXLCAsxYyAPfbSi9eh4iEcbShgf",
          "value": 22941,
          "role": "change"
        }
      ],
      "actions": {"speedup": true, "cancel": false}
    }
  ],
  "total": 1
}
```

#### Errors

`{error, code}`; see [Errors](https://raresats.net/docs/errors.md) for every code.

| Status | Code | Meaning |
| --- | --- | --- |
| 400 | `bad_address` | An address is not a mainnet address (or not one at all). |
| 400 | `bad_paging` | `limit` or `offset` out of range. |
| 400 | `bad_status` | `status` is not `all` or a comma-separated list of offer statuses, or (wallet transfers) not `pending` or `all`. |
| 422 | `legacy_address` | A legacy (P2PKH, `1…`) address: use Taproot or SegWit. |
| 422 | `unsupported_address` | An address type the marketplace does not trade (only Taproot, native SegWit and nested SegWit). |
| 503 | `market_unavailable` | The marketplace is closed right now (its backends disagree on the network, or are unreachable). |

```json title="Error (400)"
{"error": "address must be an address", "code": "bad_address"}
```

These are the transfers built with the wallet tools ([Prepare a transfer](https://raresats.net/docs/prepare-transfer.md)), not the site's feed of notable rare-sat transfers (`GET /api/transfers`, see [Supply, rows and status](https://raresats.net/docs/site-feeds.md)). Each record shows only the queried address's side (`owner_role`). This is not a privacy boundary: a transfer spends from both of the wallet's addresses in one transaction, which links them on chain anyway.

`status=pending` lists what you still have to watch: transfers in the mempool or whose broadcast is not known yet, and **dropped** transfers of a replacement chain that pays someone else (the transfer itself, or an original it replaced by a speed-up or cancel). A signed transaction that left the mempool can resurface and confirm until something else spends its inputs; a [cancel](https://raresats.net/docs/guide-speed-up.md) of the listed one spends every input of the chain, so it voids them all. A dropped transfer whose chain pays only your own addresses is not listed: if it resurfaces, the sats still end up in your wallet. `total` counts the matching transfers without `limit`.

To follow changes live, listen for the `transfer` event of [Live events](https://raresats.net/docs/live-events.md#transfer-events): it names the addresses whose transfers changed, then read this again.
