# List offers

`GET /api/market/offers`

Offers filtered by UTXO, seller, bidder, row and status, sorted by price, unit price, age or expiry, paged. Without `status`, only active offers. A wallet's "offers made" are `bidder=<address>`, its "offers received" `seller=<address>`.

#### Query parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `outpoint` | string | no | Only offers on this UTXO (`txid:vout`). |
| `seller` | string | no | Only offers to this address (that held the UTXO when the offer was made). |
| `bidder` | string | no | Only offers made by this address (the bidder's payment or ordinals address). |
| `row` | string | no | Only offers whose own row is this one (as always); with `sub=1` also those on UTXOs the row holds whole (marked `sub`), and with `contains` those on bundles holding some of its sats, apart. |
| `sub` | string | no | With `row`: `1` also answers the offers on UTXOs the row holds whole, as a rarer sub-category or a label (marked `sub`). One of: `0`, `1`. Default: `0`. |
| `contains` | string | no | With `row`: `1` also answers, apart, the offers on UTXOs holding only some sats of the row among others (in bundle) as `contains` (the first `limit`) and `contains_total`, each marked `in_bundle` with `contains_count`; `only` answers those alone as `offers`/`total`. Their unit price is their own row's, so `sort=unit` orders them by price. One of: `0`, `1`, `only`. Default: `0`. |
| `status` | string | no | `all`, or a comma-separated list of `active`, `pending`, `accepted`, `cancelled`, `expired`, `invalid`. Default: `active`. |
| `sort` | string | no | `price` (the default), `unit` (unit price), `new` (creation time) or `expiry` (offers with no expiry last). One of: `price`, `unit`, `new`, `expiry`. Default: `price`. |
| `order` | string | no | `desc` (the default; `asc` for `expiry`) or `asc`. One of: `asc`, `desc`. |
| `limit` | integer | no | Offers per page, 1-200. Default: `50`. (min 1, max 200) |
| `offset` | integer | no | Offers to skip. Default: `0`. (min 0) |

#### Example request

```bash title="cURL"
curl 'https://raresats.net/api/market/offers?outpoint=24b3eedfdc210f4a5baa96a6c99db5a51d3b1286ab2f58cb0b16fc607e54107f:0&seller=bc1p5cyxnuxmeuwuvkwfem96lqzszd02n6xdcjrs20cac6yqjjwudpxqkedrcr&bidder=bc1p4qhjn9zdvkux4e44uhx8tc55attvtyu358kutcqkudyccelu0was9fqzwh&row=decasat_alpha&status=active,pending&limit=20'
```
```js title="JavaScript"
const response = await fetch('https://raresats.net/api/market/offers?outpoint=24b3eedfdc210f4a5baa96a6c99db5a51d3b1286ab2f58cb0b16fc607e54107f:0&seller=bc1p5cyxnuxmeuwuvkwfem96lqzszd02n6xdcjrs20cac6yqjjwudpxqkedrcr&bidder=bc1p4qhjn9zdvkux4e44uhx8tc55attvtyu358kutcqkudyccelu0was9fqzwh&row=decasat_alpha&status=active,pending&limit=20');
const data = await response.json();
```
```python title="Python"
import requests

data = requests.get("https://raresats.net/api/market/offers", params={"outpoint": "24b3eedfdc210f4a5baa96a6c99db5a51d3b1286ab2f58cb0b16fc607e54107f:0", "seller": "bc1p5cyxnuxmeuwuvkwfem96lqzszd02n6xdcjrs20cac6yqjjwudpxqkedrcr", "bidder": "bc1p4qhjn9zdvkux4e44uhx8tc55attvtyu358kutcqkudyccelu0was9fqzwh", "row": "decasat_alpha", "status": "active,pending", "limit": 20}).json()
```

#### Response `200`

| Field | Type | Description |
| --- | --- | --- |
| `offers` | array of [Offer](https://raresats.net/docs/offer-object.md) | One page of offers. |
| `total` | integer | All offers matching the query. |

```json title="Response"
{
  "offers": [
    {
      "id": "dbf866a1e7e209e7",
      "kind": "item",
      "outpoint": "24b3eedfdc210f4a5baa96a6c99db5a51d3b1286ab2f58cb0b16fc607e54107f:0",
      "value": 10000,
      "seller_address": "bc1p5cyxnuxmeuwuvkwfem96lqzszd02n6xdcjrs20cac6yqjjwudpxqkedrcr",
      "price": 110000,
      "platform_fee": 2750,
      "fee_rate": 3,
      "network_fee": 963,
      "total": 113713,
      "vsize": 321,
      "unit_price": 100000,
      "row": "decasat_alpha",
      "count": 1,
      "rows": {"uncommon": 1, "alpha_uncommon": 1, "decasat_alpha": 1},
      "types": [
        {
          "types": ["uncommon", "decasat_alpha", "alpha"],
          "count": 1,
          "sats": [441000000000000]
        }
      ],
      "sats": 1,
      "ranges": [[441000000000000, 441000000000000]],
      "years": {"2010": 1},
      "bidder_payment_address": "bc1p4qhjn9zdvkux4e44uhx8tc55attvtyu358kutcqkudyccelu0was9fqzwh",
      "bidder_ordinals_address": "bc1p4qhjn9zdvkux4e44uhx8tc55attvtyu358kutcqkudyccelu0was9fqzwh",
      "status": "active",
      "created_at": 1790967012,
      "updated_at": 1790967012,
      "expires_at": 1791571812,
      "reason": null,
      "txid": null,
      "listing_id": "5e1cb930f43354c3",
      "acceptance_public": false
    },
    {
      "id": "9ab58f471cc625be",
      "kind": "item",
      "outpoint": "24b3eedfdc210f4a5baa96a6c99db5a51d3b1286ab2f58cb0b16fc607e54107f:0",
      "value": 10000,
      "seller_address": "bc1p5cyxnuxmeuwuvkwfem96lqzszd02n6xdcjrs20cac6yqjjwudpxqkedrcr",
      "price": 100000,
      "platform_fee": 2500,
      "fee_rate": 3,
      "network_fee": 921,
      "total": 103421,
      "vsize": 307,
      "unit_price": 90000,
      "row": "decasat_alpha",
      "count": 1,
      "rows": {"uncommon": 1, "alpha_uncommon": 1, "decasat_alpha": 1},
      "types": [
        {
          "types": ["uncommon", "decasat_alpha", "alpha"],
          "count": 1,
          "sats": [441000000000000]
        }
      ],
      "sats": 1,
      "ranges": [[441000000000000, 441000000000000]],
      "years": {"2010": 1},
      "bidder_payment_address": "bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu",
      "bidder_ordinals_address": "bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu",
      "status": "active",
      "created_at": 1790967012,
      "updated_at": 1790967012,
      "expires_at": null,
      "reason": null,
      "txid": null,
      "listing_id": "5e1cb930f43354c3",
      "acceptance_public": false
    }
  ],
  "total": 2
}
```

#### 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_order` | `order` is not `asc` or `desc`. |
| 400 | `bad_outpoint` | Not an outpoint (`txid:vout`). |
| 400 | `bad_paging` | `limit` or `offset` out of range. |
| 400 | `bad_row` | `row` is not a row id. |
| 400 | `bad_sort` | `sort` is not `unit`, `price` or `new`. |
| 400 | `bad_status` | `status` is not `all` or a comma-separated list of offer statuses, or (wallet transfers) not `pending` or `all`. |
| 404 | `retired_row` | `row` is a row the site retired (`uncommon_2009`, `rare_2009`): its listings are its parent row's. `retired` names the row and the parent and years to ask for. |

```json title="Error (400)"
{
  "error": "status must be all, or a comma-separated list of active, pending, accepted, cancelled, expired, invalid",
  "code": "bad_status"
}
```

A wallet page's two offer tabs are two queries: **offers made** is `?bidder=<address>&status=all`, **offers received** is `?seller=<address>&status=all`. A UTXO's offers, best first, are `?outpoint=<txid:vout>`. See [The Offer object](https://raresats.net/docs/offer-object.md) and [Make, accept and cancel offers](https://raresats.net/docs/guide-offers.md).
