What's new? | Help | Directory | Sign in
Google
friendfeed-api
FriendFeed API libraries
  
  
  
  
    
Search
for
Updated Apr 17, 2008 by btaylor
Labels: Featured
ApiDocumentation  

FriendFeed API Documentation

Introduction

The FriendFeed API enables developers interact with the FriendFeed web site programmatically via simple HTTP requests.

This is the technical documentation for the API. Other important links:

Core Concepts

Requests and Data Formats

All requests to the FriendFeed API are simple HTTP GET and POST requests. For example, you can fetch the JSON version of the most recent 30 public entries published to FriendFeed by fetching http://friendfeed.com/api/feed/public.

All of the API requests that output feeds are available in four formats: JSON, a simple form of XML, RSS 2.0, and Atom 1.0. JSON is the default output format. To request a different output format, simply add an format= argument to the URL:

The other API requests, like posting a new comment on an entry, only support the JSON and XML output formats since they do not output feed-oriented data.

Authentication

If you are publishing data to FriendFeed or if you are requesting the feed that includes data from a user with a private feed, your HTTP requests must be authenticated.

All FriendFeed users have a Remote Key to provide third party applications access to their FriendFeed. A FriendFeed Remote Key is just like a password, except that it is only used for third party applications, so it only provides access to the functionality defined by the API. Users can easily reset it if a third party application abuses the API.

All requests that require authentication use HTTP Basic Authentication. The username should be the user's nickname, and the password should be the user's Remote Key. You can direct user's to http://friendfeed.com/remotekey to get their remote key if they have not memorized it. See the FriendFeed API Application Guidelines for a complete set of recommendations of how to present authentication in your application.

The Python and PHP libraries available at http://code.google.com/p/friendfeed-api/ implement authentication for all methods that require it.

Note: We are currently exploring adding OAuth support as well. If you are interested in this support, let us know in the FriendFeed developer forum.

JSON Callbacks

The JSON output format supports an additional argument callback= that wraps the JSON output in a function call to a function of your choice. This functionality is available to enable you to use the API with JavaScript within a web browser. For example, http://friendfeed.com/api/feed/public?callback=foo outputs:

foo({"entries":[...]})

Using JSON and callbacks, you can place the FriendFeed API request inside a <script> tag, and operate on the results with a function elsewhere in the JavaScript code on the page.

All authentication is ignored if the callback= argument is given, so JSON callbacks only work with public feeds.

Reading FriendFeed Feeds

Overview

Feed Formats

The JSON form of the feeds has the following structure:

The simple XML format (output=xml) has the same structure as the JSON. The RSS and Atom formats use the standard RSS and Atom attributes for title, link, published, and updated, and include extension elements for all of the other meta-data.

Dates in JSON and dates in the FriendFeed extension elements in the Atom and RSS feeds are in RFC 3339 format in UTC. You can parse them with the strptime string "%Y-%m-%dT%H:%M:%SZ".

Filtering & Paging

All of the feed methods below support the following additional arguments:

Methods

/api/feed/public - Fetch all Public Entries

Returns the most recent public entries on FriendFeed:

http://friendfeed.com/api/feed/public

Using the FriendFeed Python library:

service = friendfeed.FriendFeed()
feed = service.fetch_public_feed()
for entry in feed["entries"]:
    print entry["title"]

/api/feed/user/NICKNAME - Fetch Entries from a User

Returns the most recent entries from the user with the given nickname:

http://friendfeed.com/api/feed/user/bret

If the user has a private feed, authentication is required.

Using the FriendFeed Python library:

service = friendfeed.FriendFeed()
feed = service.fetch_user_feed("bret")
for entry in feed["entries"]:
    print entry["title"]

/api/feed/user/NICKNAME/comments - Fetch Entries a User Has Commented On

Returns the most recent entries the user has commented on, ordered by the date of that user's comments:

http://friendfeed.com/api/feed/user/bret/comments

If the user has a private feed, authentication is required.

