# History, then live

> Show past trades or transfers and keep the list live, without missing or repeating an event.

This page is part of the Intear API docs. The Intear API is at `https://api.intea.rs` and `wss://api.intea.rs/ws`, with no API key. https://docs.intear.tech/api/llms-full.txt has all of its pages in one file, and https://docs.intear.tech/llms.txt lists every page of the Intear docs.

Trades and transfers each have two methods:
- `.query` answers once, with a page of history.
- `.subscribe` sends history and then live events, with nothing missed or repeated between them.

## A live list

Subscribe with `history` set to how many past events to show. The reply has them newest first, and each push after it has a block's new events, oldest first:

Using the client from the [Quickstart](https://docs.intear.tech/api/quickstart.md#over-the-websocket):

```js
let latestId = 0;

const { result } = await api.subscribe(
  'trades.subscribe',
  {
    fields: ['id', 'timestamp_millis', 'trader', 'side', 'amount', 'usd_value'],
    token: 'wrap.near',
    history: 50,
  },
  (push) => {
    if (push.end) throw new Error(`Subscription ended: ${push.end.message}`);
    const rows = push.rows ?? [];
    latestId = Math.max(latestId, ...rows.map((row) => Number(row[0])));
    addTrades(rows); // oldest first
  },
);

latestId = result.latest_id;
addTrades(result.rows.toReversed()); // history comes newest first
// After a reconnect, subscribe with `after_id: latestId` instead of `history`
```

The whole file, tested in CI: https://docs.intear.tech/snippets/js/src/intear-api.js

## Older pages

When there's more history than `history` asked for, the reply has `next_cursor`. Pass it as `cursor` to the matching `.query` method for the page before, and keep going with each page's `next_cursor` until it's `null`:

```json
{ "id": 2, "method": "trades.query", "params": { "fields": ["id", "side", "usd_value"], "token": "wrap.near", "limit": 200, "cursor": "L5Mbw_4QFMSVpBD7c1YULndl3Qpg28QVHKiQPOSe3_yXDijeliP2IfmcgOwCZeWs0CAUPTLYH29dvftbaV5x7WhXkQ" } }
```

Use the same filters as the subscription. `.query` also takes `after_millis` (inclusive) and `before_millis` (exclusive) to limit history to a time range.

To read on from a time instead, such as a date jumped to, pass `"order": "oldest"` with `after_millis`: pages go toward the present, and the last one, with a `null` `next_cursor`, ends at the latest block.

## After a reconnect

Subscribe again with `after_id` (for trades and transfers) instead of `history` field. The reply has every event after that one, oldest first, and pushes carry on from there:

- Set `after_id` to the newest `id` you have, or the reply's `latest_id` if that's newer. `latest_id` is the newest event the reply accounts for, matching or not, so it can be ahead of your newest row.
- More than 10,000 events after it is an error, `too_far_behind`: start over with `history`.

With neither `history` nor `after_id`, a subscription only sends events from now on.

## Filters

Trades can be filtered by token, the other token, trader, side and size, and transfers by token, sender and receiver. See [Trades](https://docs.intear.tech/api/reference/trades.md#filters) and [Transfers](https://docs.intear.tech/api/reference/transfers.md#filters) for every filter, and the combinations that are refused.

`parent` follows the tokens directly under an account instead of one `token`, like every token launched on a platform. It's resolved when the request is made, so tokens created after that aren't included. Like a `token` list, it covers up to 100 tokens: an account with more is `too_many`.

:::note
Transfer history, `after_id` included, needs a `sender`, `receiver` or `account`. Subscribing to transfers from now on doesn't, and with no filters gets every transfer.
:::
