Skip to content

Get Methods

Info

  • All calls should include the SID in the cookie (for TTRSS and FreshRSS implementations, add ‘Authorisation’: GoogleLogin auth={auth} to the header of the request)
  • All query-type operations should include the T token (&T=) (recommended to pass all to prevent errors)
  • Unless otherwise specified, request addresses are ~/reader/api/0/, e.g. freshrss.example.net/api/greader.php/reader/api/0/.
  • It is recommended to keep the client parameter to show the distinction between different clients (&client=) (passed in as params)
  • GReader and its implementation use the URL of a feed as its feed ID and the Atom entry ID of a post as its post ID.
  • In GReader and its implementation, folders are actually tags (or labels in GReader terminology), meaning that the same feed can exist in multiple folders
  • All calls accept a ck=[timestamp] parameter, which according to the Google Reader API documentation is the ‘current timestamp, possibly a shortcut used to ensure that caching is not triggered’.

Note

In the example code, we are using a pass method that is compatible with both the original Google Reader API and FreshAPI (i.e., we are passing in both the SID and the header), and both include the T token

Get subscription list

Endpoint:subscription/list

Method:GET

params:

parameter required sample value default value type description
output yes json/xml xml string Select the format of the output

usage:

curl -s -H 'Authorization: GoogleLogin auth=alice/8e6845e089457af25303abc6f53356eb60bdb5f8' -H 'Cookie: SID=YOUR_SID' \
    'https://freshrss.example.net/api/greader.php/reader/api/0/subscription/list?output=json&client=myclient&T=YOUR_T_TOKEN'
import requests

url = 'https://freshrss.example.net/api/greader.php/reader/api/0/subscription/list'
header = {
    "Authorization: GoogleLogin auth=alice/8e6845e089457af25303abc6f53356eb60bdb5f8"
}
params = {
    'output': 'json',
    'client': 'myclient',
    'T': 'YOUR_T_TOKEN'
}
cookies = {'SID': 'YOUR_SID'}
try:
    response = requests.get(url, headers=header, params=params, cookies=cookies)
    response.raise_for_status()
    print(response.text)

except requests.exceptions.RequestException as e:
    print(f"An error occurred: {e}")

When output=xml, the return example is as follows

<object> 
<string name="id">feed/http://feeds.feedburner.com/NickBradbury</string>  
<string name="title">Nick Bradbury</string>  
<list name="categories"> 
<object> 
<string name="id">user/[USER_ID]/label/Bradbury Software</string>  
<string name="label">Bradbury Software</string>  
</object> 
</list> 
<string name="sortid">C430EC8F</string>  
<number name="firstitemmsec">1203460831522</number>  
</object> 

When output=json, the return example is as follows

{
    "subscriptions": [{
        "id": "feed/39",
        "title": "标题测试1",
        "categories": [{
            "id": "user/-/label/Uncategorized",
            "label": "Uncategorized"
        }],
        "url": "https://example.com",
        "htmlUrl": "https://example-html.com",
        "iconUrl": "http://example/public.php?op=feed_icon&id=39.ico"
    }, {
        "id": "feed/31",
        "title": "标题测试2",
        "categories": [{
            "id": "user/-/label/分类测试1",
            "label": "分类测试1"
        }],
        "url": "https://example.com",
        "htmlUrl": "https://example-html.com",
        "iconUrl": "http://example/public.php?op=feed_icon&id=31.ico"
    }, {
        "id": "feed/30",
        "title": "标题测试3",
        "categories": [{
            "id": "user/-/label/分类测试1",
            "label": "分类测试1"
        }],
        "url": "https://example.com",
        "htmlUrl": "https://example-html.com",
        "iconUrl": "http://example/public.php?op=feed_icon&id=30.ico"
    }]
}

Info

The name of the folder is stored as in the node. Feeds in the root folder have an empty node. The firstitemmsec attribute is the timestamp of the oldest (first) item in that user's subscription.

