DegenFeed aggregates content from 18 decentralized, federated, and publishing protocols plus RSS/Atom. Each protocol has a dedicated provider adapter that handles authentication, content normalization, and health monitoring.
wss://relay.damus.io (default)NIP-07 browser extension (Alby, nos2x) or direct nsec/npub. NIP-46 remote signing. All signing client-side.
Relay-dependent. Typical limits: 1 req/s per relay. Some relays cap at 500 chars for Kind 1. DegenFeed uses a relay pool of 10 relays for redundancy.
Relay connection health, message latency, and subscription success rate. Circuit breaker trips after 5 consecutive failures.
hub.farcaster.standardcrypto.vc:2283Wallet-based. Sign with the wallet owning your Farcaster ID. Hub API confirms identity via Ed25519 signatures.
Hub-specific rate limits. Public Hubs: ~100 req/min. DegenFeed runs multiple Hub connections for redundancy.
Hub sync status, gRPC latency, protobuf decode success rate. Automatic failover between Hub endpoints.
api-v2.lens.dev/graphqlChallenge-response signing via connected wallet. Lens profile must exist on Polygon.
GraphQL API: ~10 req/s per IP. Polygon RPC: ~100 req/s (Lens-specific endpoints).
GraphQL query latency, Polygon RPC health, mutation success rate. Temperature monitoring for rate limit proximity.
public.api.bsky.app (read) / bsky.social (write)AT Protocol XRPC session. App password required (create in Bluesky Settings → App Passwords).
PDS-dependent. Public API: ~3000 req/5min. DegenFeed caches aggressively (60s TTL).
PDS response time, XRPC method availability, rate limit headroom. Automatic cache extension during degradation.
social.degenfeed.xyz (GotoSocial v0.22)OAuth2 via GotoSocial instance. User requests account at social.degenfeed.xyz, then authorizes via standard OAuth flow.
Instance-dependent. GotoSocial: ~300 req/5min. 15+ public instances aggregated for diverse content.
Instance response time, OAuth token expiry, ActivityPub federation lag. Per-instance circuit breakers.
lemmy.world/api/v3No authentication required for read-only. Write not yet implemented.
Instance-dependent. lemmy.world: ~60 req/min. 15 curated crypto/tech communities across 3 instances.
API response time, community data freshness. Auto-suspension if instance becomes unresponsive.
threads.net (HTML scraping)No authentication required. Public HTML scraping only.
No formal API (Meta has not released one). DegenFeed uses FlareSolverr for Cloudflare bypass. 16 curated handles.
HTML parse success rate, Cloudflare challenge frequency, data freshness. Degraded if FlareSolverr unavailable.
old.reddit.com/.rss (primary)No API key required for RSS and JSON paths. API key available for authenticated endpoints.
Triple strategy: RSS feeds, JSON API, community frontends (Redlib, Libreddit, Teddit). 60 req/min with API key.
RSS feed freshness, JSON API response time, frontend fallback availability. Degraded during API changes.
353+ feed URLsNo authentication. Public RSS/Atom feeds only.
Configurable per-source refresh interval (default: 15-60min). Rate limits determined by source servers.
Feed parse success rate, staleness tracking, source adapter error rate. Circuit breaker for persistently failing feeds.
peertube-provider (federated instances)Optional account for uploading. Read-only aggregation of public instances.
Instance-dependent. Aggregates 20+ public instances; per-instance API rate limits apply.
Instance response time, federation lag, upload/stream relay status. Per-instance circuit breakers.
youtube-provider + 68 RSS channelsNo authentication for read-only RSS-based aggregation.
Invidious instance rate limits; RSS channel polling (default 15-60min).
Invidious instance availability, RSS freshness, video parse success rate. Degraded when Invidious instances are blocked.
owncast register adapterInstance URL + admin key required for stream registration. Read-only for viewers.
Per-instance. Self-hosted instances define their own limits.
Instance reachability, stream liveness, registration success rate.
Odysee API + RSSNo authentication for read-only aggregation.
Odysee API rate limits; RSS polling fallback.
API response time, claim resolution success rate, data freshness.
Rumble RSS + public pagesNo authentication. Public HTML/RSS only.
RSS polling interval (15-60min). No formal public API.
Feed parse success rate, page fetch reliability, data freshness.
Minds API (public feeds)No authentication for public read-only feeds.
Minds API rate limits. Curated channel list.
API response time, feed parse success rate, token-gate resolution.
Substack RSS feedsNo authentication. Public RSS feeds only.
Per-publication RSS refresh interval (default 15-60min).
Feed parse success rate, staleness tracking, publication availability.
Mirror.xyz /feed/atomNo authentication. Public RSS/Atom feeds only.
Per-publication RSS refresh interval.
Feed parse success rate, Arweave gateway reachability, entry freshness.
paragraph.xyz /feedNo authentication. Public RSS feeds only.
Per-publication RSS refresh interval.
Feed parse success rate, publication availability, token-gate resolution.
Here’s how to connect, read, and post to each supported network from the DegenFeed interface. For posting to multiple networks at once, see the Cross-Posting Guide.
Install a NIP-07 browser extension (Alby, nos2x) or paste your nsec/npub. Keys never leave your device — all signing is client-side with Schnorr signatures.
Read kind-1 notes, kind-6 reposts, kind-7 reactions, and kind-30023 long-form articles. Tip creators with Lightning zaps (LNURL).
Sign in with the wallet that owns your Farcaster ID. The Hub API confirms your identity via Ed25519 signatures.
Read casts, replies, reactions, and channels. Post up to 320 characters with embeds. Open interactive Frames directly from the feed.
Authenticate with your Lens profile on Polygon via challenge-response signing with your connected wallet.
Read publications, mirrors, and comments. Collect posts as NFTs and use Open Actions. Post up to 5,000 characters.
Enter your handle and an app password (create one in Bluesky Settings → App Passwords).
Read the AT Protocol firehose with rich text facets. Post up to 300 characters with images and video via XRPC.
Authorize via OAuth on your instance (including social.degenfeed.xyz, a GotoSocial instance).
Read home, local, and federated timelines plus trending tags. Post up to 500 characters with content-warning support.
Read-only for now — no account connection required.
Follow curated crypto/tech handles aggregated from public Threads pages.
Read-only via RSS/JSON — no account connection required.
Browse 91 default subreddits with real engagement data and comments.
Read-only for public feeds — no account connection required.
Follow curated Minds channels with token-gated community content.
No authentication — public feeds only.
Read 353+ sources including Substack, Mirror, Paragraph, and YouTube channels normalized into one feed.
Optional account for uploading. Read-only aggregation of 20+ public instances.
Watch federated video and live streams. Stream via RTMP ingest relay.
No authentication for read-only aggregation.
Watch channel videos, trending content, and live streams via Invidious (no tracking).
Self-hosted instance URL + admin key to register streams.
Watch live streams from independent Owncast broadcasters alongside other video sources.
No authentication for read-only aggregation.
Watch LBRY-protocol content claims, channel videos, and livestreams.
No authentication. Public HTML/RSS only.
Watch channel videos and livestreams aggregated from public pages.
No authentication. Public RSS feeds.
Read full newsletter posts from 30+ crypto and tech publications.
No authentication. Public RSS/Atom feeds.
Read on-chain publishing articles backed by Arweave, including token-gated editions.
No authentication. Public RSS feeds.
Read on-chain newsletter posts and token-gated content collections.
DegenFeed is designed to be extensible. Adding a new protocol requires implementing a provider that follows the standard interface.
interface ProtocolProvider {
/** Unique identifier for this protocol */
id: string;
/** Fetch latest posts (used by the worker) */
fetch(options: FetchOptions): Promise<RawPost[]>;
/** Normalize a protocol-specific post to UnifiedPost */
normalize(raw: RawPost): UnifiedPost;
/** Health check - returns latency in ms or throws */
healthCheck(): Promise<number>;
/** Optional: authenticate a user */
authenticate?(credentials: AuthCredentials): Promise<AuthResult>;
/** Optional: publish a post */
publish?(post: PublishOptions): Promise<PublishResult>;
/** Optional: engage (like, repost, reply) */
engage?(action: EngageAction): Promise<void>;
}Add a new package in packages/feed-providers/{protocol}-sdk/.
Create a provider class that implements ProtocolProvider.
Map raw protocol data to UnifiedPost in packages/feed-core/normalizers/.
Add the provider to the worker router at workers/api/src/providers/.
Configure KV cache TTL and refresh strategy.
Implement health checks and circuit breaker thresholds.
Add to the protocol selector in the frontend.
Add unit and integration tests for the provider.
import { ProtocolProvider, RawPost, UnifiedPost } from '@degenfeed/types';
export class MyProtocolProvider implements ProtocolProvider {
id = 'myprotocol';
private baseUrl = 'https://api.myprotocol.io';
async fetch(options: FetchOptions): Promise<RawPost[]> {
const url = `${this.baseUrl}/posts?limit=${options.limit}&cursor=${options.cursor}`;
const res = await fetch(url);
const data = await res.json();
return data.posts;
}
normalize(raw: RawPost): UnifiedPost {
return {
id: `myprotocol:${raw.id}`,
protocol: 'myprotocol',
author: {
displayName: raw.author.name,
handle: raw.author.handle,
avatar: raw.author.avatarUrl,
},
content: raw.body,
timestamp: new Date(raw.createdAt).getTime(),
stats: {
likes: raw.likeCount,
replies: raw.commentCount,
reposts: raw.shareCount,
},
};
}
async healthCheck(): Promise<number> {
const start = Date.now();
await fetch(`${this.baseUrl}/health`);
return Date.now() - start;
}
}// In workers/api/src/providers/index.ts
import { MyProtocolProvider } from './myprotocol';
export const providers: Record<string, ProtocolProvider> = {
nostr: new NostrProvider(),
farcaster: new FarcasterProvider(),
lens: new LensProvider(),
bluesky: new BlueskyProvider(),
// ... existing providers
myprotocol: new MyProtocolProvider(),
};packages/feed-providers/. The Nostr provider is the most complete example. Submit a PR when your provider is ready!Want to contribute a new protocol? Check the contributing guide