Find the RSS feed
Plenty of sites still publish a feed, they just stopped linking to it from anywhere a human would notice. This endpoint takes a homepage or any page on a site and hands back the actual feed URL, checking the places a feed usually hides rather than the one place most people give up looking.
Run it online
Run this on our servers with your account. Free tools run in your browser; this one bills your KIT balance per the price above.
The feed didn't disappear, the link tag did
A decade ago every browser had an orange RSS icon and a page's head tag reliably declared its feed with a link rel=alternate tag. Redesigns stripped that icon out, a lot of CMS themes stopped rendering the link tag by default, and social sharing buttons took over the space RSS icons used to occupy — but the underlying feed very often still exists at /feed, /rss.xml, /atom.xml or a dozen other conventional paths, quietly serving whichever crawler or reader still asks for it. Finding it by hand means view-source, guessing paths, or trawling a site's sitemap.
How the discovery actually works
Send a URL to POST /web/rss-discover and get a task_id back while the page is fetched and inspected: the endpoint checks the declared link rel=alternate tags first, then falls back to probing the conventional feed paths a given platform is known to use, and returns whichever feed URL it confirms is live and parseable. Results arrive by webhook or a signed link valid for 24 hours, and if nothing is found, the task reports that plainly rather than guessing.
Why this still matters when everyone talks about email and social
RSS never actually left; podcast distribution runs entirely on it, a large share of newsletter tools still ingest content via feeds behind the scenes, and plenty of publishing platforms — WordPress, Ghost, Substack, most static site generators — emit a feed automatically whether or not the theme links to it. The gap isn't that feeds stopped existing, it's that discovering them got harder as the visible signals disappeared, which is exactly the gap this endpoint closes.
Where discovery feeds into a larger system
A monitoring tool onboarding a new site to track doesn't want to ask a user to hunt down their own feed URL, and a research pipeline building a list of sources from a directory of company blogs can't afford to check each one by hand. Running discovery first, then handing the confirmed feed URL to a parser, keeps the whole chain automated end to end. Because it's billed per request and a site with no discoverable feed is reported as a clean negative result rather than charged as a failure, scanning a long list of candidate sites costs nothing extra for the ones that simply don't have a feed.
What you can do with it
Onboarding sites into a feed monitor
When a user adds a site to track, run discovery first to resolve its actual feed URL instead of requiring them to find it themselves.
Building a source list from a directory
Given a list of company or industry blog homepages, discover which ones publish a feed before attempting to parse any of them.
Recovering feeds after a site redesign
Re-check a previously known site whose feed link disappeared from its homepage to confirm the feed still exists at a new or hidden path.
Podcast and newsletter aggregator setup
Resolve the correct feed URL for shows or publications submitted by users who only provide the show's website, not its feed.
FAQ
How do I find a site's RSS feed with the API?
POST the site's URL to /web/rss-discover, keep the returned task_id, and collect the discovered feed URL by webhook or a signed link valid for 24 hours.
Is the RSS discovery API free?
No, there is no free tier or trial; it costs $0.002 per request, and a failed lookup is never charged.
What if the site genuinely has no feed?
The task completes and clearly reports that no feed was found, rather than guessing at a URL or failing silently.
Does it check more than the homepage's link tag?
Yes, it checks declared link rel=alternate tags first and also probes conventional feed paths common to major publishing platforms.
Does it work on any page, or only the homepage?
You can submit any page on the site; discovery looks at that page's declared links and also tries site-wide conventional paths.
Can I run discovery on a large list of sites in bulk?
Yes, submit one async task per site and collect each result by webhook, which is the typical way to build a source list at scale.
Does discovery also parse the feed's content?
No, this endpoint only resolves the feed URL; pair it with the RSS to JSON endpoint to parse the actual items.
Is the site data stored after discovery?
No, fetched pages and discovery results are deleted after the retention window and are never used for training.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, and soon from our app, email and Telegram.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/web/rss-discover \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://ejemplo.com"}'const res = await fetch("https://api.kit.forhosting.com/web/rss-discover", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"url": "https://ejemplo.com"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/web/rss-discover",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"url": "https://ejemplo.com"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/web/rss-discover", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"url":"https://ejemplo.com"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"url":"https://ejemplo.com"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/web/rss-discover", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"url": "https://ejemplo.com"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "web.rss_discover",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
timeout_sec | 30 |
max_crawl_pages | 25 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |