The Ultimate Guide to Decoding the Flickr API

Flickr, being the biggest photo management and sharing site in the world, has an impressive API to let developers access and manipulate almost all of its data. Lets take a look at how to work with the API: at the lowest level possible.

Advertisement Advertisement Advertisement Advertisement Advertisement Jul 28, 2009 • 17 min read

Flickr, being the biggest photo management and sharing site in the world, has an impressive API to let developers access and manipulate almost all of its data. Lets take a look at how to work with the API: at the lowest level possible.

A Word From the Author

In this Web 2.0 era, web applications which have an easy to use, intuitive API have a distinct advantage as it lets developers exploit and build for the platform and thus capture more users. As we move towards the social web and mashups, a good API is not a nice addition anymore: it is downright necessary. And remember too much abstraction is never a good thing. While there are a number of API kits out there to simplify working with the API in question, wouldn't it be cool to know what is actually going on under the hood? Wouldn't it be exciting to deconstruct the actual voodoo going on between the kit and the API? Yeah, I thought so! In this new series, we'll be taking a look at the APIs of some of the most popular services out there. Today, we take a look at the Flickr API.

The Sequence of Events

The tango between the developer and API begins and culminates in a series of well defined steps. I'll explain each step as we go.

Deciding the Type of Application

First of all, we need to decide on the type of application we are going to build. Desktop applications have to use the desktop model while a web application can use either of the models. The mobile model is beyond the scope of this article.

For this article I've chosen to go with the desktop model since the web model requires all the testing to be done on the domain on which the app is to be deployed. This might not necessarily be feasible for a lot of people. We choose the desktop model since it is devoid of this restriction.

Obtaining an API Key

The next step is obtaining an application key. Flickr uses this app key to keep tabs on our usage and other statistics. Head on over here and apply for your own API key.

Since our usage of this particular API key is purely educational we choose to obtain a non-commercial key.

Fill in all the details the form requires with special attention to the description of the project. The devs at Flickr actually read this description if your app misbehaves in some way to make sure it is legit. So spend that extra minute describing your masterpiece.

A successful registration yields you this page. Do note down the api key and the shared secret for later use.

Flickr API Basics

The Flickr API provides a number of methods which may or may not require authentication. Each method takes a number of arguments which modify its behavior and payload. Responses can be received in a number of formats including JSON, XML, SOAP and REST. All these requests can be made to end points corresponding the format you've chosen to make the request in. For example, we'll be using REST for the rest of this article and so our URL end point would be http://api.flickr.com/services/rest/.

Pulling in Public Data

There are a number of methods which pull in public data and thus require no authentication of any sort. We just need the api key we had obtained earlier along with any required arguments of the method in question. Lets take a look at an example.

The getPublicGroups method is an example of a method which doesn't require authentication and which pulls in public data. We pass in the user id of the user and our api key and the API responds in the format you requested with a list of groups the user is part of.

We'd send in a request to this URL.

http://api.flickr.com/services/rest/?method=flickr.people.getPublicPhotos&api_key=your_api_key&user_id=user_id_x 

Replace your_api_key with the key we obtained earlier and user_id_x with a valid NSID. Since I like my responses to be in JSON, I can add another parameter asking the API to respond with a JSON payload.

http://api.flickr.com/services/rest/?method=flickr.people.getPublicPhotos&api_key=your_api_key&user_id=user_id_x&format=json 

The API will send a response like so:

jsonFlickrApi(
"photo":[
"farm":4, "title":"opac", "ispublic":1, "isfriend":0, "isfamily":0>,
"server":"2531", "farm":3, "title":"scale", "ispublic":1, "isfriend":0, "isfamily":0>,]>,
"stat":"ok">)

Properly formatted, it is going to look like this.

