endpoint at a server you control and the hits go there instead. Same client, same wire format, same classification.
Why the split exists
Beacon is two halves, and it matters which half does what. The client reports raw facts: the path, theUser-Agent as received, the source address, whether Markdown was negotiated, any signature headers. It deliberately draws no conclusions.
The server decides what those facts mean: which crawler this is, and whether it is who it claims to be.
That split is not an implementation detail. A client that graded its own traffic would only be repeating what the crawler told it, and a crawler registry compiled into your site’s dependencies goes stale the day after you install it.
This is why there is a server to self-host at all. If classification happened on your site, “self-hosting” would just mean not sending the data anywhere.
What you get, and what you do not
You get
Ingest, crawler classification, IP-range and reverse-DNS verification, Web Bot Auth signature checking, daily rollups, and storage in SQLite or Postgres.
You do not get
A dashboard, a stats API, charts, alerting, crawl-to-referral attribution, or history beyond what your own database holds.
POST /v3/beacon/hits and GET /health. It records classified, verified hits into a database. What you do with them is yours.
If you want the dashboard, the maintained verified-crawler dataset and attribution, that is what hosted SnowSEO is. Both run the same ingestBatch function, so the open half cannot quietly drift from the hosted one.
Three ways to do it
1
Run the reference server
One command, or a container. Storage in SQLite by default, Postgres if you want it. See Running the server.
2
Embed the pipeline in an app you already have
@snowseo/beacon-server exports ingestBatch on its own. Call it from your existing Fastify, Express or Hono app and persist however you like. Implement the HitStore interface for your own database.3
Write your own collector
The wire protocol is frozen and documented, so a collector in Go, Rust or Python is a supported path rather than a hack. You give up the classification engine, which is the hard part.
Requirements
Node 24, or Node 22.5+ with--experimental-sqlite. The SQLite store uses Node’s built-in driver, so there is no native module to compile and no dependency to install.
Postgres needs pg, declared as an optional peer dependency and imported only if you choose that store.

