> For the complete documentation index, see [llms.txt](https://docs.baas.sh/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.baas.sh/baas-sdk/blockchain/events.md).

# Event history

Find contract events by amount, sender or date, using JSON filters or SDK helpers.

Find transfers by amount, sender or date. Both searches return decoded events, newest first:

| Search                                       | SDK method                                                                                                     |
| -------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| All events on a contract                     | `baas.contract(name).address(tokenAddress).events(options)`                                                    |
| The signed-in user's events on that contract | [`baas.user.events({ address: tokenAddress, ...options })`](/baas-sdk/manage-user.md#filter-the-users-history) |

Sign in and [select your project's network](/baas-sdk/blockchain/networks.md#the-active-chain) before querying. Replace `tokenAddress` with your registered contract's address.

{% hint style="info" %}
History is available on your project's own network, from the moment the deployment is registered. Public-network deployments have no history here. See [Indexed networks](/baas-console/contracts/explorer.md#indexed-networks).
{% endhint %}

```ts
const token = baas.contract('MyToken').address(tokenAddress);
const page = await token.events({ event: 'Transfer' });

console.log(page.data);  // events on this page
console.log(page.count); // total matching events
```

The examples below use this `token`. Replace these sample sender addresses with the wallets you want to find:

```ts
const alice = '0x1111111111111111111111111111111111111111';
const bob = '0x2222222222222222222222222222222222222222';
```

## Filter events

Pass a filter as `where`. You can write it as JSON or use the helpers: both select the same events.

For amounts, use [Smart Units](/baas-sdk/blockchain/smart-units.md) to enter tokens directly. `SmartUnits('1.5')` means **1.5 tokens**, with no manual conversion. The event argument must have a [unit](/baas-console/contracts/units.md). If it has no unit, or its unit depends on another argument, use a raw integer string.

### Find transfers of at least 1.5 tokens

```ts
import { and, gte, SmartUnits } from '@baas.sh/sdk';

const where = and(gte('args.value', SmartUnits('1.5')));
const page = await token.events({ event: 'Transfer', where });
```

### Combine conditions

Find transfers of **at least 1.5 tokens AND (sent by Alice OR Bob)**. Put the sender group inside the amount's `and` group.

{% tabs %}
{% tab title="Helpers" %}

```ts
import { and, or, eq, gte, SmartUnits } from '@baas.sh/sdk';

const where = and(
  gte('args.value', SmartUnits('1.5')),
  or(eq('args.from', alice), eq('args.from', bob)),
);
const page = await token.events({ event: 'Transfer', where });
```

{% endtab %}

{% tab title="JSON" %}
Here Alice is `0x1111…1111` and Bob is `0x2222…2222`:

```json
{
  "combinator": "and",
  "rules": [
    {
      "field": "args.value",
      "operator": ">=",
      "value": { "value": "1.5", "encoding": "units", "baasSdkInput": true }
    },
    {
      "combinator": "or",
      "rules": [
        { "field": "args.from", "operator": "=", "value": "0x1111111111111111111111111111111111111111" },
        { "field": "args.from", "operator": "=", "value": "0x2222222222222222222222222222222222222222" }
      ]
    }
  ]
}
```

{% endtab %}
{% endtabs %}

### Find transfers of at least 100 tokens since a date

Find transfers from Alice or Bob, of at least 100 tokens, since September 1. Use `oneOf` for the sender list:

```ts
import { and, oneOf, gte, SmartUnits } from '@baas.sh/sdk';

const where = and(
  oneOf('args.from', [alice, bob]),
  gte('args.value', SmartUnits('100')),
  gte('occurredAt', '2026-09-01T00:00:00Z'),
);
const page = await token.events({ event: 'Transfer', where });
```

## Write rules

A JSON rule contains `field`, `operator` and `value`. A group contains `combinator` (`and` or `or`) and `rules`, which can contain both rules and groups.

| Find events where a value…   | Helper                    | JSON operator               |
| ---------------------------- | ------------------------- | --------------------------- |
| Equals / differs from yours  | `eq` / `ne`               | `=` / `!=`                  |
| Is above / at least yours    | `gt` / `gte`              | `>` / `>=`                  |
| Is below / at most yours     | `lt` / `lte`              | `<` / `<=`                  |
| Matches any value in a list  | `oneOf`                   | `in`                        |
| Contains some text           | `contains`                | `contains`                  |
| Starts / ends with some text | `startsWith` / `endsWith` | `starts_with` / `ends_with` |

For example, `contains('args.label', 'reward')` selects an event whose text argument `label` contains `reward`. Choose the event that declares that argument.

| Field         | What it selects                                                |
| ------------- | -------------------------------------------------------------- |
| `args.<name>` | An event argument, such as `args.from` or `args.value`         |
| `occurredAt`  | The block's date and time                                      |
| `key`         | A key defined by the deployment's mappings, such as a token id |
| `wallet`      | An address involved in the event, according to its mappings    |

`args.<name>` needs `event` to identify one event. For an overloaded name, pass its full signature, such as `Transfer(address,address,uint256)`. Only scalar arguments can be filtered. `wallet` and `key` accept `eq` or `oneOf` and require matching mappings.

Use Smart Units for bound amounts, strings for raw integers and dates, and booleans for flags. Operators depend on the field's type; see [Filters](/baas-console/filters.md#operators). Filters allow **3 group levels**, **8 rules** and **50 values** across the whole filter; the root counts as a level. Empty groups are refused. Omit `where` to read without a filter. Event-history filters must also fit within 4,096 characters of JSON.

## Page through events

Use the same `where` for each page. `count` is the total number of matching events; `data` contains only the requested page.

```ts
const firstPage = await token.events({ event: 'Transfer', where, page: 1, limit: 50 });
const secondPage = await token.events({ event: 'Transfer', where, page: 2, limit: 50 });
```

The default is 20 events per page, up to 100. Stop when `page * limit >= count`. Start at page 1 after changing a filter.

## Read an event

Read `event.log.args` for the event's arguments. Amounts with a unit include `raw` and `formatted`; display `formatted`:

```ts
const transfer = page.data[0];
// Example transfer.log.args:
// { from: '0x…', to: '0x…', value: {
//   raw: '1500000', formatted: '1.5',
//   metadata: { encoding: 'units', decimals: '6' }
// } }
```

Each event includes `transactionHash`, `blockNumber` and `timestamp`. Mappings add the roles `out`, `in`, `related` and the business data in `values`. Contract history also includes events without mappings. See [formatted amounts](/baas-sdk/blockchain/smart-units.md#read-a-formatted-amount).

## Handle errors

An invalid filter returns a `BaasApiError` with status `400`. Read `err.body.code` to identify the problem; see [Event filter errors](/baas-sdk/resources/error-handling.md#event-filter-errors).

## Types

See the [API reference](/baas-sdk/resources/api-reference.md#types) for `Where`, `ContractEventsOptions`, `ContractEventsPage` and `ContractEvent`.

## Next

* [Smart units](/baas-sdk/blockchain/smart-units.md) — enter amounts in tokens and display formatted values.
* [Smart contracts](/baas-sdk/blockchain/smart-contracts.md) — read or call the contract.
* [Manage user](/baas-sdk/manage-user.md) — read one user's history.
