BIO.RE
Content

Blog RSS Feed

RSS 2.0 XML feed of the last 20 published blog posts. Content-Type application/rss+xml. Bot-detection skipped (feed readers should not be flagged). CDN 15min/30min SWR.

GET /api/v1/public/blog/feed โ€” ๐ŸŒ Public ยท Rate limit: 30 req / minute

Returns the last 20 published blog posts as an RSS 2.0 XML feed for feed readers (NetNewsWire, Feedly, Reeder, etc). Bot-detection is skipped (@SkipBotDetection()) โ€” feed readers are bot-like and shouldn't be challenged. Cached 15min at the CDN with 30min stale-while-revalidate.

Different response shape from the rest of the portal. This endpoint returns raw XML with Content-Type: application/rss+xml; charset=utf-8 โ€” NOT the standard JSON { success, data } envelope. Consume with an XML parser (or just hand to your feed reader). The standard error envelope still applies for 4xx/5xx, but the success path is XML.

Cap is 20 (lower than the regular list). Feeds are designed for "what's new" โ€” the last 20 posts is plenty. The regular /public/blog endpoint serves up to 50 per page with full pagination if you need older posts.

Request

No body, no params, no headers required.

Response headers

HeaderValue
Content-Typeapplication/rss+xml; charset=utf-8
Cache-Controlpublic, s-maxage=900, stale-while-revalidate=1800

Response

200 OK โ€” RSS 2.0 XML

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
  <title>BIO.RE Blog</title>
  <link>https://bio.re/blog</link>
  <description>Latest posts from the BIO.RE blog</description>
  <language>en</language>
  <lastBuildDate>Wed, 29 Apr 2026 20:00:00 GMT</lastBuildDate>
  <atom:link href="https://bio.re/api/v1/public/blog/feed" rel="self" type="application/rss+xml"/>
  <item>
    <title>Introducing BIO.RE</title>
    <link>https://bio.re/blog/introducing-biore</link>
    <guid isPermaLink="true">https://bio.re/blog/introducing-biore</guid>
    <description><![CDATA[A short excerpt of the post...]]></description>
    <pubDate>Wed, 29 Apr 2026 20:00:00 GMT</pubDate>
    <category>Product Updates</category>
  </item>
</channel>
</rss>

XML elements

ElementSourceNotes
channel.titlehardcodedBIO.RE Blog
channel.linkhardcodedhttps://bio.re/blog
channel.descriptionhardcodedLatest posts from the BIO.RE blog
channel.languagehardcodeden
channel.lastBuildDatecomputedThe most recent publishedAt of any item, formatted as RFC 822 (UTC)
channel.atom:linkhardcodedSelf-link to this feed
item.title / item.link / item.guid / item.pubDateper postIndividual post metadata. Title is XML-escaped server-side.
item.descriptionper postThe post's excerpt (or empty), wrapped in CDATA[]
item.categoryper post categoryOne <category> element per associated BlogCategory.name, XML-escaped

Errors

HTTPReason
429Rate limit exceeded (30 req/min โ€” tighter than the JSON list)

Side effects

  1. getBlogFeedItems() โ€” prisma.blogPost.findMany({ where: status PUBLISHED, orderBy publishedAt desc, take: 20, select: slug+title+excerpt+publishedAt+categories }).
  2. Build XML string by concatenation. Each user-controllable field passes through xmlEscape() (replaces &, <, >, ", ' with entities).
  3. Set Content-Type: application/rss+xml; charset=utf-8 + cache header on the raw response (@Res() mode โ€” bypasses the standard interceptor).
  4. Return the XML body. No mutations.

Code samples

curl https://api.bio.re/api/v1/public/blog/feed
https://api.bio.re/api/v1/public/blog/feed

Paste this URL into NetNewsWire / Feedly / Reeder / Inoreader. Most feed readers will auto-detect the format and start polling.

// Server-side โ€” fetch + parse with rss-parser
import Parser from 'rss-parser';

const parser = new Parser();

async function fetchBlogFeed() {
  const feed = await parser.parseURL('https://api.bio.re/api/v1/public/blog/feed');
  for (const item of feed.items) {
    console.log(item.title, item.link, item.pubDate);
  }
}

Try it

GET
/api/v1/public/blog/feed

Response Body

curl -X GET "https://loading/api/v1/public/blog/feed"
Empty

Source

SourcePathLines
Controllerapps/api-core/src/modules/content/public-content.controller.ts209โ€“222 (getBlogRssFeed), 145โ€“147 (xmlEscape), 149โ€“179 (buildRss2)
Serviceapps/api-core/src/modules/content/content.service.ts578โ€“... (getBlogFeedItems โ€” slug+title+excerpt+publishedAt+categories slice)
Prisma modelpackages/prisma/prisma/schema.prismaBlogPost (filter status = PUBLISHED), BlogCategory (joined for <category> elements)
Bot detection skipapps/api-core/src/common/decorators/skip-bot-detection.decorator.ts@SkipBotDetection()

On this page