jsonFlickrApi( 
"photos":  
"page": 1, 
"pages": 1, 
"perpage": 100, 
"total": "2", 
"photo": [ 
"id": "3729689790", 
"owner": "40318902@N02", 
"secret": "ea9c38a675", 
"server": "3466", 
"farm": 4, 
"title": "opac", 
"ispublic": 1, 
"isfriend": 0, 
"isfamily": 0 
"id": "3729689845", 
"owner": "40318902@N02", 
"secret": "df6dfee053", 
"server": "2531", 
"farm": 3, 
"title": "scale", 
"ispublic": 1, 
"isfriend": 0, 
"isfamily": 0 
"stat": "ok" 

Pulling in Private Data

This is probably the reason you want to learn how to work with the Flickr API and so we'll go over each step slowly since this part has a tendency to confuse people.

Signing

To obtain private data, each method needs authentication and for authentication to work each of our calls has to be signed. Signing works like so:

Make an alphabetically sorted list of the arguments

For example, in the previous example our list would look like so:

Create the signature string

The signature string is created by taking the API secret we obtained earlier and then appending the list of arguments to it. For example, our signature string would look like so:

0123456789api_keyxxxformatjsonuseridyyy 

Signing our call

The final step is the actual signing. Flickr expects us to take the MD5 hash of our signature string and append it to our original method call as a named parameter.

So any authenticated call has this general format

http://api.flickr.com/services/rest/?method=ourmethod&api_key=apikey&api_sig=hashedvalue 

Obtaining a frob

Now with the signing out of the way, we can now move on to the actual authentication. Flickr uses a system similar to OAuth for authorization which means that a user who wants to use our app doesn't need to divulge his/her user credentials. Users are transported to the Flickr web site where the user is asked whether he/she wants to allow our app to access the user's data.

This is where a frob comes in. To create the login link which takes the user to an authorization page on Flickr, we need a way to identify a specific login session.

In order to obtain a frob to identify the session, we need to call the flickr.auth.getFrob passing our api key as a named argument. Our URL would look like so:

http://api.flickr.com/services/rest/?method=flickr.auth.getFrob&api_key=apikey&api_sig=hashedvalue 

A JSON response looks like so:

frobcallback( 
"frob": 
"_content": "xxx" 
"stat":"ok" 

Constructing the login URL

Having successfully obtained a frob, we can now work on building the URL which lets the user authorize our application. The login URL has this general format:

http://flickr.com/services/auth/?api_key=apikey&api_sig=apisig&perms=perms&frob=frob 

Replace api_key's value with the one we had obtained earlier, api_sig's value with a MD5 hash of our signature string and frob's value with the frob value returned by the API. The perms parameter defines the desired level of account access and has valid values of read, write and delete. Each access includes the rights of all its predecessors.

A valid login URL takes this form:

http://flickr.com/services/auth/?api_key=63b08e2efcc22de9900163f4d761fdbc&api_sig=663369798c695dbe2fd7e2af7576dd2b&perms=delete&frob=72157621742082858-8e995a1104e28114-870912 

The authorization pages looks like so:


First, Flickr makes sure the user wasn't conned into authorizing the application.


Next, it is made sure the user knows the level of authorization the he/she is granting to the application.


Successful authorization!

Obtaining the auth token

Once the user has given authorization for our application, we can proceed forward. The final step in this process is obtaining an auth_token. An auth token ties a specific API key to a specific user ID i.e an auth token can be used to manipulate only a specific user's data whilst using a specific API key. An auth token is necessary for each and every API method call which requires authentication.

Obtaining an auth token is as simple as calling the flickr.auth.getToken method passing in the api key, frob and api signature as named parameters. The URL would look like so:

http://flickr.com/services/auth/?api_key=apikey&api_sig=apisig&frob=frob 

A successful request nets us an auth token which can be used indefinitely to access a specific user's data using a specific api key.

Making the call

Now, that all the prerequisites have been met, we can go about retrieving data as needed. Remember, each of your authenticated calls needs to be signed and so each call must send in the api_key, auth_token and api_sig for the method call to work.

At the base minimum, the URL for your REST request must look like this. Other method specific parameters or parameters which modify the payload can be appended as needed.

http://flickr.com/services/auth/?api_key=xxx&api_sig=yyy&auth_token=zzz&method=method_name 

While signing, make sure to also include the other arguments and their values. This is a frequent cause of error and headache and is easily rectified. Are you including a callback parameters in the URL to avoid the cross domain restriction in browsers whilst using AJAX? Those have to go in the signature string too!

Reconstructing the URLs

Let's take a look at an example response for a method which returns public photos.

jsonFlickrApi(