vike
On-chain

Alerts

Create, list, edit and delete on-chain transfer alerts, list notification channels, and register a signed webhook.

6 tools for on-chain transfer alerts: rules that fire when a transfer of a given token crosses a USD threshold, or when a given wallet sends or receives one. Unlike every other family here, these tools write to your account — they are the only ones that change state.

Five things constrain what an alert can express today, all of them stated by the tools themselves:

  • Chains eth and bsc only. One chain per alert: passing two silently watches only the first, with no error to tell you the second was dropped. Watching both means creating two alerts.
  • USD thresholds only. There is no token-quantity condition — a rule triggers on transfer value, not on size in tokens. There is no upper bound either: max_value_usd is stored on the alert but the checker does not apply it.
  • One wallet per alert, as a 20-byte EVM address (0x and 40 hex characters). An ENS name, an entity name ("Binance 14") or a non-EVM address is refused, not resolved. See Watching a wallet.
  • One alert type. transfer is the only kind the service accepts.
  • Delivery is the channels you have set up: email, Discord and signed webhooks.

Alerts belong to the authenticated user, and every tool enforces ownership: you can only list, edit or delete your own. Both credentials resolve to a user, so an API key and an OAuth token reach the same alerts.

alerts_list

Free — 0 credits. Lists your alert rules. Active only by default.

ParameterTypeDefaultNotes
include_inactivebooleanfalseInclude paused and soft-deleted alerts

Returns {"alerts": [...]}, one row each with id, label, alert_type, chain, token_symbol, min_value_usd, max_value_usd, address_conditions, cooldown_minutes, max_triggers_day, notify_channel_ids, is_active and created_at. address_conditions is a list of {"role": "from" | "to" | "any", "address": "0x…"}, empty when the alert watches no wallet; an alert made on the website can carry both a from and a to address, which is why it is a list.

This is also how you get an alert_id — alerts_edit and alerts_delete both need one, and neither accepts a label.

List my alerts, including the paused ones.

alerts_list_channels

Free — 0 credits. Your enabled notification channels. No parameters.

Returns {"channels": [...]} with {id, channel_type, is_verified, label} per row.

Call it before creating an alert. An alert created against a channel you have not set up is still created — it simply never notifies anyone, which is the failure mode worth avoiding.

What notification channels do I have set up?

alerts_create

3 credits. Creates a transfer alert.

ParameterTypeDefaultNotes
labelstringrequiredThe alert's user-visible name
token_symbolstring—Ticker in UPPERCASE (USDC, ETH, PEPE)
chainenumetheth or bsc, single value
min_value_usdnumber—Fire when transfer USD value ≥ this
max_value_usdnumber—Stored on the alert, not applied by the checker
addressstring—One wallet to watch: 0x and 40 hex characters
address_roleenumanyany (sent or received), from (it sent) or to (it received); needs address
channelsarray—["email"], ["discord"], or both
cooldown_minutesinteger60Minimum gap between triggers, floor of 1

Returns {"alert": {...}} — the new row in the shape alerts_list uses, including its id. A malformed address, an unknown address_role, or a role without an address comes back as {"error": "..."} and nothing is created.

min_value_usd is the only threshold the checker enforces. cooldown_minutes is what keeps a busy token from filling your inbox, and it is enforced per rule.

Alert me on email when more than $5M of USDC moves on Ethereum, at most once an hour.

Alert me on Discord when 0x28C6…1d60 sends more than $1M on Ethereum.

alerts_edit

2 credits. A partial update: only the fields you pass change.

ParameterTypeNotes
alert_idintegerRequired. From alerts_list.
label, token_symbol, chain, min_value_usd, max_value_usd, channels, cooldown_minutes—Same meaning as in alerts_create
address, address_rolestringSame rules as in alerts_create. address replaces the alert's wallet condition; address: "" removes it; address_role alone moves the existing address to that side
is_activebooleanfalse pauses the alert without deleting it

The exported schema carries per-field descriptions only for address; the other fields mirror alerts_create above, which is where their meaning is stated.

An edit that leaves address out keeps the wallet condition as it was, and address without address_role keeps the current side (any when the alert had no wallet). A rejected address changes nothing, including the other fields in the same call.

Pause my USDC alert.

Raise the threshold on alert 41 to $10M.

alerts_delete

2 credits. Removes an alert.

ParameterTypeDefaultNotes
alert_idintegerrequiredThe alert to delete
hardbooleanfalsetrue removes permanently; the default pauses and keeps history

Returns {"ok": true} on success. A soft delete is the same state as is_active: false, so an alert deleted this way still appears under alerts_list with include_inactive: true and can be re-enabled with alerts_edit.

Delete alert 41 — actually, just pause it.

alerts_register_webhook

2 credits. Registers an HTTPS webhook as a delivery channel. Vike POSTs signed JSON to the URL when your alerts fire.

ParameterTypeDefaultNotes
urlstringrequiredWebhook URL (http or https), reachable from Vike's servers
secretstring—HMAC secret, 16 characters or more. Recommended.

Verifying a delivery

The signing is Stripe-style. Each POST carries:

Content-Type: application/json
User-Agent: vike-alerts/1.0
X-Vike-Timestamp: <unix epoch seconds>
X-Vike-Signature: t=<ts>,sig=<hex hmac>

Compute HMAC-SHA256(secret, "<X-Vike-Timestamp>.<raw body>"), hex-encode it, and compare it in constant time against the sig= value. Reject the delivery if the timestamp is more than about five minutes old — that is what stops a captured request being replayed.

Without a secret the POST still goes out, unsigned. That is fine for a private endpoint and not fine for anything reachable from the internet, since nothing then distinguishes Vike's POST from anyone else's.

Send my alerts to https://example.com/hooks/vike as well, with a signing secret.

Watching a wallet

address and address_role ask for a transfer that involves one wallet: from matches a transfer the wallet sent, to one it received, any either. Stored on the alert exactly as the website's alert form stores it (from_address, to_address or any_address in the alert's notes), so an alert made here opens and edits correctly under Account → Alerts, and the reverse.

What the match is, and is not:

  • A transfer row, any token. The checker compares the address with the sender and receiver of each recorded transfer on the alert's chain: native coin and token transfers alike. With no token_symbol every token counts, spam and dust tokens included.
  • min_value_usd is optional, and it changes what matches. With it, only transfers that already carry a USD value at or above it match, so an unpriced token never does. Without it, every transfer touching the address matches, priced or not. Either way the alert sends at most one notification per cooldown_minutes (default 60) and 10 a day, and names the newest matching transfer, so a busy wallet with no threshold is a flood that the cooldown only throttles.
  • Not supported. An ENS name or an entity label as the address; a non-EVM address; two wallets on one alert; a wallet on base or hyperevm; "any wallet in this group". Create one alert per wallet and per chain.
  • Not the same as a wallet's balance or PnL. The alert looks at individual transfers; it does not know a wallet's net position.

When alerts are evaluated

Alerts are not evaluated inline with the chain. A scheduled checker sweeps recent transfers and fires matching rules; its lookback window is deliberately twice its run interval, so one missed run still gets caught rather than dropping the transfers it would have seen. Expect alerting latency in minutes, and treat these as monitoring rather than as a trading trigger. A rule with a min_value_usd can only match a transfer once it has a USD value, so a transfer that is priced after the lookback has passed is not reported.

On this page