A simpler way is to call subscriptions/export as a GET method to get an export of the OPML file, but this does not include any GReader data (such as firstitemmsec).

Note: The / in the request parameter needs to be URL encoded, e.g. / is encoded as %2F.

Note: The operation will fail unless the feed parameter (s parameter) is passed. (It is not possible to create an empty folder, you must create a folder with a subscription feed)

Get the total unread count of the reader

Endpoint:unread-count

Method:GET

params:

parameter required sample value default value type description
output yes xml/json xml string Select the format of the output

usage:

curl -s -H 'Authorization: GoogleLogin auth=alice/8e6845e089457af25303abc6f53356eb60bdb5f8' -H 'Cookie: SID=YOUR_SID' \
    'https://freshrss.example.net/api/greader.php/reader/api/0/unread-count?output=json&client=myclient&T=YOUR_T_TOKEN'
import requests

url = 'https://freshrss.example.net/api/greader.php/reader/api/0/unread-count'
header = {
    "Authorization: GoogleLogin auth=alice/8e6845e089457af25303abc6f53356eb60bdb5f8"
}
params = {
    'output': 'json',
    'client': 'myclient',
    'T': 'YOUR_T_TOKEN'
}
cookies = {'SID': 'YOUR_SID'}
try:
    response = requests.get(url, headers=header, params=params, cookies=cookies)
    response.raise_for_status()
    print(response.text)

except requests.exceptions.RequestException as e:
    print(f"An error occurred: {e}")

If there are unread entries, return the xml sample as follows

<object> 
    <number name="max">1000</number> 
    <list name="unreadcounts"> 
        <object> 
            <string name="id">user/-/state/com.google/reading-list</string> 
            <number name="count">8</number> 
            <number name="newestItemTimestampUsec">1232641608774062</number> 
        </object> 
        <object> 
            <string name="id">feed/http://rss.cnn.com/rss/cnn_topstories.rss</string> 
            <number name="count">4</number> 
            <number name="newestItemTimestampUsec">1232641203555343</number> 
        </object> 
        <object> 
            <string name="id">user/-/label/FolderName</string> 
            <number name="count">8</number> 
            <number name="newestItemTimestampUsec">1232641608774062</number> 
        </object> 
        <object> 
            <string name="id">feed/http://www.engadget.com/rss.xml</string> 
            <number name="count">4</number> 
            <number name="newestItemTimestampUsec">1232641608774062</number> 
        </object> 
</list> 
</object> 
Returns a json example as follows

{
    "max": 8
    "unreadcounts": [
        {
            "id": "user/-/state/com.google/reading-list",
            "count": 8,
            "newestItemTimestampUsec": "1232641608774062"
        },
        {
            "id": "feed/http://rss.cnn.com/rss/cnn_topstories.rss",
            "count": 4,
            "newestItemTimestampUsec": "1232641203555343"
        },
                {
            "id": "user/-/label/FolderName",
            "count": 8,
            "newestItemTimestampUsec": "1232641608774062"
        },
        {
            "id": "feed/http://www.engadget.com/rss.xml",
            "count": 4,
            "newestItemTimestampUsec": "1232641608774062"
        }
        ...
    ]
}

If there are no unread entries, return the xml sample as follows

<object> 
    <number name="max">1000</number> 
    <list name="unreadcounts"/> 
</object> 

Returns a json example as follows

{
  "max": 1000,
  "unreadcounts": []
}

Get all entries

Endpoint:stream/contents/user/-/state/com.google/reading-list

Method:GET

params:

parameter required sample value default value type description
n no 20 20 number Maximum number of requests, up to 1000
r no o / n o string Sort by. o means sort by posting time (old->new), n means sort by updating time (new->old).
t no 1678886400 none number Get articles that are more recent than the specified timestamp (Unix timestamp, milliseconds)
ot no 1678886400 none number Get articles older than the specified timestamp (Unix timestamp, milliseconds)
xt no user/-/state/com.google/read none string Exclude tab, example for excluding read content
c no continuation string none string Continued reading string for paging to load more entries
output yes xml/json json string Sample output, defaults to json

