Simple API to fetch rss feeds for github releases using fresh rss (powered by FastAPI)
This allows you to easily integrate it with https://gethomepage.dev/ Using their Custom API integration
The API provides interactive documentation at:
- Swagger UI:
http://localhost:5000/docs - ReDoc:
http://localhost:5000/redoc
GET /freshrss/unread- Fetch unread RSS items from FreshRSS- Optional query parameters:
n(integer, default10, valid range1–100) - Number of unread items to returncategory(string) - FreshRSS category label to scope unread items, e.g./freshrss/unread?category=Tech
- Optional query parameters:
GET /health- Container health endpoint (does not require authentication)
Bearer authentication is optional. When RSS_API_TOKEN is not set the API
accepts all requests — convenient for trusted/internal networks. Set
RSS_API_TOKEN to a long random secret to require an Authorization: Bearer <token>
header on every protected endpoint. /health always remains unauthenticated.
Generate a long random token with OpenSSL and save it in .env:
RSS_API_TOKEN=$(openssl rand -hex 32)
printf 'RSS_API_TOKEN=%s\n' "$RSS_API_TOKEN" >> .env# With auth enabled (token set):
curl \
-H "Authorization: Bearer <token>" \
"http://localhost:5000/freshrss/unread?n=10&category=Tech"
# Without auth (token not set):
curl "http://localhost:5000/freshrss/unread?n=10&category=Tech"When auth is enabled, clients such as Homepage must send the same header:
headers:
Authorization: Bearer <token>Run the test suite with:
uv sync
uv run pytestGitHub Actions runs these tests for pull requests and before publishing the Docker image from main.
Example of services.yaml:
- Updates:
icon: github.png
href: http://192.168.0.11:5000
siteMonitor: http://192.168.0.11:5000/freshrss/unread
widget:
type: customapi
name: Unread RSS
url: http://192.168.0.11:5000/freshrss/unread
headers:
Authorization: Bearer <token>
display: dynamic-list
mappings:
name: feed
label: displayCopy the example environment file and set the required values:
cp .env.example .envConfigure these environment variables in .env or your Compose environment:
| Variable | Required | Default if unset | Description |
|---|---|---|---|
FRESHRSS_HOST |
Yes | No default; app startup fails. | FreshRSS base URL reachable from the API container. The example .env uses http://freshrss for a same-network Compose service. |
FRESHRSS_USER |
Yes | No default; app startup fails. | FreshRSS username used for Google Reader API login. |
FRESHRSS_PASS |
Yes | No default; app startup fails. | FreshRSS API/GReader password used for Google Reader API login. This is not the normal FreshRSS web UI password. Create or set the API password in FreshRSS user settings and use that value here. |
RSS_API_TOKEN |
No | Empty/unset; bearer auth disabled. | Optional bearer token for this API. When set, protected endpoints require Authorization: Bearer <token>. |
FRESHRSS_HOST must be a URL that is reachable from the API container. Do
not use localhost: inside the container that name refers to the API container
itself, not FreshRSS. Compose validates FRESHRSS_HOST, FRESHRSS_USER, and
FRESHRSS_PASS before creating the container, so an unset or empty value
produces a clear configuration error instead of entering a restart loop.
Important
FRESHRSS_PASS must be the FreshRSS API/GReader password, not your normal
FreshRSS web login password. FreshRSS stores these separately. If you use the
web login password here, FreshRSS may reject the login with 401 and log
Password API mismatch for user <username>.
RSS_API_TOKEN is different from FRESHRSS_PASS:
| Value | Used by | Purpose |
|---|---|---|
FRESHRSS_PASS |
rss-api → FreshRSS |
Logs into FreshRSS through the Google Reader API. Must be the FreshRSS API/GReader password. |
RSS_API_TOKEN |
Client → rss-api |
Protects this API's endpoints with bearer authentication. Optional. |
Choose one of the following host configurations.
When FreshRSS is a service on the same Compose network, use its service name.
For example, if the service is named freshrss:
services:
freshrss:
image: freshrss/freshrss:latest
# Add the FreshRSS volumes and other settings required by your deployment.
custom-api:
image: ghcr.io/skulldorom/rss-api:latest
environment:
FRESHRSS_HOST: http://freshrss
FRESHRSS_USER: ${FRESHRSS_USER:?Set FRESHRSS_USER in .env}
# Must be the FreshRSS API/GReader password, not the web UI password.
FRESHRSS_PASS: ${FRESHRSS_PASS:?Set FRESHRSS_PASS in .env}
# Optional: require Authorization: Bearer <token> on protected endpoints.
RSS_API_TOKEN: ${RSS_API_TOKEN:-}Equivalently, keep the provided Compose file and set this in .env:
FRESHRSS_HOST=http://freshrssDocker Desktop provides host.docker.internal for reaching a service exposed
by the host. If FreshRSS is published on host port 8020, use:
FRESHRSS_HOST=http://host.docker.internal:8020On Linux, set the host's address explicitly (replace the example address with one reachable from Docker):
FRESHRSS_HOST=http://192.168.1.10:8020Alternatively, map Docker's host gateway in docker-compose.yml and then use
the same hostname as the Docker Desktop example:
services:
custom-api:
extra_hosts:
- "host.docker.internal:host-gateway"FRESHRSS_HOST=http://host.docker.internal:8020If API requests fail with:
FreshRSS login failed with status 401
and FreshRSS logs show:
Password API mismatch for user <username>
then FRESHRSS_PASS is probably set to the normal FreshRSS web login password.
Fix it by creating or setting the FreshRSS API/GReader password in FreshRSS user
settings, then update .env:
FRESHRSS_PASS=<your-freshrss-api-password>Restart the API container after changing .env.
You can run the API using the pre-built image from GitHub Container Registry:
docker compose upThis uses the image ghcr.io/skulldorom/rss-api:latest.
If you want to build locally, update docker-compose.yml to use build: . instead of the image: field.
The container image defines a Docker HEALTHCHECK that calls GET /health.
If you want to override it in docker-compose.yml, you can add a service-level healthcheck block.
Go to the location where you ran git clone, cd rss-api
docker compose down
git pull origin main
docker compose up -d