README
¶
WoT Scoring — Nostr Web of Trust
Live: wot.klabo.world
NIP-85 Trusted Assertions provider. Crawls the Nostr follow graph, computes PageRank trust scores, collects per-pubkey, per-event, and per-identifier engagement metadata, publishes kind 30382/30383/30384/30385 events to relays, consumes kind 10040 provider authorizations, consumes kind 10000 mute lists (NIP-51) for community moderation signals, enriches relay data from trustedrelays.xyz with social reputation, detects trust communities via label propagation, and consumes assertions from external NIP-85 providers for composite trust scoring. Auto re-crawls every 6 hours.
What it does
- Crawls kind 3 (contact list) events from seed pubkeys (depth 2)
- Builds a directed graph of follow relationships
- Computes PageRank over the graph
- Crawls kind 1 (notes), kind 7 (reactions), and kind 9735 (zap receipts) for user metadata
- Crawls event engagement (comments, reposts, reactions, zaps) for kind 30383/30384
- Crawls addressable events (kind 30023 long-form, kind 30311 live activities) for kind 30384
- Crawls external identifiers — hashtags (t-tags) and URLs (r-tags) — for kind 30385
- Serves scores and metadata via HTTP API
- Combines relay infrastructure trust (trustedrelays.xyz) with operator social reputation (PageRank)
- Publishes all four NIP-85 assertion kinds to Nostr relays
- Consumes kind 30382 assertions from external NIP-85 providers
- Computes composite trust scores blending internal PageRank with external assertions
- Consumes kind 10040 provider authorization events — tracks which users trust which providers
- Consumes kind 10000 mute lists (NIP-51) — builds reverse index for community moderation signals
- Detects trust communities via label propagation over the follow graph
- Re-crawls automatically every 6 hours
API
Live at https://wot.klabo.world — try any endpoint below.
GET / — Service info and endpoint list
GET /health — Health check (status, graph size, uptime)
GET /score?pubkey=<hex> — Trust score for a pubkey (kind 30382) + composite from external providers
GET /audit?pubkey=<hex> — Score audit: full breakdown of why a pubkey has its score
GET /personalized?viewer=<hex>&target=<hex> — Personalized trust score relative to viewer's follow graph
POST /batch — Score up to 100 pubkeys in one request (JSON: {"pubkeys":[...]})
GET /similar?pubkey=<hex> — Find similar pubkeys by follow-graph overlap
GET /recommend?pubkey=<hex> — Follow recommendations (friends-of-friends)
GET /metadata?pubkey=<hex> — Full NIP-85 metadata (followers, posts, reactions, zaps)
GET /event?id=<hex> — Event engagement score (kind 30383)
GET /external?id=<ident> — External identifier score (kind 30385, NIP-73)
GET /external — Top 50 external identifiers (hashtags, URLs)
GET /relay?url=<wss://...> — Relay trust + operator WoT (via trustedrelays.xyz)
GET /decay?pubkey=<hex> — Time-decayed trust score (newer follows weigh more)
GET /decay/top — Top pubkeys by decay-adjusted score with rank changes
GET /authorized — Kind 10040 authorized users (who declared trust in this provider)
GET /authorized?pubkey=<hex> — Authorizations for a specific provider
GET /communities — Top trust communities (label propagation clusters)
GET /communities?pubkey=<hex>— Community membership and top peers for a pubkey
GET /nip05?id=user@domain — NIP-05 verification + WoT trust profile (resolves identity to pubkey)
POST /nip05/batch — Bulk NIP-05 verification (up to 50 identifiers, concurrent)
GET /nip05/reverse?pubkey=<hex|npub> — Reverse NIP-05 lookup (pubkey → NIP-05 identity, bidirectional verification)
GET /timeline?pubkey=<hex|npub> — Trust timeline: monthly follower growth and estimated score evolution over time
GET /spam?pubkey=<hex|npub> — Spam detection: multi-signal analysis with classification and signal breakdown
POST /spam/batch — Bulk spam check up to 100 pubkeys with summary counts (JSON: {"pubkeys":[...]})
GET /weboftrust?pubkey=<hex|npub> — D3.js-compatible trust graph: nodes + links for force-directed visualization
GET /blocked?pubkey=<hex|npub> — Who has this pubkey muted (their NIP-51 mute list)
GET /blocked?target=<hex|npub> — Who has muted this target (reverse lookup + community signal)
POST /verify — Verify a NIP-85 kind 30382 assertion from any provider (cross-check signature + claims)
GET /anomalies?pubkey=<hex|npub> — Trust anomaly detection: follow-farming, ghost followers, trust concentration, risk assessment
GET /sybil?pubkey=<hex|npub> — Sybil resistance scoring (0-100, multi-signal analysis, classification)
POST /sybil/batch — Batch Sybil scoring for up to 50 pubkeys (sorted by suspicion)
GET /trust-path?from=<hex>&to=<hex> — Multi-hop trust path analysis (multiple paths, trust scoring, diversity)
GET /reputation?pubkey=<hex> — Composite reputation score (0-100, grade A-F, 5 dimensions)
GET /predict?source=<hex>&target=<hex> — Link prediction (5 graph signals, prediction score, mutual connections)
GET /influence?pubkey=<hex>&other=<hex> — Influence propagation (differential PageRank what-if analysis)
GET /network-health — Network topology health (degree stats, connectivity, Gini, hubs, health score)
GET /trust-circle?pubkey=<hex> — Trust circle analysis: mutual follows, cohesion, density, member roles
GET /trust-circle/compare?pubkey1=<hex>&pubkey2=<hex> — Compare trust circles: overlap, Jaccard, compatibility
GET /follow-quality?pubkey=<hex> — Follow list quality: diversity, ghost ratio, categorization, suggestions
GET /influence/batch — Batch influence scoring for up to 50 pubkeys (network role, reach, tier)
GET /compare-providers?pubkey=<hex> — Cross-provider NIP-85 score comparison with consensus metrics
WS /ws/scores — Real-time score streaming via WebSocket (subscribe to pubkey updates)
GET /providers — External NIP-85 assertion providers and assertion counts
GET /top — Top 50 scored pubkeys
GET /export — All scores as JSON
GET /stats — Service stats and graph info
POST /publish — Publish NIP-85 kind 30382/30383/30384/30385 + NIP-89 handler to relays
Interactive UI
The landing page at wot.klabo.world includes interactive trust analysis tools. The demo dashboard provides 13 live cards calling 14 API endpoints with 10 parallel fetches per search:
- Score Lookup — Enter any npub or hex pubkey to see trust score, followers, posts, reactions, zaps
- Trust Leaderboard — Top 10 scored pubkeys with live rank, score, and follower counts
- Trust Communities — Visualize detected trust clusters with member counts and top-ranked members
- Compare — Side-by-side comparison of two pubkeys with relationship badges and bar charts
- Trust Path — BFS shortest-path visualization showing each hop with WoT scores between any two pubkeys
- Timeline — Trust evolution visualization showing monthly follower growth bars with velocity coloring
- Spam Check — Multi-signal spam probability analysis with per-signal breakdown bars
- Trust Graph — Interactive force-directed SVG visualization of a pubkey's trust network
- Follow Quality — Follow list quality score with entropy-based diversity, ghost ratio, and suggestions
- Trust Circle Compare — Trust circle compatibility with Jaccard coefficient and shared connections
- Network Health — Auto-loading network-wide metrics: 51k nodes, 620k edges, Gini coefficient, power-law exponent
- Anomaly Detection — Suspicious pattern analysis with risk classification
- Link Prediction — "People you may know" with 5 graph-theoretic signals
- Score Audit — Full PageRank breakdown: rank, percentile, top followers, engagement metrics
- Recommended Follows — Friends-of-friends recommendations with mutual counts and WoT scores
Client SDK
nostr-wot — zero-dependency JavaScript client library with TypeScript declarations and L402 payment support. Covers all 48 endpoints.
Relay Plugin
strfry-wot — drop-in writePolicy plugin for strfry relays. Filters events by WoT trust score. One binary, three env vars.
go install github.com/joelklabo/strfry-wot@latest
# strfry.conf: writePolicy { plugin = "strfry-wot" }
Run
go build -o wot-scoring .
./wot-scoring
# Listens on :8090 (override with PORT env var)
# NIP-85 publishing requires NOSTR_NSEC env var
Docker:
docker build -t wot-scoring .
docker run -p 8090:8090 -e NOSTR_NSEC=nsec1... wot-scoring
Systemd (persistent service):
sudo cp wot-scoring /usr/local/bin/
sudo cp wot-scoring.service /etc/systemd/system/
sudo mkdir -p /etc/wot-scoring
echo "NOSTR_NSEC=nsec1..." | sudo tee /etc/wot-scoring/env
sudo useradd -r -s /usr/sbin/nologin wot
sudo systemctl enable --now wot-scoring
Test
go test -v ./...
Numbers
Typical crawl: ~51,000 nodes, ~620,000 edges in 8-10 seconds from 4 seed pubkeys.
NIP-85 Tags Published
Each kind 30382 event includes these standard NIP-85 tags:
| Tag | Description |
|---|---|
d |
Subject pubkey |
p |
Subject pubkey (relay hint) |
rank |
Normalized trust score (0-100) |
followers |
Follower count from follow graph |
post_cnt |
Kind 1 notes (not replies) |
reply_cnt |
Kind 1 notes that are replies |
reactions_cnt |
Kind 7 reactions received |
zap_amt_recd |
Sats received via zap receipts |
zap_cnt_recd |
Number of zaps received |
zap_amt_sent |
Sats sent via zap receipts |
zap_cnt_sent |
Number of zaps sent |
first_created_at |
Earliest known event timestamp |
zap_avg_amt_day_recd |
Average daily sats received |
zap_avg_amt_day_sent |
Average daily sats sent |
t |
Common topics/hashtags (up to 5) |
active_hours_start |
Peak activity window start (UTC hour, 0-23) |
active_hours_end |
Peak activity window end (UTC hour, 0-23) |
reports_cnt_recd |
Kind 1984 reports received |
reports_cnt_sent |
Kind 1984 reports sent |
Kind 30383 Tags (Event Assertions)
Each kind 30383 event scores an individual Nostr event:
| Tag | Description |
|---|---|
d |
Event ID |
e |
Event ID (relay hint) |
p |
Author pubkey |
rank |
Engagement score (0-100) |
comments |
Reply count |
reposts |
Kind 6 repost count |
reactions |
Kind 7 reaction count |
zap_count |
Number of zaps received |
zap_amount |
Sats received via zaps |
Kind 30384 Tags (Addressable Event Assertions)
Each kind 30384 event scores an addressable event (articles, live activities):
| Tag | Description |
|---|---|
d |
Event address (kind:pubkey:d-tag) |
a |
Event address (relay hint) |
p |
Author pubkey |
rank |
Engagement score (0-100) |
comments |
Reply count |
reposts |
Repost count |
reactions |
Reaction count |
zap_count |
Number of zaps received |
zap_amount |
Sats received via zaps |
Kind 30385 Tags (External Identifier Assertions)
Each kind 30385 event scores an external identifier (NIP-73 format — hashtags, URLs):
| Tag | Description |
|---|---|
d |
NIP-73 identifier (e.g. #bitcoin, https://example.com) |
rank |
Engagement score (0-100) |
mentions |
Number of events referencing this identifier |
unique_authors |
Number of distinct authors who mentioned it |
reactions |
Aggregate reaction count |
reposts |
Aggregate repost count |
comments |
Aggregate reply count |
zap_count |
Number of zaps on mentioning events |
zap_amount |
Sats zapped on mentioning events |
Relay Trust Assessment
The /relay endpoint combines infrastructure data from trustedrelays.xyz with operator social reputation from our PageRank graph:
combined_score = infrastructure_trust * 0.70 + operator_wot_score * 0.30
Example response for GET /relay?url=wss://relay.damus.io:
{
"url": "wss://relay.damus.io",
"name": "damus.io",
"operator_pubkey": "32e1827...",
"relay_trust": {
"overall": 90,
"reliability": 84,
"quality": 94,
"accessibility": 94,
"operator_trust": 71,
"uptime_percent": 100,
"confidence": "high",
"observations": 5149
},
"operator_wot": {
"pubkey": "32e1827...",
"wot_score": 18,
"followers": 1358,
"in_graph": true
},
"combined_score": 68,
"source": "wot.klabo.world + trustedrelays.xyz"
}
Responses are cached for 30 minutes to respect trustedrelays.xyz rate limits (60 req/min). Unknown relays gracefully return a 0 score.
Interoperability — External Assertion Consumption
The service consumes NIP-85 kind 30382 events from other providers on the relay network and blends them into a composite trust score.
- Subscribes to kind 30382 events from the last 7 days on all configured relays
- Filters out self-published assertions (only external providers are included)
- Stores per-provider, per-subject assertions with deduplication (newest wins)
- When querying
/score, if external assertions exist for a pubkey, the response includes acomposite_scoreandexternal_assertionsbreakdown
Composite scoring formula:
composite = (internal_score × 0.70) + (external_avg × 0.30)
This means clients can ask our service for a trust score that blends multiple independent WoT engines — true NIP-85 interoperability.
The /providers endpoint lists all discovered external NIP-85 assertion providers and their assertion counts.
Personalized Trust Scoring
The /personalized endpoint scores a target pubkey relative to a viewer's follow graph — the same query Vertex claims NIP-85 can't serve. Our server handles the computation:
GET /personalized?viewer=<hex>&target=<hex>
Response:
{
"personalized_score": 55,
"global_score": 21,
"viewer_follows_target": true,
"target_follows_viewer": true,
"mutual_follow": true,
"trusted_followers": 748,
"shared_follows": 293,
"trusted_follower_sample": ["32e1827...", "fa984bd..."]
}
Formula: 50% global PageRank + 50% social proximity (direct follow: +40, mutual: +10, trusted follower ratio: up to +50).
Similar Pubkey Discovery
Find pubkeys with the most overlapping follow graphs — useful for recommendations and discovery:
GET /similar?pubkey=<hex|npub>&limit=20
Response:
{
"pubkey": "32e1827...",
"similar": [
{
"pubkey": "82341f...",
"similarity": 0.218,
"shared_follows": 293,
"wot_score": 21
}
],
"total_found": 20,
"graph_size": 51446
}
Algorithm: Jaccard similarity of follow sets (|intersection| / |union|), weighted 70% similarity + 30% WoT PageRank score. Minimum 3 follows required. Max 50 results.
Follow Recommendations
Get personalized follow recommendations — "who should this pubkey follow?" based on friends-of-friends analysis:
GET /recommend?pubkey=<hex|npub>&limit=20
Response:
{
"pubkey": "32e1827...",
"recommendations": [
{
"pubkey": "82341f...",
"mutual_follows": 45,
"mutual_ratio": 0.293,
"wot_score": 67
}
],
"total_found": 20,
"follows_count": 154,
"graph_size": 51446
}
Algorithm: For each account you follow, find who they follow. Count how many of your follows also follow each candidate. Exclude accounts you already follow. Rank by 60% mutual ratio + 40% WoT score. Minimum 2 mutual connections required. Max 50 results.
Graph Explorer
Two modes for exploring trust connections in the follow graph:
Trust Path Finder
Find the shortest connection between any two pubkeys through the follow graph:
GET /graph?from=<hex|npub>&to=<hex|npub>
Response:
{
"from": "32e1827...",
"to": "fa984bd...",
"found": true,
"path": [
{"pubkey": "32e1827...", "wot_score": 92},
{"pubkey": "82341f...", "wot_score": 78},
{"pubkey": "fa984bd...", "wot_score": 65}
],
"hops": 2,
"graph_size": 51446
}
BFS over follow edges, max depth 6. Each node in the path includes its WoT score.
Neighborhood Graph
Get the local follow network around a pubkey — who they follow, who follows them, and mutual connections:
GET /graph?pubkey=<hex|npub>&depth=1&limit=50
Response:
{
"pubkey": "32e1827...",
"wot_score": 92,
"follows_count": 942,
"followers_count": 12847,
"mutual_count": 15,
"neighbors": [
{"pubkey": "82341f...", "wot_score": 78, "relation": "mutual"},
{"pubkey": "fa984bd...", "wot_score": 65, "relation": "follows"},
{"pubkey": "abc123...", "wot_score": 45, "relation": "follower"}
],
"depth": 1,
"graph_size": 51446
}
Relations: mutual (both follow each other), follows (you follow them), follower (they follow you), extended (depth=2, friends-of-friends). Depth 1 or 2, max 200 results, sorted by WoT score.
Score Audit
Explains exactly why a pubkey has its score, breaking down all contributing factors:
GET /audit?pubkey=<hex|npub>
Response:
{
"pubkey": "32e1827...",
"found": true,
"final_score": 92,
"pagerank": {
"raw_score": 0.000245,
"normalized_score": 92,
"follower_count": 12847,
"following_count": 942,
"percentile": 0.9987,
"rank": 7,
"algorithm": "PageRank",
"damping": 0.85,
"iterations": 20,
"normalization": "log10(raw/avg + 1) * 25, capped at 100"
},
"engagement": {
"posts": 234,
"replies": 156,
"reactions_received": 892,
"reactions_sent": 445,
"zaps_received_sats": 15240,
"zaps_received_count": 42,
"zaps_sent_sats": 5000,
"zaps_sent_count": 18,
"first_event": "2022-12-03T10:30:00Z"
},
"top_followers": [
{"pubkey": "82341f...", "score": 95},
{"pubkey": "fa984bd...", "score": 78}
],
"graph_context": {
"total_nodes": 51446,
"total_edges": 620467,
"last_rebuild": "2026-02-09T12:30:00Z"
}
}
When external NIP-85 assertions exist, the response includes a composite object showing the 70/30 internal/external weighting and per-provider breakdown instead of final_score.
Trust Comparison
Compare two pubkeys side-by-side to understand their relationship in the Web of Trust:
GET /compare?a=<pubkey|npub>&b=<pubkey|npub>
Returns:
- Direct relationship: mutual, a_follows_b, b_follows_a, or none
- Profile stats: WoT score, rank, percentile, follows/followers count for each
- Shared follows: top 20 people both pubkeys follow (ranked by WoT score)
- Shared followers: top 20 people who follow both pubkeys (ranked by WoT score)
- Follow similarity: Jaccard index (0.0-1.0) of their follow sets
- Trust path: shortest path between the two pubkeys via BFS
Batch Scoring
Score up to 100 pubkeys in a single request:
POST /batch
Content-Type: application/json
{"pubkeys": ["hex1", "hex2", "npub1..."]}
Returns score, composite score, and follower count per pubkey. Supports both hex and npub formats.
NIP-89 Handler Announcement
On publish, the service also emits a kind 31990 event (NIP-89 Recommended Application Handler) announcing support for kinds 30382, 30383, 30384, and 30385. This lets Nostr clients auto-discover the service as a NIP-85 assertion provider.
Client Integration
Any Nostr client can consume NIP-85 trust scores directly from relays — no API dependency required. Here's how to query user trust assertions using nostr-tools:
import { SimplePool } from 'nostr-tools/pool'
const pool = new SimplePool()
const WOT_PROVIDER = '28207d114dec1046c40ad9d8f5b2d86e0e470e4c0fc35739c17679faa8df4534'
const relays = ['wss://relay.damus.io', 'wss://nos.lol', 'wss://relay.primal.net']
// Query trust score for a pubkey
async function getTrustScore(targetPubkey) {
const events = await pool.querySync(relays, {
kinds: [30382],
authors: [WOT_PROVIDER],
'#d': [targetPubkey],
})
if (events.length === 0) return null
const event = events[0]
const rank = event.tags.find(t => t[0] === 'rank')?.[1]
const followers = event.tags.find(t => t[0] === 'followers')?.[1]
return { score: parseInt(rank), followers: parseInt(followers) }
}
// Filter a feed by trust score
async function filterByTrust(pubkeys, minScore = 10) {
const events = await pool.querySync(relays, {
kinds: [30382],
authors: [WOT_PROVIDER],
'#d': pubkeys,
})
const scores = new Map()
for (const ev of events) {
const pk = ev.tags.find(t => t[0] === 'd')?.[1]
const rank = parseInt(ev.tags.find(t => t[0] === 'rank')?.[1] || '0')
if (pk) scores.set(pk, rank)
}
return pubkeys.filter(pk => (scores.get(pk) || 0) >= minScore)
}
Or use the HTTP API directly:
# Single score lookup
curl https://wot.klabo.world/score?pubkey=npub1sg6plzptd64u62a878hep2kev3zah5demn5au0ge0nf6ynlvk9qs2gpzg7
# Batch scoring (up to 100 pubkeys)
curl -X POST https://wot.klabo.world/batch \
-H 'Content-Type: application/json' \
-d '{"pubkeys":["82341f882b6eabcd...", "fa984bd7dbb282f0..."]}'
# Personalized trust (is this person trustworthy FROM MY perspective?)
curl "https://wot.klabo.world/personalized?viewer=MY_PUBKEY&target=THEIR_PUBKEY"
Trust Decay Scoring
Time-decayed PageRank that weighs recent follows more heavily than old ones. A follow from last week contributes more to trust than one from two years ago.
GET /decay?pubkey=<hex|npub>&half_life=365
Response:
{
"pubkey": "32e1827...",
"decay_score": 88,
"static_score": 92,
"delta": -4,
"half_life_days": 365,
"found": true,
"follower_count": 12847,
"followers_with_time_data": 11234,
"oldest_follow": "2022-11-15T08:30:00Z",
"newest_follow": "2026-02-08T14:22:00Z"
}
Algorithm: Exponential decay on PageRank edge weights. Each follow's contribution is scaled by e^(-λ × age_days) where λ = ln(2) / half_life_days. Default half-life: 365 days (a 1-year-old follow has 50% weight). Configurable via half_life parameter.
The /decay/top endpoint shows how rankings shift when freshness is factored in — who gains rank (recently followed) vs who loses rank (legacy follows fading).
NIP-05 Identity Verification
Look up a NIP-05 identifier and get its WoT trust profile in one request — bridges Nostr identity verification with Web of Trust scoring:
GET /nip05?id=user@domain.com
Response:
{
"nip05": "user@domain.com",
"pubkey": "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245",
"verified": true,
"trust_level": "highly_trusted",
"score": 92,
"raw_score": 0.000245,
"found": true,
"graph_size": 51446,
"followers": 12847,
"post_count": 234,
"reply_count": 156,
"reactions": 892,
"nip05_relays": ["wss://relay.damus.io"],
"topics": ["bitcoin", "nostr", "lightning"]
}
Trust levels: highly_trusted (80+), trusted (50+), moderate (20+), low (>0), untrusted (0), unknown (not in graph).
This endpoint resolves the NIP-05 identifier via the standard /.well-known/nostr.json protocol, then returns the full WoT trust profile for the resolved pubkey. Useful for verifying identities before transacting, following, or trusting someone.
Bulk NIP-05 Verification
Verify and trust-score up to 50 NIP-05 identifiers in a single request. Resolves all identifiers concurrently for fast directory-scale lookups.
POST /nip05/batch
Content-Type: application/json
{"identifiers": ["jb55@jb55.com", "max@klabo.world", "alice@example.com"]}
Response:
{
"count": 3,
"graph_size": 51446,
"results": [
{
"nip05": "jb55@jb55.com",
"pubkey": "32e1827...",
"verified": true,
"trust_level": "highly_trusted",
"score": 92,
"found": true,
"followers": 12847,
"nip05_relays": ["wss://relay.damus.io"]
},
{
"nip05": "max@klabo.world",
"pubkey": "f2da534b...",
"verified": true,
"trust_level": "trusted",
"score": 55,
"found": true,
"followers": 42
},
{
"nip05": "alice@example.com",
"error": "NIP-05 endpoint returned status 404",
"verified": false
}
]
}
Failed resolutions return per-item errors without failing the entire batch. Useful for clients that need to verify contact lists, organization directories, or NIP-05-heavy platforms.
Reverse NIP-05 Lookup
Given a pubkey, find its NIP-05 identity — the inverse of standard NIP-05 resolution. Fetches the pubkey's kind 0 profile from relays, extracts the NIP-05 field, and bidirectionally verifies it resolves back to the same pubkey.
GET /nip05/reverse?pubkey=<hex|npub>
Response:
{
"pubkey": "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245",
"nip05": "_@jb55.com",
"display_name": "jb55",
"verified": true,
"score": 92,
"found": true,
"graph_size": 51446,
"followers": 12847,
"nip05_relays": ["wss://relay.damus.io"]
}
If the pubkey has no kind 0 profile or no NIP-05 field set, the response still includes trust score data with verified: false and an error message. Useful for answering "who is this pubkey?" when you only have a hex key or npub.
L402 Lightning Paywall
The API supports the L402 protocol for pay-per-query access via Lightning Network micropayments.
Free tier: 50 requests/day per IP on priced endpoints. No payment needed.
Priced endpoints:
| Endpoint | Price |
|---|---|
/score, /decay, /nip05 |
1 sat |
/personalized, /similar, /recommend, /compare, /nip05/reverse, /timeline, /spam, /blocked |
2 sats |
/weboftrust, /anomalies, /sybil, /predict |
3 sats |
/audit, /nip05/batch, /trust-path, /reputation, /influence, /network-health, /compare-providers |
5 sats |
/batch, /spam/batch, /sybil/batch |
10 sats |
All other endpoints (/top, /stats, /health, /export, /providers, /graph, /event, /external, /relay, /metadata, /docs, /swagger, /openapi.json) are free and unlimited.
Interactive API documentation: https://wot.klabo.world/docs
Swagger UI API explorer: https://wot.klabo.world/swagger — interactive testing of all endpoints in the browser
OpenAPI Spec: https://wot.klabo.world/openapi.json — machine-readable OpenAPI 3.0.3 specification for automated client generation and tool integration
Pricing metadata: https://wot.klabo.world/pricing — L402 free tier + priced endpoints (sats)
Usage flow:
# Free tier (first 50 requests/day)
curl https://wot.klabo.world/score?pubkey=<hex>
# After free tier: returns 402 with invoice
# Response: {"status":"payment_required","invoice":"lnbc...","payment_hash":"abc123","amount_sats":1}
# Pay the invoice, then retry with payment hash
curl -H "X-Payment-Hash: abc123" https://wot.klabo.world/score?pubkey=<hex>
Configuration: Set LNBITS_URL and LNBITS_KEY environment variables to enable. Without these, the paywall is disabled and all endpoints are free.
Built for
WoT-a-thon hackathon — Web of Trust tools for Nostr.
License
MIT
Webhook Testing
This PR tests the GitHub webhook integration.
Updated 2026-02-10
Test 3 - Tue Feb 10 09:12:47 PM PST 2026 Live test - Tue Feb 10 09:14:34 PM PST 2026
Documentation
¶
There is no documentation for this package.
Source Files
¶
- anomalies.go
- authorize.go
- blocked.go
- community.go
- compare.go
- compare_providers.go
- consume.go
- decay.go
- demo.go
- event_scoring.go
- external_scoring.go
- follow_quality.go
- influence.go
- influence_batch.go
- l402.go
- main.go
- metadata.go
- network_health.go
- nip05.go
- openapi.go
- predict.go
- pricing.go
- ratelimit.go
- relay_trust.go
- reputation.go
- spam.go
- sybil.go
- timeline.go
- trust_circle.go
- trust_circle_compare.go
- trustpath.go
- verify.go
- weboftrust.go
- websocket.go