Farbeam
Docs / Alerts and webhooks

Alerts overview

An alert rule is a Beamline expression plus a webhook URL. When a new transfer is stored and the expression is true for it, Farbeam sends a signed HTTP POST to your URL. A rule can also watch liquidity samples of curated tokens. Rules need a free API key. The feature is Early access.

#The path of an alert

  1. A poller finds a transfer of at least $100,000 and stores it. See indexing.
  2. If the row is new, every enabled rule's expression runs on it.
  3. For a match, a delivery is queued, unless the rule is in its cooldown or has hit its hourly cap.
  4. A worker runs every 3 seconds and sends up to 20 due deliveries.
  5. Your endpoint verifies the signature and answers with a 2xx code within 6 seconds.
  6. On failure, the delivery is retried up to three more times. See webhook retries.

#What rules can see

A transfer rule runs on stored transfer rows only. This sets three firm limits.

LimitConsequence
Only rows above $100,000A rule with usd < 50k is valid and will not match any new row
Only curated tokens and indexed native assetsA rule cannot watch an arbitrary token
Only indexed chainsA rule with chain == "polygon" is valid and never matches

Rules look forward only. Saving a rule does not replay old rows, and a rule cannot catch up on rows it missed while disabled. Validate a rule runs against stored rows for testing, and it sends nothing.

A rule that names liquidity_usd or change_pct runs on liquidity samples and does not run on transfers. See Beamline fields. There are no rules on gas, wallet balances, price or token reports. For those, poll the API. See the recipes.

#Cooldown

Each rule has cooldown_seconds, from 60 to 86,400, with a default of 300. After a rule fires, it ignores all matches until the cooldown ends. Those matches are dropped and are not queued for later. So a rule tells you that something matched, and it does not give you every row. To get every row, set the cooldown to 60 and read List large transfers when an alert arrives, or use the live stream. Test deliveries ignore the cooldown.

#Limits

#Delivery formats

FormatBodyUse
json (default)Farbeam event JSONYour own service. See webhooks.
discordDiscord webhook messageA Discord channel. See Discord delivery.
telegramText message to a linked chat, with no urlPlanned until the bot is connected

Telegram delivery is Planned. The code path exists, but POST /account/telegram answers 503 telegram_not_configured until the bot is connected. A telegram rule answers 409 telegram_not_linked until a chat is linked. Email delivery is Planned and is not built.

#Security model

  • Your endpoint gets a signature header. See webhook signatures.
  • Each rule has its own secret, shown once at creation.
  • URLs must be public HTTPS on port 443. Private addresses are refused at create time, and again at each send. See webhooks.

#A first rule

curl -s -X POST "https://farbeamlabs.com/api/v1/rules" \
  -H "Authorization: Bearer $FARBEAM_KEY" \
  -H "content-type: application/json" \
  -d '{"name":"Large moves to exchanges","expression":"to_type == \"exchange\" and usd >= 1m and not sampled","url":"https://example.com/hooks/farbeam"}'
const res = await fetch("https://farbeamlabs.com/api/v1/rules", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.FARBEAM_KEY}`,
    "content-type": "application/json",
  },
  body: JSON.stringify({
    name: "Large moves to exchanges",
    expression: 'to_type == "exchange" and usd >= 1m and not sampled',
    url: "https://example.com/hooks/farbeam",
  }),
});
const { data, error } = await res.json();
if (error) throw new Error(`${error.code}: ${error.message}`);
console.log(data.id, data.signing_secret);
import os, requests

res = requests.post(
    "https://farbeamlabs.com/api/v1/rules",
    headers={"Authorization": f"Bearer {os.environ['FARBEAM_KEY']}"},
    json={
        "name": "Large moves to exchanges",
        "expression": 'to_type == "exchange" and usd >= 1m and not sampled',
        "url": "https://example.com/hooks/farbeam",
    },
    timeout=30,
)
body = res.json()
if "error" in body:
    raise RuntimeError(body["error"]["message"])
print(body["data"]["id"], body["data"]["signing_secret"])

#What an alert means

An alert says a transfer matched your rule. It does not say a trade happened, and it is not a signal. Read transfers vs trades. Farbeam makes no buy or sell calls.

#Rule lifecycle

StateHow it is reachedEffect
OnCreated with enabled true (default), or PATCH with enabled: trueMatches new rows. A PATCH to on also clears the failure count.
Off, by youPATCH with enabled: falseNo new matches. Queued deliveries still run.
Off, automatic20 failed deliveries in a rowSame as off. Fix your endpoint, then turn it on.
Off, key revokedDELETE /meAll rules of the key turn off.
DeletedDELETE /rules/{id}Rule, log and queued deliveries are removed.

Manage rules through the console or the rule endpoints. The next pages cover the language, the payload and how to test.