Web Reactions API
Web Reactions collects one piece of data that's genuinely interesting on its own: the aggregate reaction counts of pages across the web. The plan is to expose that data as a small, read-only HTTP API anyone can build on.
Not available yet. Endpoints below are a design preview, not a contract. They will roll out gradually starting with the next few releases. Follow the repo or join the waitlist below to be the first to know when an endpoint goes live.
Get notified at launch
Leave your email and we will send a single message when the first endpoint goes live. No newsletter, no follow-ups — one launch email, then the address has done its job.
We store the address you enter (plus a hashed copy for de-duplication) until launch, only to send that one email. Details in the privacy policy.
Principles
- Open data. Reaction counts are facts about public web pages. The dataset is released under a permissive license (see below) — once you have a response, you can republish, mirror, and build on it freely.
- Paid access. Aggregating and serving fresh reaction counts across millions of pages takes significant compute. To keep the project alive without ads or data resale, API access will be paid. A free tier for small projects and open research is planned; full pricing will be published before the first endpoint goes live.
- No personal data, ever. The API will only ever expose aggregates. There is no "who reacted" endpoint and there never will be — the underlying database doesn't even associate identities with public targets in a way that could power one.
- Cache-friendly. Every response will set
Cache-ControlandETagheaders so the edge does the heavy lifting and your client doesn't pay for stale requests. CORS will be open to*.
Planned endpoints
1. Per-target reactions
Get the full reaction breakdown for one public target — a Facebook post, a GitHub repo, an Amazon product, and whatever else is supported by the time the endpoint ships.
GET /v1/reactions/{site}/{targetId}
{
"site": "github",
"targetId": "khasky/web-reactions",
"total": 1284,
"counts": {
"❤️": 612,
"🔥": 301,
"👍": 189,
"🎉": 102,
"🤔": 80
},
"lastUpdated": 1747560000000
} 2. Batch reads
The same shape, multiplexed. Useful for embedding counts on a listing page where you have many targets in one render.
GET /v1/reactions/batch?t=github/khasky/web-reactions&t=amazon/B08N5WRWNW 3. Top pages
The most-reacted-to targets across a site, or globally, optionally windowed to a recent period. Useful for "what's everyone talking about right now" boards.
GET /v1/top?site=github&window=24h&limit=50
{
"window": "24h",
"items": [
{ "site": "github", "targetId": "user/repo", "total": 921 },
{ "site": "github", "targetId": "user/other", "total": 743 },
...
]
}
Supported windows under consideration: 1h,
24h, 7d, 30d,
all.
4. Trending
Targets ranked by the rate of reactions in a window rather than the absolute count. A two-day-old post that gained 500 reactions today beats a five-year-old post that has 50 000 lifetime reactions but none today.
GET /v1/trending?site=facebook&window=1h&limit=20 5. Emoji popularity
Which emojis are most-used as reactions — globally, per site, or per time window. Answers "what does the modern web feel like today?" in one chart.
GET /v1/emojis?site=&window=7d&limit=25
{
"window": "7d",
"items": [
{ "reaction": "❤️", "count": 184_402 },
{ "reaction": "🔥", "count": 97_215 },
{ "reaction": "👍", "count": 88_117 },
...
]
} 6. Site activity
Time-bucketed totals per site: reactions per hour or per day, suitable for sparkline charts and longitudinal research. No targets, no users — just the count of votes landing in each bucket.
GET /v1/activity?site=amazon&bucket=hour&range=24h
{
"site": "amazon",
"bucket": "hour",
"range": "24h",
"buckets": [
{ "t": 1747551600000, "count": 412 },
{ "t": 1747555200000, "count": 388 },
{ "t": 1747558800000, "count": 506 },
...
]
} 7. Aggregate site stats
A one-line summary per site: total reactions ever recorded, total targets observed, number of supported items by category, and the timestamp of the most recent reaction.
GET /v1/sites/{site}/stats
{
"site": "github",
"totalReactions": 412_900,
"uniqueTargets": 18_204,
"topReactions": [ "❤️", "🔥", "👍", "🎉", "💯" ],
"lastReactionAt": 1747560000000
} What you could build
Six concrete use cases the planned endpoints are designed around, from one-evening widgets to full research pipelines:
-
Sentiment dashboards
Publishers & bloggers
See how people actually feel about a video, thread, or news post on platforms that hide dislikes or collapse everything into one Like.
GET /v1/reactions/{site}/{targetId} -
Product research
Commerce
Pull reaction breakdowns for a whole listing page of products in one call and chart them next to star ratings.
GET /v1/reactions/batch -
Mood-of-the-web boards
Media & research
Rank the emojis the web is using right now, per site or globally, and watch the mix shift through the day.
GET /v1/emojis?window=24h -
Breakout detection
Brands & platforms
Catch a page that starts collecting reactions faster than its baseline, hours before lifetime totals show anything unusual.
GET /v1/trending?window=1h -
Creator widgets
Creators
Embed a live reaction strip for your repo, post, or product on your own site — the planned oEmbed endpoint makes it a one-liner.
GET /v1/reactions/github/you/your-repo -
Open research
Research
Longitudinal, PII-free reaction data for media studies and social-web research, with per-site activity series and aggregate stats.
GET /v1/activity?bucket=day
Built for
The same open aggregates read very differently depending on who's holding them. Start from your corner:
-
Creators
Read how your work really landed past a single Like, and embed a live reaction strip on your own site.
-
Publishers & bloggers
An audience-reaction signal you own — verifiable, and impossible for a platform to quietly switch off.
-
Commerce
Independent product reactions, separate from a seller's own stars — and checkable against the public log.
-
Developers
Real signal on your repos and packages, in a batchable, cache-friendly API with an open dataset.
Sample dashboards
Three small widgets showing what the responses render into. All numbers are illustrative mocks, not live data — the shapes match the endpoint examples above.
Embeds and widgets
Beyond raw JSON, no-code surfaces so a creator, blogger, or shop can put counts on a page without touching the API:
- Reaction badge — a live SVG badge for a README, blog sidebar, or listing: the top-three emoji and a running total, embedded in one line like a CI badge, rendering for everyone whether or not they have the extension.
- Embeddable widget — a drop-in reaction strip for your own site, carrying a "verified" mark that links back to the public proof behind the count.
- oEmbed endpoint — so platforms that already understand oEmbed (Ghost, WordPress, Substack, …) can unfurl a Web Reactions target URL into an interactive reaction strip without a plug-in.
- Webhooks. Subscribe to a target and get a POST when its reaction count crosses a threshold you set. Useful for site owners who want to know when their post breaks out.
Rate limits and fair use
Every endpoint will sit behind a per-IP rate limit chosen so a normal dashboard never hits it. Heavy users (research crawlers, public dashboards with global reach) should reach out before the first launch so the budget can be tuned rather than tripped.
Responses will set
X-RateLimit-Remaining and
X-RateLimit-Reset headers, and a
429 will always include a Retry-After
value. Edge caching means most repeat fetches are free at the client.
Data license
Reaction counts are facts about public web pages, and the aggregates this API serves are open data. Once you hold a response you can republish it, mirror it, cache it, and build on it — commercially or not.
- Attribution welcomed, not demanded. A link back to webreactions.app helps more people find and independently verify the data.
- No PII to license. The dataset only ever contains aggregate counts. No response includes a user identifier of any kind, so there is nothing personal to license, leak, or de-anonymize.
- License text finalized at launch. The exact license ships together with the first endpoint, before anything goes live. The principles above are the commitment it will encode: permissive, open aggregates.
What it will not do
- No reaction submission via the public API. Votes will always go through the extension's authenticated path. A public submit endpoint would defeat the one-person-one-vote guarantee that makes the counts worth reading in the first place.
- No identity lookups. Not by email, not by hash, not by anything else. The public API only knows about counts.
- No private targets. If a page requires authentication to view, the extension doesn't record reactions for it and the API has nothing to return.
- No data resale. What you pay for is access to the live service — query throughput, freshness, uptime.
- Provenance, not a headcount. A verifiable count proves the number wasn't rewritten after the fact and that reactions came through the extension's authenticated path. It doesn't claim each reaction is a distinct human — it's a strong, checkable engagement signal that complements bot-detection rather than replacing it.