/api/feed/user/NICKNAME/likes - Fetch Entries a User Has "Liked"

Returns the most recent entries the user has "liked," ordered by the date of that user's "likes":

http://friendfeed.com/api/feed/user/bret/likes

If the user has a private feed, authentication is required.

/api/feed/user/NICKNAME/discussion - Fetch Entries a User Has Commented On or "Liked"

Returns the most recent entries the user has commented on or "liked":

http://friendfeed.com/api/feed/user/bret/discussion

If the user has a private feed, authentication is required.

/api/feed/user - Fetch Entries from Multiple Users

Returns the most recent entries from a list of users, specified by nickname:

http://friendfeed.com/api/feed/user?nickname=bret,paul,jim

If more than one nickname is specified, the feed most recent entries from all of the given users. If any one of the users has a private feed, authentication is required.

Using the FriendFeed Python library:

service = friendfeed.FriendFeed()
feed = service.fetch_multi_user_feed(["bret", "jim", "paul"])
for entry in feed["entries"]:
    print entry["title"]

/api/feed/home - Fetch the Friends Feed

Returns the entries the authenticated user would see on their FriendFeed homepage - all of their subscriptions and friend-of-a-friend entries:

http://friendfeed.com/api/feed/home

Authentication is always required.

Using the FriendFeed Python library:

service = friendfeed.FriendFeed(nickname, remote_key)
feed = service.fetch_home_feed()
for entry in feed["entries"]:
    print entry["title"]

/api/feed/search - Search

Executes a search over the entries in FriendFeed. If the request is authenticated, the default scope is over all of the entries in the authenticated user's Friends Feed. If the request is not authenticated, the default scope is over all public entries.

http://friendfeed.com/api/feed/search?q=friendfeed

The query syntax is the same syntax as http://friendfeed.com/search/advanced. The query operators are:

Using the FriendFeed Python library:

service = friendfeed.FriendFeed()
feed = service.search("who:bret friendfeed")
for entry in feed["entries"]:
    print entry["title"]

Publishing To FriendFeed

All of the calls to publish information to FriendFeed are HTTP requests. You can perform test calls from a web browser using the HTTP Basic Authentication built into your browser at http://friendfeed.com/static/html/apitest.html.

Requests to FriendFeed are rate limited, which, e.g., limits the number and size of thumbnails you can upload in a day. Normal uses should fall well within our rate limits. If you encounter HTTP 403 errors because of rate limits, and you think the limit is erroneous, please let us know in the developer forum.

Create New Entries

/api/share - Publish Links or Messages

A POST request to /api/share will publish a new entry on the authenticated user's feed. The arguments are:

Example usage with the FriendFeed Python library:

service = friendfeed.FriendFeed(nickname, remote_key)

# Publish a text message
service.publish_message("Testing the FriendFeed API")

# Publish a link
service.publish_link("Testing the FriendFeed API", "http://friendfeed.com/api/")

# Publish a link with thumbnail images
service.publish_link(
    title="Testing the FriendFeed API",
    link="http://friendfeed.com/api/",
    image_urls=[
        "http://friendfeed.com/static/images/jim-superman.jpg",
        "http://friendfeed.com/static/images/logo.png",
    ],
)

Example usage with curl:

curl -u "nickname:remotekey" -d "title=Testing+the+FriendFeed+API&link=http://friendfeed.com/" http://friendfeed.com/api/share

Upload Images with Entries

The /api/share method can also accept uploaded images encoded as multipart/form-data. This encoding is the standard used for file uploads within web browsers.

If any images are uploaded with the /api/share request, the original and the thumbnail are stored on FriendFeed's servers, and the thumbnail is displayed with the entry.

By default, the thumbnails will link to the destination link for the entry. If you want each uploaded image to link somewhere else, you can specify the link in the IMAGENAME_link argument. For example, if your uploaded image is POST argument file0, you can specify the link for that thumbnail as file0_link.