usage:

curl -s -H 'Authorization: GoogleLogin auth=alice/8e6845e089457af25303abc6f53356eb60bdb5f8' -H 'Cookie: SID=YOUR_SID' \
    'https://freshrss.example.net/api/greader.php/reader/api/0/stream/contents/user/-/state/com.google/reading-list?n=20&r=o&ot=1678886400&xt=user/-/state/com.google/read&output=json&client=myclient&T=YOUR_T_TOKEN'
import requests

url = 'https://freshrss.example.net/api/greader.php/reader/api/0/stream/contents/user/-/state/com.google/reading-list'
header = {
    "Authorization: GoogleLogin auth=alice/8e6845e089457af25303abc6f53356eb60bdb5f8"
}
params = {
    'n': 20,
    'r': 'o',
    'ot': 1678886400,
    'xt': 'user/-/state/com.google/read',
    'output': 'json',
    'client': 'myclient',
    'T': 'YOUR_T_TOKEN'
}
cookies = {'SID': 'YOUR_SID'}
try:
    response = requests.get(url, headers=header, params=params, cookies=cookies)
    response.raise_for_status()
    print(response.text)

except requests.exceptions.RequestException as e:
    print(f"An error occurred: {e}")

Response:

Get user info

Endpoint:user-info

Method:GET

Parmas:None

usage:

curl -s -H 'Authorization: GoogleLogin auth=alice/8e6845e089457af25303abc6f53356eb60bdb5f8' -H 'Cookie: SID=YOUR_SID' \
    'https://freshrss.example.net/api/greader.php/reader/api/0/user-info?T=YOUR_T_TOKEN'
import requests

url = 'https://freshrss.example.net/api/greader.php/reader/api/0/user-info'
header = {
    "Authorization: GoogleLogin auth=alice/8e6845e089457af25303abc6f53356eb60bdb5f8"
}
params ={
    'T': 'YOUR_T_TOKEN'
}
cookies = {'SID': 'YOUR_SID'}
try:
    response = requests.get(url, headers=header, params=params, cookies=cookies)
    response.raise_for_status()
    print(response.text)

except requests.exceptions.RequestException as e:
    print(f"An error occurred: {e}")

Response:

{
    "userId":"admin",
    "userName":"admin",
    "userProfileId":"admin",
    "userEmail":""
}

Get user's friend information

Endpoint:friend/list

Method:GET

Parmas:None

usage:

curl -s -H 'Authorization: GoogleLogin auth=alice/8e6845e089457af25303abc6f53356eb60bdb5f8' -H 'Cookie: SID=YOUR_SID' \
    'https://freshrss.example.net/api/greader.php/reader/api/0/friend/list&T=YOUR_T_TOKEN'
import requests

url = 'https://freshrss.example.net/api/greader.php/reader/api/0/friend/list'
header = {
    "Authorization: GoogleLogin auth=alice/8e6845e089457af25303abc6f53356eb60bdb5f8"
}
params ={
    'T': 'YOUR_T_TOKEN'
}
cookies = {'SID': 'YOUR_SID'}
try:
    response = requests.get(url, headers=header, params=params, cookies=cookies)
    response.raise_for_status()
    print(response.text)

except requests.exceptions.RequestException as e:
    print(f"An error occurred: {e}")

Getting information about reader preferences

Endpoint:preference/list

Method:GET

Parmas:None

usage:

curl -s -H 'Authorization: GoogleLogin auth=alice/8e6845e089457af25303abc6f53356eb60bdb5f8' -H 'Cookie: SID=YOUR_SID' \
    'https://freshrss.example.net/api/greader.php/reader/api/0/preference/list&T=YOUR_T_TOKEN'
