For the complete documentation index, see llms.txt. This page is also available as Markdown.

Triggers and Filters

What fires a GetBlock webhook delivery: the three triggers, the unconfirmed and confirmed phases, the filter tree, and named address lists.

A webhook has a trigger — the kind of event it reacts to — and a filter that says which of those events you want: which addresses, contracts or topics. GetBlock delivers an event only when it matches both.

Triggers

trigger_type

Fires on

phases

Payload

address_activity

Native ETH or token activity of a watched address

unconfirmed, confirmed — one or both

raw and block; decoded for ERC-20 Transfer and Approval

log_event

A contract log matched by contract and/or topic filters

unconfirmed, confirmed — one or both

raw and block; decoded for ERC-20 Transfer and Approval

tx_confirmation

A transaction matched by the filter (for example, sent from or to a watched address) reaching confirm_depth blocks

Required, but ignored: the confirmation itself is the event

raw is the transaction; block is the chain head that reached the depth

For tx_confirmation, raw and eventId are those of the block the transaction was mined in, while block names the newer block at which it reached the depth. See Delivery Format for the payload of each trigger.

Phases and confirmation depth

  • unconfirmed — the event is delivered as soon as it appears in a new block. A chain reorganization can still remove it.

  • confirmed — the event is delivered again, with "confirmed": true, once the chain has grown confirm_depth blocks past the block that holds it.

A webhook with both phases gets two deliveries per event, and each is billed. confirm_depth is between 2 and 96 on Ethereum; leave it out or send null for the default, 96.

Reorg corrections ("removed": true) are delivered with the unconfirmed phase only. If you subscribe to confirmed alone, you are not told about a reorganization that happens after your confirmed delivery. See Handling Chain Reorganizations.

tx_confirmation still needs a non-empty phases list when you create the webhook (an empty one is refused with 400 invalid_phases), but the value does not change what is delivered. Send ["confirmed"].

Filters

The filters field is a tree. Every node is exactly one of:

  • {"all": [node, …]} — every child must match;

  • {"any": [node, …]} — at least one child must match;

  • {"not": node} — the child must not match;

  • a leaf.

There are three leaf types:

Leaf
Fields
Matches

address

dir: in, out or any; in: addresses (20-byte hex); list_refs: address list ids (al_…)

Activity to (in), from (out) or to or from (any) the addresses

contract

in: contract addresses (20-byte hex)

Logs emitted by these contracts

topic

position: 0 to 3; in: topics (32-byte hex)

Logs whose topic at that position is one of these values; position 0 is the event signature

Rules:

  • The tree is at most 8 levels deep and has at most 256 nodes. At most 1,000 addresses can be written into the tree itself; use address lists for more.

  • The trigger needs a matching leaf: address_activity needs an address leaf, log_event a contract or topic leaf. tx_confirmation accepts any leaf. A mismatch is refused with 400 filter_trigger_mismatch.

  • An unknown key is refused: filter_invalid_leaf inside a leaf, filter_malformed next to all, any or not.

  • Addresses may be sent in any case, EIP-55 checksummed included, and are returned in lower case.

  • The abi and amount leaves are not supported in this version.

Shortcuts for addresses and lists

Instead of writing an address leaf yourself, you can send two top-level fields when you create or update a webhook:

  • addresses — addresses to watch in both directions. They are stored in the webhook's own address list, which you read with GET /api/v1/webhooks/{id}/addresses.

  • list_refs — ids of your named address lists to watch in both directions.

GetBlock turns them into one address leaf with "dir": "any". If you also send filters, the result is {"all": [<your tree>, <that leaf>]}. In the webhook returned by the API, that leaf carries "src": "sugar". The marker is reserved: remove that leaf before you send the tree back in filters, or the request is refused with 400 filter_reserved_field.

Examples

Incoming and outgoing activity of two wallets, both phases:

Every ERC-20 Transfer of USDT: the contract and the Transfer signature in topic position 0:

A notification when a transaction of the addresses in a named list is 12 blocks deep:

Send any of these bodies to POST /api/v1/webhooks — see Create a webhook.

Address lists

A named address list (al_…) holds a set of addresses that any number of webhooks reference through list_refs. Changing the list changes what all of them match, without editing the webhooks.

  • A list holds up to 100,000 addresses. An account can have 50 lists, and a webhook can reference 10.

  • A request body is limited to about 5 MiB: 100,000 addresses (about 4.6 MB) fit in one request; larger sets go in several.

  • A list that a webhook still references cannot be deleted (409 list_in_use): remove it from the webhook's list_refs, or delete the webhook, first.

  • Every address of a list counts towards the plan limits of every webhook that references it. See Plan limits.

In the dashboard, lists are on the Address lists tab, where you can also import a .txt or .csv file. The endpoints are in the API Reference.

Changing a webhook

PATCH /api/v1/webhooks/{id} changes the fields you send and leaves the rest as they are.

  • chain, network and trigger_type cannot be changed: sending them is refused with 400 malformed_body. Create a new webhook instead.

  • addresses and list_refs replace the current values; [] clears them.

  • "name": null removes the name; "confirm_depth": null resets the depth to the default.

  • A change that would leave the webhook with no condition at all is refused with 400 filter_would_be_empty; send filters in the same request.

  • A change applies to the next event at once. Retries that are already scheduled may use the previous settings for up to 60 seconds.

The API also accepts a batching object. It is stored, but has no effect in this version: every request carries one event.

Last updated

Was this helpful?