Comment and Like Entries

/api/comment - Add or Edit Comments

A POST request to /feed/comment will add a comment or edit an existing comment on a FriendFeed entry. The arguments are:

Example usage from the Python library:

service = friendfeed.FriendFeed(nickname, remote_key)
service.add_comment(
    entry="550e8400-e29b-41d4-a716-446655440000",
    body="Testing the FriendFeed API",
)

Example usage with curl:

curl -u "nickname:remotekey" -d "entry=550e8400-e29b-41d4-a716-446655440000&body=Testing+the+FriendFeed+API" http://friendfeed.com/api/comment

/api/comment/delete - Delete a Comment

A POST request to /feed/comment/delete will delete an existing comment. The arguments are:

/api/like - "Like" an Entry

A POST request to /feed/like will add a "Like" to a FriendFeed entry for the authenticated user.

Example usage from the Python library:

service = friendfeed.FriendFeed(nickname, remote_key)
service.add_like("550e8400-e29b-41d4-a716-446655440000")

Example usage with curl:

curl -u "nickname:remotekey" -d "entry=550e8400-e29b-41d4-a716-446655440000" http://friendfeed.com/api/like

/api/like/delete - Delete a "Like"

A POST request to /feed/like/delete will delete an existing "Like." The arguments are:

Get User Profile Information

/api/user/USERNAME/profile - Get services and subscriptions

Returns list of all of the user's subscriptions (people) and services connected to their account:

http://friendfeed.com/api/user/bret/profile

The returned JSON has the form:


Comment by engtechnology, Mar 27, 2008

I'm thinking of writing an app to search for all my Twitter friends on Friend Feed. I can see how I could go about finding them on the advanced search page.

But how do I add them as a friend without webscraping?

Comment by engtechnology, Mar 27, 2008

Also, it would be nice to get an API to get the list of the available Friend Feed services for building drop down boxes, etc. Especially if we don't need a remote key to get that information.

Comment by ben.binary.bloch, Mar 27, 2008

I would also like to be able to retrieve a list of services.

Comment by thelevybreaks, Apr 01, 2008

How about a way for users to sign up on Friend Feed through our site?

So we re-direct them, they sign up, and get sent back to our sites.

Comment by btaylor, Apr 03, 2008

thelevybreaks: we will add that feature. Thanks for bring it up.

Comment by alok.kumar, Apr 03, 2008

How about 1) An api that lets you add and remove friends? 2) An api that lets you add virtual friends? 3) letting virtual friends comment/like your posts?

Comment by atomoil, Apr 04, 2008