import requests

url = 'https://freshrss.example.net/api/greader.php/reader/api/0/preference/list'
header = {
    "Authorization: GoogleLogin auth=alice/8e6845e089457af25303abc6f53356eb60bdb5f8"
}
params ={
    'T': 'YOUR_T_TOKEN'
}
cookies = {'SID': 'YOUR_SID'}

try:
    response = requests.get(url, headers=header, params=params, cookies=cookies)
    response.raise_for_status()
    print(response.text)

except requests.exceptions.RequestException as e:
    print(f"An error occurred: {e}")

Get starred articles

Endpoint:preference/list/stream/contents/user/-/state/com.google/starred

Method:GET

Parmas:

parameter required sample value default value type description
n yes 20 none number Get the number of starred articles, the maximum is 1000.
output no json/xml json string Sample output, defaults to json

usage:

curl -s -H 'Authorization: GoogleLogin auth=alice/8e6845e089457af25303abc6f53356eb60bdb5f8' -H 'Cookie: SID=YOUR_SID' \
    'https://freshrss.example.net/api/greader.php/reader/api/0/stream/contents/user/-/state/com.google/starred?n=20&output=json&client=myclient&T=YOUR_T_TOKEN'
import requests

url = 'https://freshrss.example.net/api/greader.php/reader/api/0/stream/contents/user/-/state/com.google/starred'
header = {
    "Authorization: GoogleLogin auth=alice/8e6845e089457af25303abc6f53356eb60bdb5f8"
}
params = {
    'n': 20,
    'output': 'json',
    'client': 'myclient',
    'T': 'YOUR_T_TOKEN'
}
cookies = {'SID': 'YOUR_SID'}
try:
    response = requests.get(url, headers=header, params=params, cookies=cookies)
    response.raise_for_status()
    print(response.text)

except requests.exceptions.RequestException as e:
    print(f"An error occurred: {e}")

Response

{
  "id": "user/-/state/com.google/reading-list",
  "updated": 1738469151,
  "items": [
    {
      "id": "tag:google.com,2005:reader/item/000000000001035c",
      "crawlTimeMsec": "1738411626000",
      "timestampUsec": "1738411626000000",
      "published": 1738411626,
      "title": "...",
      "canonical": [
        {
          "href": "...""
        }
      ],
      "alternate": [
        {
          "href": "...""
        }
      ],
      "categories": [
        "user/-/state/com.google/read",
        "user/-/state/com.google/starred"
      ],
      "origin": {
        "streamId": "feed/31",
        "title": "..."",
        "htmlUrl": "...""
      },
      "summary": {
        "content": "...""
      },
      "author": ""
    }
  ],
  "continuation": "1"
}

Prase feed url

Endpoint:/atom/feed/{feed_url}

Method:GET

Parmas:

parameter required sample value default value type description
feed_url yes http://feeds.feedburner.com/NickBradbury none string RSS links to be prased
n no 40 20 number Number of loaded article entries
xt no user/-/state/com.google/read none string Excluded labels

usage:

curl -s -H 'Authorization: GoogleLogin auth=alice/8e6845e089457af25303abc6f53356eb60bdb5f8' -H 'Cookie: SID=YOUR_SID' \
    'https://freshrss.example.net/api/greader.php/reader/api/0/atom/feed/http://feeds.feedburner.com/NickBradbury?n=40&xt=user/-/state/com.google/read&client=myclient&T=YOUR_T_TOKEN'
import requests

url = 'https://freshrss.example.net/api/greader.php/reader/api/0/atom/feed/http://feeds.feedburner.com/NickBradbury'
header = {
    "Authorization: GoogleLogin auth=alice/8e6845e089457af25303abc6f53356eb60bdb5f8"
}
params = {
    'n': 40,
    'xt': 'user/-/state/com.google/read',
    'client': 'myclient',
    'T': 'YOUR_T_TOKEN'
}
cookies = {'SID': 'YOUR_SID'}
try:
    response = requests.get(url, headers=header, params=params, cookies=cookies)
    response.raise_for_status()
    print(response.text)

