Skip to content

Instantly share code, notes, and snippets.

@d3m3vilurr
Last active September 5, 2023 06:24
Show Gist options
  • Star 88 You must be signed in to star a gist
  • Fork 13 You must be signed in to fork a gist
  • Save d3m3vilurr/5904029 to your computer and use it in GitHub Desktop.
Save d3m3vilurr/5904029 to your computer and use it in GitHub Desktop.
Unofficial Feedly API Document

IDs

  • user_id - user/:uid
  • feed_id - feed/:feed_uri
  • category_id - :user_id/category/:category (special category: global.all, global.uncategorized)
  • tag_id - :user_id/tag/:tag (special tag: global.saved)

APIs

http://cloud.feedly.com/:version/:api

  • Common params
    • ck - timestamp (optional)
    • ct - client type (eg: feedly.desktop, optional)
    • cv - client version (eg: 16.0.548, optional)

HTTP Header must have Authorization field except auth and feeds apis

Field format like this; Authorization: OAuth :oauth_token

auth

Login process

Step

  1. GET /v3/auth/auth

Automatic oauth2 chain

  • Params
    • client_id - feedly (fixed)
    • redirect_uri - https://cloud.feedly.com/feedly.html (fixed)
    • scope - https://cloud.feedly.com/subscriptions (fixed)
    • response_type - code (fixed)
    • provider - google (fixed)
    • migrate - false (fixed, now feedly not support migrate google reader)

Final URI of oauth chain; https://cloud.feedly.com/feedly.html?code=:code&state=

  1. POST /v3/auth/token

Generate and refresh oauth token

  • Body

    Normal application/x-www-form-urlencoded format, not application/json

        client_id=feedly
        &client_secret=0XP4XQ07VVMDWBKUHTJM4WUQ
        &grant_type=authorization_code
        &redirect_uri=http%3A%2F%2Fwww.feedly.com%2Ffeedly.html
        &code=:code
    

    or

        client_id=feedly
        &client_secret=0XP4XQ07VVMDWBKUHTJM4WUQ
        &grant_type=refresh_token
        &refresh_token=:refresh_token
    
  • Response

    authorization_code mode

        {
          "refresh_token": ":refresh_token",
          "access_token": ":oauth_token",
          "expires_in": :second,
          "token_type": "Bearer",
          "id": ":uid"
        }
    

    refresh_token mode

        {
          "token_type": "Bearer"
          "access_token": ":oauth_token",
          "expires_in": :second,
          "id": ":uid"
        }
    

feeds

No need authorization

  • Using

    GET /v3/feeds/:feed_id

  • Response

      {
        "id": ":feed_id", 
        "subscribers": :subscriber_count, 
        "title": ":feed_title", 
        "velocity": :velocity, 
        "website": ":site_uri"
      }
    

profile

  • Using

    GET /v3/profile

  • Reponse

      {
        "email": ":email",
        "familyName": ":family_name",
        "gender": ":gender",
        "givenName": ":first_name",
        "google": ":google_plus_key",
        "id": ":uid",
        "locale": ":locale",
        "picture": ":profile
        _avatar_uri",
        "reader": ":reader_key",
        "wave": ":wave"
      }
    

subscriptions

subscripted feed control

  • Using

    GET /v3/subscripts or POST /v3/subscripts or DELETE /v3/subscripts/:feed_id

  • Body

    POST method only

      {
        "id": ":feed_id",
        "title": ":feed_title",
        "categories": [
          {
            "id": ":category_id",
            "label": ":category"
          }
        ]
      }
    
  • Response

    GET method only

      [
        {
          "categories": [
              {
                  "id": ":category_id",
                  "label": ":category"
              }
          ],
          "id": "feed_id",
          "title": ":feed_title",
          "updated": :timestamp,
          "website": ":feed_uri"
        },
        ...
      ]
    

streams

load feed stream

  • Using

    GET /v3/streams/:category_id_or_feed_id_or_tag_id/contents

  • Params

    • count - load max count (default: 20)
    • unreadOnly - true or false (default: false)
    • ranked - newest or oldest (default: newest)
    • continuation - until continuation_key (optional)
  • Response

      {
        "continuation": ":continuation_key",
        "id": ":category_id",
        "items": [
          {
            "actionTimestamp": ":action_timestamp",
            "alternate": [
              {
                "href": ":alternate_uri",
                "type": ":mimetype"
              }
            ],
            "author": ":author",
            "canonical": [
              {
                "href": ":canonical_uri",
                "type": ":mimetype"
              }
            ],
            "categories": [
              {
                "id": ":item_category_id",
                "label": ":item_category_name"
              }
            ],
            "crawled": ":crawled_timestamp",
            "fingerprint": ":fingerprint",
            "id": ":item_id",
            "keywords": [
              ":keyword"
            ],
            "origin": {
              "htmlUrl": ":site_uri",
              "streamId": ":feed_id",
              "title": ":feed_title"
            },
            "originId": ":item_uri",                        # optional
            "published": "item_pub_timestamp",
            "summary": {                                  # or content
              "content": ":item_desc",
              "direction": ":text_direction"
            },
            "title": ":item_title",
            "tags": [
              {
                "id": ":tag_id",
                "label": ":tag_name"
              },
              ...
            ],
            "unread": true
          }
        ],
        ...
      }
    