The XML output doesn't seem to totally line up with the documented structure above. iconUrl has been added to 'service' and the comments are in multiple 'comment' tags. Not sure re: likes and media as my stream doesn't have them in at the moment (presume it's multiple like and media tags).

Comment by JeffNClark, Apr 04, 2008

Hi. If I search on 'bell' with the api it seems to match on user names and link text as well as the title. This means I get everything posted by 'Clayton Bell' to friendfeed rather than things having to do with 'bell'. (Nothing personal Clayton) Is there a way to restrict the search to the actual content (title) rather than a whole bunch of fields ?

Comment by btaylor, Apr 05, 2008

JeffNClark: unfortunately, there is no way to restrict your search currently, but this is a common feature request, so we will likely add that capability in the future.

Comment by ourdoings, Apr 07, 2008

I'd like an optional argument to /api/share that would cause an error to be returned if the user's feed is public. This could be used for "unlisted" material.

Comment by patrick.hawks, Apr 12, 2008

How about a way to pull comments for a specific item to display along with my other blog comments.

Comment by bastien.chetelat, Apr 14, 2008

Hi!

I'm trying to delete a comment, but can't get it work... I have no UUID for comments in xml file!?

Here is a <comment> structure : <comment>

<date>2008-04-14T13:29:33Z</date> <body>testing comments</body> <user>
<profileUrl>http://friendfeed.com/bplatypus</profileUrl> <nickname>bplatypus</nickname> <id>1075d3b2-fe6c-11dc-aeb4-003048343a40</id> <name>Platypus</name>
</user>
</comment>

Thx for help!

Comment by gdalziel, Apr 14, 2008

Going along with bastien, could we have a method to pull back a single comment based on ID?

Comment by btaylor, Apr 15, 2008

Comment IDs have now been added! Thanks for letting us know about it.

Comment by engtechnology, Apr 16, 2008

I'd love to be able to get a structure of the user's hidden services and an API call to hide a service.

I'd also like to be able to query the FOAF structure: given a Twitter user, find their Friend Feed account name, given a Friend Feed account name, find their Twitter username, etc.

I'd absolutely LOVE a REST based way to create an imaginary friend in one click. Then you could create a Greasemonkey script for twitter.com that put an "Add this person to Friend Feed" link on user pages.

Comment by engtechnology, Apr 18, 2008

Given only the entry id (550e8400-e29b-41d4-a716-446655440000), we should be able to query the API to get the data structure for it.

Comment by a...@avivshaham.com, Apr 18, 2008

engtech: since you'll be using GM, you can already use the web interface to add/remove/list Imaginary Friends. See the friendfeedfun.rb file I posted to the FF dev forum for ideas, and I implemented the list functionality in the Filters script from a few days ago. (Aviv/FF)

Comment by macmegasite, Apr 27, 2008

The XML profile doesn't quite match the docs... instead of <subscriptions> .. </subscriptions> and <services> .. </services> with arrays of elements, it returns separate <subscription> and <service> elements.

Comment by JeffNClark, Apr 27, 2008

Simple search for everyone, both using web page and API, doesn't return any results fresher than around 6am April 25th.

Comment by ydfeed, May 05, 2008

Is there a way to request all entries for a specific URL?

Comment by btaylor, May 05, 2008

ydfeed: there is no way to request all entries for a specific URL currently.

Comment by brady.gaster, May 06 (6 days ago)

the csharp implementation of the Entry class currently does not appear to be populated. For example (and most annoying), the Service value doesn't indicate the service origin of each entry. Each Entry.Service.IconUrl? value is always null as well. Is there any plan to fix this? Thanks, love the service overall.

Comment by reynaldo77, May 07 (5 days ago)

Is there a function to quickly validate a user's login credentials (username and RemoteKey?)? Similar to twitter's "verify_credentials" and pownce's "verify callback".

It would just be really nice to confirm immediately for a user whether we're able to successfully use the account info they provide when enabling integration, rather than waiting until they first post and having them discover an "unauthorized" error then.

Comment by duprezolivier, May 08 (4 days ago)

Please, add Serialized PHP output :o|

Comment by pastith, May 09 (4 days ago)

I don't understand how paging is supposed to work. The document mentions that:

"start - return entries starting with the given index, e.g., start=30 "

What is that index? Is it the entry id? If so, why does start=foo-bar-UUID returns the entries up to the specified id and not the ones after that? Is there some other way I can obtain the list of updates after a specific entry that I have cached?

Comment by btaylor, May 09 (3 days ago)

patith: it is like the Google search result pages. start=30 means "start on the 30th most recent entry". You would page 30 at a time with start=0, start=30, start=60, etc.

Comment by duprezolivier, May 10 (3 days ago)

Some users have too many friends and we fetch their profiles data slowly :o(

I submit to remove subscriptions from /api/user/USERNAME/profile method and create dedicated method.

Comment by duprezolivier, May 10 (2 days ago)

Could you add blogs titles into /api/feed/home method results ? Thank :o)

Comment by roland.hesz, May 10 (2 days ago)

How could I get the line that says: "published photos on Flickr" and such? That tell me the exact action? Currently, all the activities (favouriting a photo on Flickr, posting a photo on Flickr, etc.) look the same from the API.

Is there any info about that, or it's not possible to get this at the moment?


Sign in to add a comment