except requests.exceptions.RequestException as e:
    print(f"An error occurred: {e}")

Response:

<entry>
  <id>tag:google.com,2005:reader/item/30fd6c8e007ebcbf</id>
  <published>2009-01-03T18:37:04Z</published>
  <updated>2009-01-03T18:37:04Z</updated>
  <title>[Article summary]</title>
  <content type="html">[Article content]</content>
  <author>
    <name>Nick Bradbury</name>
  </author>
  <link rel="alternate" href="http://example.com/article" />
  <category scheme="http://www.google.com/reader/atom" term="tag:google.com,2005:reader/feed/http://feeds.feedburner.com/NickBradbury" />
  <gr:crawl-timestamp-msec>1233716224000</gr:crawl-timestamp-msec>  <!-- Unix timestamp -->
  <gr:is-read-state-locked>true</gr:is-read-state-locked> <!-- If an entry is locked as unread -->
</entry>

Note

gr:crawl-timestamp-msec Indicates the Unix timestamp (in milliseconds) at which Google Reader received the article.

gr:is-read-state-locked=‘true’: This attribute is included if the reading state of the entry is locked (‘remain unread’).

<id> The value of the entry is always the ID in Google Reader, replacing the original GUID/ID in the subscription feed. The original GUID/ID can still be retrieved from the ID node, e.g..

<id gr:original-id=‘http://nick.typepad.com/blog/2009/01/’>tag:google.com,2005:reader/item/30fd6c8e007ebcbf</id>

Categories is used to reflect not only the category assigned to the entry in the actual feed, but also the read/tagged status in GReader.

  • If an article has been read, its Categories will look like this:
    • <category term=‘user/[userid]/state/com.google/read’ scheme=‘http://www.google.com/reader/’ label=‘read’ />
  • If an article has been starred, its **Categories ** will look like this:
    • <category term=‘user/[userid]/state/com.google/starred’ scheme=‘http://www.google.com/reader/’ label=‘starred’ /> * If an article is in a folder, it will look like this.
  • If an article is in a folder, its Categories will look like this
    • <category term=‘user/[userid]/label/[folderName]’ scheme=‘http://www.google.com/reader/’ label=‘[folderName]’/>

An important part of Google Reader's (GReader's) access to the feed is the continuation feature, which provides a way to page through entries in the feed. For example, if you request the latest 20 entries in the feed, the root element might contain a gr:continuation child element, for example:

<feed xmlns:gr="http://www.google.com/schemas/reader/atom/" xmlns="http://www.w3.org/2005/Atom"> 
    <generator uri="http://www.google.com/reader">Google Reader</generator> 
    <id>tag:google.com,2005:reader/feed/http://feeds.feedburner.com/NickBradburyClippings</id> 
    <title>Nick Bradbury&amp;#39;s Shared Items on NewsGator Online</title> 
    <updated>2009-01-15T15:17:16Z</updated> 
<gr:continuation>CP__hN2fq5gC</gr:continuation>  

Simply append the gr:continuation value to subsequent requests to get the next 20 entries in the subscription feed, for example: GET http://www.google.com/reader/atom/feed/http://feeds.feedburner.com/NickBradbury&c=CP__hN2fq5gC This makes it possible to access the history of the subscription feed, which may be useful immediately after subscribing to the feed or the first time a user chooses to enable GReader synchronisation.

Get user's shared entires

Info

For self-hosting RSS readers, shared items may be useless and unsupported, so not all API-compatible implementations will be able to call this API

Endpoint:/reader/atom/user/-/state/com.google/broadcast&n={count}

Method:GET

Parmas:

parameter required sample value default value type description
{count} yes 20 none number To get the number of articles shared by users

usage:

