RSS → WEBHOOK

Any RSS feed, POSTed to your code as JSON.

You wanted one thing: to know when that feed has something new. What you were about to write was a poller, an XML parser, a seen-items table, a cron entry, and the bug where it re-notifies everything after a deploy. Point emit at the feed instead and every new item arrives at your endpoint as clean JSON.

One call

curl -X POST https://api.rssemit.com/v1/sinks \
  -H "Authorization: Bearer $EMIT_KEY" \
  -d '{
    "kind": "webhook",
    "url": "https://yourapp.dev/feed-events",
    "feed_url": "https://anyblog.com/rss.xml"
  }'

That's the whole setup. The feed can be one you don't own — someone else's blog, a GitHub releases feed, a status page, a subreddit — or a feed emit built for you from a page that never had one.

What lands on your endpoint

POST /feed-events
Content-Type: application/json
X-Emit-Event: sink.item

{
  "event": "item",
  "sink_id": "9c1f…",
  "name": "webhook: anyblog.com",
  "item": {
    "guid": "https://anyblog.com/posts/shipping-v2",
    "title": "Shipping v2",
    "url": "https://anyblog.com/posts/shipping-v2",
    "summary": "The rewrite is done and here is what changed…",
    "published_at": "2026-07-30T09:12:00+00:00"
  }
}

Fixed shape, every time — normalized out of whatever RSS 2.0, Atom, or JSON Feed dialect the publisher happened to emit, with the summary already stripped to text. No feed-parsing library in your stack, and no surprise the day a publisher changes CMS.

Or batch it

A busy feed doesn't need to wake your service forty times a day. Set "schedule": "daily" (or "weekly", with your own digest_hour and digest_tz) and emit holds items and sends one POST at the boundary instead:

X-Emit-Event: sink.digest

{
  "event": "digest",
  "sink_id": "9c1f…",
  "name": "webhook: anyblog.com",
  "items": [ { "guid": "…", "title": "…", "url": "…", "summary": "…", "published_at": "…" }, … ]
}

The parts you were going to get wrong

Worth knowing: per-item mode sends up to 10 items per polling cycle, so a feed that dumps fifty posts at once drains over the following cycles rather than stampeding your endpoint. A digest holds up to 200 items between boundaries.

See it before you trust it

POST /v1/sinks/{id}/test sends one real delivery — the newest item already in the feed, or content you pass in — and returns the exact body it posted. In the dashboard, the test button renders that body inline, so you can diff it against your handler before you write a line of it.

This isn't the signed-webhook thing

emit has two kinds of outbound HTTP, and they answer different questions. JSON broadcasts — this page — carry a feed's items, from any feed URL, with optional digest batching. Account-event webhooks carry things that happened in your emit account (a subscriber joined, a broadcast went out); those are HMAC-signed, retried with backoff, and have a per-endpoint delivery log. Most people who arrive here want the first one. Posting to a channel instead? See RSS to Slack.

Pricing

250 deliveries a month free. Polling feeds and serving the feed itself cost nothing, and each account gets 250 free sink deliveries per calendar month (UTC) across webhooks, Slack, Discord, Teams, Telegram, and Google Chat. After that each delivery is 1 credit ($1.60 per 1,000); a daily or weekly digest counts as one delivery however many items it carries, and test sends are free. If the allowance is used and the balance can't cover more, deliveries pause and items are held, not dropped, until you add credits. Email (1 credit per email) and optional LLM work (1 credit per 5 items judged, 1 per summary) draw on the same prepaid balance.

Where it gets interesting

The feed you point at doesn't have to be someone's raw output. Put a filtered feed in front of it — a plain-language prompt over forty sources, LLM-judged, deduplicated — and your endpoint stops receiving everything and starts receiving only what matched. Same payload, far less of it.

Connect a webhook → Read the API docs