Quilcast Spam

Spam scores for every Farcaster cast

Our own Laya model reads each cast the moment it lands on Hypersnap and decides how likely it is to be spam. Anyone can ask for those scores with one free API call, with no key and no sign-up, and the answer comes straight from storage in under a millisecond.

Paste a full 40-character cast hash or any link that contains one.

API

There is one endpoint. Pass up to 100 cast hashes, separated by commas, and you get back each hash with its spam probability.

GET https://spam.quilcast.com/scores?h=0x<hash>,0x<hash>
ParameterMeaning
hComma-separated cast hashes of 40 hex characters, with or without 0x, up to 100 per call. The answer keeps each hash as you sent it, in lowercase, and leaves out malformed entries.

Answer

{
  "0x0b7f…a2c1": 0.97,
  "0x41d2…9e03": 0.12,
  "0x77aa…11f0": null
}

A number is the probability, from 0 to 1, that the cast is spam. null means the cast has no score: it was posted before the service started, it has no text to read, or it landed in the last few seconds and is still in the queue. Ask again later for casts that were just posted.

From a browser or a server

const hashes = casts.map((c) => c.hash).join(',')
const scores = await fetch(`https://spam.quilcast.com/scores?h=${hashes}`).then((r) => r.json())
const spam = casts.filter((c) => scores[c.hash] >= 0.9)
curl 'https://spam.quilcast.com/scores?h=0x0113f2fc7bce0b51e63c7b12742a7a07beb22cb4'

Good to know

Picking a threshold

The model was first trained on Telegram group spam, where it learned to catch claim links, airdrop bait, giveaway loops and paid promotion. On Farcaster it is very sure about that kind of cast, and it is more suspicious of short, friendly replies than a person would be. In practice a cut-off of 0.9 catches the reward-claim and slot-machine floods while leaving conversations alone, which is why Quilcast uses 90% by default. Lower it if you would rather see less noise and can live with an occasional false alarm.

How it works

  1. The service follows the event stream of every Farcaster shard on Quilibrium's Hypersnap node, starting a day back when it first runs.
  2. Each new cast's text and links go to a Laya model that runs on our own server, so no cast leaves our hardware and no outside AI service is involved.
  3. The score is stored in SQLite under the cast's hash, and the API reads it from there.

Images are not read yet, so a cast with only a picture has no score.

In Quilcast

Quilcast, the Farcaster client this service was built for, labels casts at or over your threshold with their odds, such as Spam 97%, or hides them. Both choices and the threshold live in Settings, under Spam.