curl -s -H 'Authorization: GoogleLogin auth=alice/8e6845e089457af25303abc6f53356eb60bdb5f8' -H 'Cookie: SID=YOUR_SID' \
    'https://freshrss.example.net/api/greader.php/reader/api/0/reader/atom/user/-/state/com.google/broadcast?n=20&client=myclient&T=YOUR_T_TOKEN'
import requests

url = 'https://freshrss.example.net/api/greader.php/reader/api/0/reader/atom/user/-/state/com.google/broadcast'
header = {
    "Authorization: GoogleLogin auth=alice/8e6845e089457af25303abc6f53356eb60bdb5f8"
}
params = {
    'n': 20,
    'client': 'myclient',
    'T': 'YOUR_T_TOKEN'
}
cookies = {'SID': 'YOUR_SID'}
try:
    response = requests.get(url, headers=header, params=params, cookies=cookies)
    response.raise_for_status()
    print(response.text)

except requests.exceptions.RequestException as e:
    print(f"An error occurred: {e}")

Note

  • Note that the entry ID must be the ID of the entry in the GReader, so entries from non-GReader sources need to be shared as if they were arbitrary URLs, for example:
  • POST item/edit?share=true&title={title}&url={url}&snippet={snippet}&srcTitle=‘{srcTitle}’&srcUrl={srcUr}.
  • When retrieving the user's shared project again, you will see that GReader has assigned an entry ID to this project. sourceTitle and srcUrl parameters are the name and link of the project's source page/source, respectively. You can also add the annotation parameter. The annotated shared project entry (‘Shared with notes’) will contain something like this

Get a list of tags (folders)

Endpoint:tag/list

Method:GET

Parmas:

parameter required sample value default value type description
output yes xml/json none string Sample output, defaults to json

usage:

curl -s -H 'Authorization: GoogleLogin auth=alice/8e6845e089457af25303abc6f53356eb60bdb5f8' -H 'Cookie: SID=YOUR_SID' \
    'https://freshrss.example.net/api/greader.php/reader/api/0/tag/list?output=json&client=myclient&T=YOUR_T_TOKEN'

```python import requests

url = 'https://freshrss.example.net/api/greader.php/reader/api/0/tag/list' header = { "Authorization: GoogleLogin auth=alice/8e6845e089457af25303abc6f53356eb60bdb5f8" } params = { 'output': "json", 'client': 'myclient', 'T': 'YOUR_T_TOKEN' } cookies = {'SID': 'YOUR_SID'} try: response = requests.get(url, headers=header, params=params, cookies=cookies) response.raise_for_status() print(response.text)

except requests.exceptions.RequestException as e: print(f"An error occurred: {e}")

If output=json, the Response is as follows:

{
    "tags": [{
        "id": "user/-/state/com.google/starred"
    }, {
        "id": "user/-/label/A",
        "type": "folder"
    }, {
        "id": "user/-/label/B",
        "type": "folder"
    }, {
        "id": "user/-/label/C",
        "type": "folder"
    }, {
        "id": "user/-/label/D",
        "type": "folder"
    }, {
        "id": "user/-/label/E",
        "type": "folder"
    }, {
        "id": "user/-/label/F",
        "type": "tag"
    }, {
        "id": "user/-/label/G",
        "type": "folder"
    }, {
        "id": "user/-/label/H",
        "type": "tag"
    }, {
        "id": "user/-/label/I",
        "type": "folder"
    }, {
        "id": "user/-/label/J",
        "type": "folder"
    }, {
        "id": "user/-/label/K",
        "type": "folder"
    }, {
        "id": "user/-/label/L",
        "type": "tag"
    }, {
        "id": "user/-/label/Uncategorized",
        "type": "folder"
    }, {
        "id": "user/-/label/测试",
        "type": "tag"
    }]
}

Note

Since Google Reader treats folders as labels, this list will contain folder names. The client needs to parse out the actual folder name labels themselves.