Google Reader API compatibility
RSSMonster exposes its Google Reader-compatible API at /api/greader. The implementation targets the clients listed below and intentionally does not attempt to reproduce every historical Google endpoint.
Authentication setup
Clients use their RSSMonster username and password with ClientLogin. The response contains a credential for the Reader authorization header:
Authorization: GoogleLogin auth=<username>/<authentication-token>
State-changing requests must also send the 57-character action token returned by GET /reader/api/0/token in the T form or query parameter. Authentication tokens and action tokens are separate credentials. Reader responses containing credentials or mutable state use Cache-Control: no-store, private.
Examples below use placeholders and contain no real credentials:
curl --request POST \
--data-urlencode 'Email=<username>' \
--data-urlencode 'Passwd=<password>' \
'https://rss.example.test/api/greader/accounts/ClientLogin'
curl --header \
'Authorization: GoogleLogin auth=<username>/<authentication-token>' \
'https://rss.example.test/api/greader/reader/api/0/subscription/list?output=json'
curl --header \
'Authorization: GoogleLogin auth=<username>/<authentication-token>' \
'https://rss.example.test/api/greader/reader/api/0/token'
curl --request POST \
--header \
'Authorization: GoogleLogin auth=<username>/<authentication-token>' \
--form 'T=<action-token>' \
--form 'subscriptions_file=@subscriptions.opml;type=text/xml' \
'https://rss.example.test/api/greader/reader/api/0/subscription/import'
To verify that a reverse proxy forwards the Authorization header:
curl --header \
'Authorization: GoogleLogin auth=<username>/<64-character-token>' \
'https://rss.example.test/api/greader/check/compatibility'
The check returns PASS Authorization header forwarded for the supported header shape. Missing or unsupported headers return a FAIL ... response. It checks proxy/header transport, not account credentials.
Supported endpoint matrix
| Endpoint | Methods | Support |
|---|---|---|
/accounts/ClientLogin | GET, POST | Supported |
/check/compatibility | GET | Supported header-forwarding check |
/reader/api/0/token | GET | Supported |
/reader/api/0/user-info | GET | Supported |
/reader/api/0/tag/list | GET | Feed categories only |
/reader/api/0/subscription/list | GET | Supported; htmlUrl is empty until publisher-site metadata is stored |
/reader/api/0/subscription/edit | GET, POST | Supported; repeated s and positionally paired t accepted; GET retained for existing clients |
/reader/api/0/subscription/quickadd | POST | Supported |
/reader/api/0/subscription/import | POST | Multipart subscriptions_file, application/xml, or text/xml; maximum 1 MiB |
/reader/api/0/subscription/export | GET | Supported OPML export |
/reader/api/0/unread-count | GET | Supported |
/reader/api/0/stream/contents[/<stream>] | GET | Supported |
/reader/api/0/stream/items/ids | GET | Supported |
/reader/api/0/stream/items/contents | GET, POST | Supported |
/reader/api/0/edit-tag | POST | Read and starred states supported |
/reader/api/0/mark-all-as-read | POST | Supported |
/reader/api/0/rename-tag | POST | Feed categories supported |
/reader/api/0/disable-tag | POST | Feed categories supported; repeated s accepted |
Client integration checklist
The repository’s named source-derived smoke fixtures exercise representative setup and synchronization sequences for each intended client. They are based on established Reader client behavior and the FreshRSS/Tiny Tiny RSS compatibility implementation used for the audit; they are not packet captures. No user-agent-specific behavior is present. A live traffic capture has not been checked into the repository, so client-version-specific behavior should still be recorded during release smoke testing.
| Client | Endpoint groups in the RSSMonster contract | Release status |
|---|---|---|
| NetNewsWire | ClientLogin, subscription/list, bare item lookup | Named source-derived smoke fixture; live client capture pending |
| Reeder | token, unread-count, edit-tag | Named source-derived smoke fixture; live client capture pending |
| FeedMe | quickadd with missing and valid action tokens | Named source-derived smoke fixture; RSSMonster intentionally requires the action token; live client capture pending |
| Fluent Reader | doubled feed prefix, r=n, stream contents | Named source-derived smoke fixture; live client capture pending |
| NewsFlash | stream/items/ids, stream/items/contents, mark-all-as-read | Named source-derived smoke fixture; live client capture pending |
Identifier and time contracts
- Reading list:
user/-/state/com.google/reading-list - Read state:
user/-/state/com.google/read - Starred state:
user/-/state/com.google/starred - Feed:
feed/<percent-encoded subscription URL> - Compatibility input also normalizes duplicated
feed/feed/<reference>prefixes for feed streams and subscription operations. - Feed category:
user/-/label/<percent-encoded category name> - Serialized item IDs: 16-character lowercase hexadecimal IDs in
tag:google.com,2005:reader/item/<hex>form. - Item lookup accepts strict positive decimal IDs, exactly 16 hexadecimal characters, or the complete tagged form.
- Stream order accepts
r=ofor oldest-first andr=dorr=nfor newest-first. - Continuations contain the publication timestamp in milliseconds and article ID, separated by
:. crawlTimeMsecis the immutable RSSMonster insertion time in milliseconds.timestampUsecis publisher publication time in microseconds.publishedis publisher publication time in seconds.ot,nt, and mark-alltsare interpreted against immutable insertion time and accept seconds, milliseconds, or microseconds.
Unsupported behavior and deliberate limits
- Arbitrary Google Reader article-label mutation is unsupported. RSSMonster’s
Tagrows contain crawl-derived, feed-derived, rule-derived, and manual metadata under one per-article name uniqueness rule. Treating those rows as Reader labels would make label removal destroy derived metadata or create collisions. Feed categories remain distinct and are not used as article labels. - Historical Google preference, recommendation, friend, broadcast, note, and sharing endpoints are not implemented because no intended RSSMonster client flow currently requires them.
- OPML import performs the same URL validation, guarded outbound discovery, canonical URL handling, metadata initialization, and duplicate handling as regular feed creation. Uploads are held in memory and are limited to 1 MiB; no user-controlled filename is written.
FEED_MAX_COUNTcontrols the maximum claimed crawl batch size. Deployments using the previousMAX_FEEDCOUNTname remain temporarily supported when the new name is absent. This is not a subscription-count cap, so the API does not misrepresent it as one.