How to auto-post Hugging Face model releases without writing a single “new model dropped” tweet.
The short answer to the question you came here for: don't auto-post. Pull huggingface.co/api/models?sort=createdAt&direction=-1 on a cron (no auth required), turn each new release into a set of search topics, and feed those into a momentum-filtered engagement loop that replies to threads on r/LocalLLaMA, r/MachineLearning, and X where people are already evaluating models in your space. The rest of this page is the argument for why that is the right move and the actual config to wire it up.
direct answer (verified 2026-04-29)
Hugging Face does not publish an official RSS feed for new model releases. The Hub does expose a JSON endpoint at https://huggingface.co/api/models that accepts sort=createdAt&direction=-1 and returns up to 1000 model records per call without authentication. That is the feed you consume.
The right way to act on it: not a scheduled launch tweet, but a momentum-aware reply loop. New model id and its tags become search topics. The engagement pipeline only fires when an existing thread is gaining traction, so your reply lands while the conversation is alive.
Source: Hugging Face Hub API documentation.
Why a scheduled “new model dropped” tweet does almost nothing
Most of the tools and most of the playbooks for this topic have a tidy answer: connect the Hub to a webhook, write a tweet template, schedule it. Done. The problem is that this answer ignores how releases on Hugging Face actually find their audience.
A new model has a long tail of useful life. The DeepSeek-V3 release got a 2316-upvote thread on r/LocalLLaMA on day one, and the same model is still being mentioned in “what 7B should I run for code” threads months later. The templated launch tweet reaches frontpage scrollers once. The people who actually adopt your model find it three weeks in, while they are evaluating something else.
The launch tweet does not reach those people. A reply in their thread does. So the right job is not “announce on a schedule”, it is “detect new releases, expand each release into search topics, and reply to threads where someone is already evaluating models in that space.”
Same release, two distribution moves
Schedule a launch tweet the moment the model uploads. Same shape on Reddit. Both posts go live, decay in hours, never reach the long-tail evaluators.
- tweet template fires on Hub webhook
- r/LocalLLaMA self-promotion post (often pruned by mods)
- spike in hour 1, near-zero by hour 6
- no signal for who actually saw it
The Hub feed: what you actually get for free
The endpoint is https://huggingface.co/api/models. With sort=createdAt&direction=-1 it returns model records ordered newest first. No token. No rate limit at the cadence we use. Each record looks like this:
{
"_id": "...",
"id": "deepseek-ai/DeepSeek-V4-Pro",
"author": "deepseek-ai",
"createdAt": "2026-04-22T06:04:45.000Z",
"tags": ["transformers", "safetensors", "long-context", "..."],
"pipeline_tag": "text-generation",
"library_name": "transformers",
"likes": 3241,
"downloads": 174402,
"trendingScore": 3069,
"private": false
}The interesting fields for distribution are id, author, tags, and pipeline_tag. The id is the unique handle people will paste into a thread when they recommend you. The author lets you filter the firehose down to your org. The tags and pipeline_tag are the seed for the search topics that drive the engagement loop.
Two distribution moves, side by side
The same release, two completely different shapes of work. The left tab is what every other guide tells you to schedule. The right tab is what S4L runs.
auto-post hugging face model releases
# the move every scheduler tells you to make
new model just dropped 🚨🚀
introducing my-org/My-Model-7B
✅ open weights
✅ apache 2.0
✅ outperforms <bigger model> on <hand-picked benchmark>
try it now 👉 https://huggingface.co/my-org/My-Model-7B
#opensource #ai #llm #huggingfaceHow a release flows through the pipeline
The Hub feed is the input. The momentum filter is the gate. The bandit picks the voice. The reply lands in a live thread. Every step is logged so the next cycle re-ranks itself from real outcomes.
hub -> queries -> momentum gate -> reply
The momentum gate, in one formula
This is the one piece of math that decides whether your model release ever produces a reply. Read scripts/fetch_twitter_t1.py, the compute_delta function around line 43. The shell sleeps 300 seconds between the two snapshots:
# scripts/fetch_twitter_t1.py
def compute_delta(t0, t1):
dl = (t1.get("likes", 0) or 0) - (t0.get("likes", 0) or 0)
dr = (t1.get("retweets", 0) or 0) - (t0.get("retweets", 0) or 0)
dp = (t1.get("replies", 0) or 0) - (t0.get("replies", 0) or 0)
dv = (t1.get("views", 0) or 0) - (t0.get("views", 0) or 0)
db = (t1.get("bookmarks", 0) or 0) - (t0.get("bookmarks", 0) or 0)
return dl + 3 * dr + 2 * dp + dv / 1000.0 + db
Retweets are weighted 3x because they are the strongest virality signal. Replies are 2x because a reply means someone cared enough to type. Views are divided by 1000 so they do not dominate. The threshold is a literal delta_score >= 1. Anything below that is a tweet that has stopped moving. The pipeline does not spend a single LLM token drafting against it.
“The sleep between the two engagement snapshots. Shorter and you catch noise; longer and the conversation has moved to the next release.”
skill/run-twitter-cycle.sh
The config you actually touch on release day
One project block in config.json. The discovery cron writes the queries; you only edit it manually if you want to override what tags expand into search topics.
// config.json (the only block you touch when you ship a model)
{
"projects": {
"my-model-7b": {
"landing_pages": {
"repo": "https://huggingface.co/my-org/My-Model-7B",
"readme": "https://huggingface.co/my-org/My-Model-7B/raw/main/README.md"
},
"threads": {
"external_subreddits": [
{ "name": "LocalLLaMA", "floor_days": 7 },
{ "name": "MachineLearning", "floor_days": 14 },
{ "name": "OpenSourceAI", "floor_days": 7 }
],
"twitter_queries": [
// generated from the Hub feed: model id, tags, pipeline_tag
"\"My-Model-7B\" since:YESTERDAY",
"long context 7B since:YESTERDAY",
"function calling open weights since:YESTERDAY"
]
}
}
},
"exclusions": {
"github_repos": ["my-org/My-Model-7B"]
}
}Wiring it up end to end
Five steps. Most of the work is the first one (the discovery cron). The rest is wiring its output into the existing engagement loop.
1. Poll the Hub feed once an hour
A cron runs curl against https://huggingface.co/api/models?sort=createdAt&direction=-1&limit=50, pipes it through jq, filters by .author or .id prefix, and writes the new model records to a small SQLite table keyed by id. Anything already in the table is skipped, so a re-poll is a no-op until something new ships.
2. Expand each new model into search topics
scripts/seed_release_queries.py turns a model record into 3 to 5 queries: the bare model id with quotes, the pipeline_tag plus the most distinctive tag, the parameter count plus a usage phrase. since:YESTERDAY is appended so stale tweets are dropped at the source. The queries land in the project's threads.twitter_queries array in config.json.
3. The next twitter cycle picks them up
skill/run-twitter-cycle.sh fires every 20 minutes via launchd. It loads twitter_queries for each project in config.json, runs them, snapshots engagement, sleeps 300, re-fetches, and computes delta_score per the compute_delta formula. Tweets with delta_score < 1 are dropped before drafting begins.
4. Reddit goes through the same expansion
external_subreddits stays static for a release (LocalLLaMA, MachineLearning, OpenSourceAI). The engagement pipeline searches recent threads in those subs for the model id and the tag-derived terms. Per-subreddit floor_days enforces a cooldown so the same sub cannot receive two posts about the same release inside its window.
5. Every reply writes a row to posts
INSERT INTO posts(platform, engagement_style, thread_id, our_content, ...). The next cycle's bandit reads from this table to re-rank engagement_style by live posts.avg_upvotes. A model that performs better with a contrarian voice on r/LocalLLaMA but a pattern_recognizer voice on X gets ranked accordingly without you tuning anything.
What this approach is bad at, honestly
A reply loop is not the right move for every kind of release. If you are an AI lab with a billion-parameter model and a press team, the templated launch post will reach more people on day one than a momentum-filtered reply ever will. The launch beats the reply at the front of the curve.
Where the reply loop wins is the back of the curve: the long tail of evaluators, integrators, and people running their own benchmarks weeks or months later. If your model is open-weights, dev-tooling-adjacent, or competes on a specific axis (speed at small batch, function-calling reliability, low-VRAM ergonomics), the long tail is where most adoption actually happens. The reply loop is sized for that audience.
It is also genuinely worse at vanity metrics. A momentum-filtered reply does not produce a viral 10k-retweet announcement screenshot you can put on a fundraising deck. It produces a slow accumulation of conversations where you showed up next to a real question with a useful answer, and a corresponding slow accumulation of downloads and stars. If your KPI is the screenshot, this is the wrong tool.
Want this loop pointed at your next Hugging Face release?
Book 20 minutes and we will configure the discovery cron, the search-topic expansion, and the momentum filter against your repo and tags live.
Questions about auto-posting Hugging Face model releases
Does Hugging Face have an official RSS feed for new model releases?
Not for the Models index. The Hub does have an open JSON endpoint at https://huggingface.co/api/models that supports sort=createdAt&direction=-1, returns up to 1000 results per call without authentication, and includes id, author, tags, pipeline_tag, downloads, likes, trendingScore, and createdAt for every model. That is the feed you should consume on a cron. Daily Papers and a few community projects publish RSS over the Hub (papers.takara.ai/api/feed for papers, the zernel huggingface-trending-feed repo for trending models), but the Models index itself is consumed via the JSON API.
Why is a templated 'new model dropped' tweet a bad idea?
Two reasons. First, the X algorithm and r/LocalLLaMA both have very strong recognition for the announcement-shape post and route it to a small audience that already follows your account or the subreddit. Second, model releases have a long tail of useful life. Most of the people who care about your model find it three days, three weeks, or three months later, while they are evaluating something else and a thread asks 'has anyone tried a 7B with function calling that does not hallucinate'. The templated launch tweet does not reach those people. A reply in that thread does.
What does S4L actually do when a new release is in the feed?
It treats the model id and its tags as search topics for the existing engagement pipeline. The Twitter cycle (skill/run-twitter-cycle.sh) fetches candidate tweets matching those queries with since:YESTERDAY, sleeps 300 seconds, re-fetches the same tweet ids, and computes delta_score per the formula in scripts/fetch_twitter_t1.py: Δlikes + 3·Δretweets + 2·Δreplies + Δviews/1000 + Δbookmarks. Any tweet with delta_score below 1 is dropped before the model is spawned. Reddit goes through run-reddit-search.sh with the same per-subreddit floor_days cooldowns the rest of the system uses.
How do I avoid spamming r/LocalLLaMA every time I push a new commit to the repo?
Two layers. First, the discovery cron only fires when createdAt is newer than the last seen createdAt for that project; minor pushes that update last_modified but not createdAt do not trigger anything. Second, every external subreddit in config.json carries a floor_days: r/LocalLLaMA defaults to 7, r/MachineLearning to 14, and the engagement script queries the posts table for the most recent post against (project, subreddit) before drafting. If now minus last_posted_at is less than floor_days, the subreddit is skipped. The floor is per-project, so other releases in your account are not blocked.
What gets posted? An announcement, or a reply?
Almost always a reply. The Reddit prompt explicitly discourages pivoting into a product pitch and favors subreddit-native voice. The Twitter prompt allows first-person mentions but the reply still has to stand on its own as a useful observation, the mention is a byline rather than a CTA. There is a top-level submission path (run-reddit-threads.sh) that drafts a post with the README as context, but the comment pipeline (run-reddit-engage.sh) is what reaches the long-tail evaluators and is what you want for a model release.
Will the Hub API rate-limit me on the polling step?
Not at the cadence we run. The /api/models endpoint with sort=createdAt&direction=-1&limit=50 is a cheap call and the Hub serves it from a CDN. We poll once an hour, which is roughly 24 calls per day per workstation. The interesting gate is Reddit, not Hugging Face: scripts/post_reddit.py runs a preflight against /r/popular.json?limit=1, reads X-Ratelimit-Remaining, caches it to /tmp/reddit_ratelimit.json, and exits cleanly if the quota is below 3. That preflight runs before Claude is ever spawned, so a low-quota window costs zero LLM tokens.
Can I use this without S4L?
Yes. The mental model is what matters. Pull the Hub feed on a cron with curl + jq. Filter to your org or model id. When a new id appears, expand it into search topics: the id itself, the pipeline_tag, the most distinctive tag. Run those through any tool that can search a platform and reply through your account. The two pieces that take real engineering are the momentum filter (do not reply to dead tweets) and the per-subreddit cooldown (do not appear in the same subreddit over and over). Without those, you get reach without trust, which on Reddit is worse than nothing.
What if my model release is private or behind a gated repo?
The Hub API will not surface gated repos to an unauthenticated client, so the discovery cron skips them by default. If you want to drive distribution from a gated release before it is public, fire the seed_release_queries step manually with the model id you intend to publish. The momentum-filtered engagement loop does not care about gating, it only needs queries that match what people are already saying.