markers

  • Using

    GET /v3/markers/counts or POST /v3/markers

  • Body

    POST method only

      {
        "action": ":action",
        "type": "entries",
        "entryIds": [":item_id"]
      }
    

    or

      {
        "action": ":action",
        "type": "feeds",
        "feedIds":[":feed_id"],
        "asOf": :timestamp
      }
    
    • action - markAsRead or keepUnread
  • Response

    GET method only

      {
        "unreadcounts": [
          {
            "id": ":feed_id_or_category_id",
            "count": :count,
            "updated": :timestamp
          },
          ...
        ],
        "max": :max_count
      }
    

tags

  • Using

    DELETE /v3/tags/:tag_id/:itemid or PUT /v3/tags/:tag_id

  • Body

    PUT method only

      {
        "entryId": ":item_id"
      }
    

Non cloud APIs

http://www.feedly.com/:group/:api

  • Common params
    • ck - timestamp (optional)

search.v2/feeds.v2

  • Using

    GET /search.v2/feeds.v2

  • Params

    • q - search query string
    • lf - false or true (optional)
    • n - max count (default: 5)
    • d - false or true (optional)
  • Response

      {
        "hint": ":query_string",
        "results": [
          {
            "title": ":feed_title",
            "website": "site_uri",
            "feedId": ":feed_id",
            "score": :score,
            "solrScore": :solr_score,
            "deliciousTags: [":delicious_tag"],
            "language": ":lang",
            "velocity": :velocity,
            "subscribers": :subscriber_count,
            "documentBoost": :doc_boost,
            "avgLikes": :avg_like_count,
            "minLikes": :min_like_count,
            "maxLikes": :max_like_count,
            "medLikes": :med_like_count,
            "hint": ":query_string",
            "explain": ":search_query_explain"
          },
          ...
        ],
        "related": [
          ":related_keyword",
          ...
        ]
      }
    
@balupton
Copy link

balupton commented Sep 3, 2013

Where do you get the information about this? I haven't been able to find any docs by Feedly about their API

@d3m3vilurr
Copy link
Author

@balupton: just reverse engineering.
I just used chrome dev tool, curl, and vim. :)

@penso
Copy link

penso commented Sep 12, 2013

@d3m3vilurr @bapulton We can't do anything without an oauth application token, can we?

@d3m3vilurr
Copy link
Author

@penso: yes. many action require oauth token.

client_id=feedly&client_secret=0XP4XQ07VVMDWBKUHTJM4WUQ
this is very valid application token. (used feedly website)

https://gist.github.com/d3m3vilurr/5904029#auth chain generate new user oauth token.

  1. Send GET request
    http://cloud.feedly.com/v3/auth/auth?client_id=feedly&redirect_uri=https://cloud.feedly.com/feedly.html&scope=https://cloud.feedly.com/subscriptions&response_type=code&provider=google&migrate=false

    It should go to google login page (authoriztion chain)
    (eg. https://github.com/d3m3vilurr/libfeedly/blob/5bc8e2cf0/libfeedly/api.py#L91)

  2. Finally you get like this page link
    https://cloud.feedly.com/feedly.html?code=AQAAHSPiHq...&state=

    This code value is short time oauth code.

  3. Send POST request
    http://cloud.feedly.com/v3/auth/token

    with body data is
    client_id=feedly&client_secret=0XP4XQ07VVMDWBKUHTJM4WUQ&grant_type=authorization_code&redirect_uri=http%3A%2F%2Fwww.feedly.com%2Ffeedly.html&code=AQAAHSPiHq...

    You may get new user token.
    (eg. https://github.com/d3m3vilurr/libfeedly/blob/5bc8e2cf0/libfeedly/api.py#L103)

If you need new application token (like using new mobile app auth), should contact feedly

@irodqp
Copy link

irodqp commented Apr 21, 2014

Anyone, any idea on how to implement this on a Weebly Platform? Please Advise

@hazemusa
Copy link

Hello,

I want to run code to retrieve Feeds and their entries on interval basis. I want to store those in two different tables for later processing.
I tried using curl but it looks very complicated to get the data and insert it into the db.
Basically, I get the feeds and based on the results I retrieve each feed entry. Both are then inserted into the database. However, the code should run on regular intervals so that the news are up-to-date in the db and the front-end where I need to use it.
I checked a PHP Feedly API library but the authentication part is a nightmare because when it expires, I don't know how to automate the re-authentication process through curl (Feedly -> Google -> new authentication).

If anyone has some ideas, tips, or advice I would really appreciate it.

Thanks

@hotbaby
Copy link

hotbaby commented Dec 23, 2016

Hello,

The feeds API /v3/feeds/:feedId does not work here.

Request:

http://cloud.feedly.com/v3/feeds/feed/http://www.hadoopweekly.com/feed.xml

Resopnse:

{
  "errorCode": 400,
  "errorId": "ap11-sv2.2016122220.3175965",
  "errorMessage": "invalid feed ids"
}

Thanks

@LovishBathla
Copy link

Hi

I want to extract the articles title,url which i have saved as named "Feed" in Boards Section.
For that i am using cloud.feedly.com/v3/tags Autorization OAuth

But I am getting error 404.

Please help.

@aubryll
Copy link

aubryll commented Jun 26, 2017

How does one parse the http://cloud.feedly.com/v3/streams/contents?streamId=feed response on android?

@pfftdammitchris
Copy link

@LovishBathla you have to encode the feed id in URI params

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment