Designing APIs for Humans
Earlier this month I gave a talk at Devs Love Bacon on an API design philosophy I picked up while working at IFTTT I’ve been calling ‘APIs for Humans’. Sadly, it’s not about this:
OH at @devslovebacon “I thought the “APIs for humans” talk was about controlling humans” #devslovebacon
— Julian Cheal (@juliancheal) April 12, 2013
At IFTTT I identified three major areas for how non-developers end up consuming API data in significant numbers. In this talk I cover what those areas are and how you can tailor your API designs to encourage developers to build human-friendly integrations.
Since I had extra time I threw in a few points on developer experience too. After all, developers are humans too.
» Authentication: Don’t be Clever
My contribution to the new API UX blog:
By using standardized, common authentication schemes you can reduce the cognitive overhead for the developer consuming your API and avoid getting into unfamiliar, untested security situations. Authentication is the first thing any developer using your API will have to deal with and it’s those first few moments that are crucial to their success using your API to solve their problem. Take care to make the first impression a good one.
The Good and the Bad of OAuth 2.0 Authorization Implementations
While testing out a new tool I’m working on that uses a variety of OAuth2 providers and thought I’d catalog some of the quirks I came across. This is just for the authorization flow, not for actually making requests once you’ve secured a token.
Now that the OAuth2 spec is solidified we should start seeing less and less of these issues.
Good: The APIs Console is one of the best out there. My favorite feature: allowing you to specify multiple callback URLs for a single app. This makes testing different environments way easier because you don’t need to go back and constantly edit the callback URL value.
Good: The OAuth 2.0 Playground is fantastic. It will show you all the HTTP requests that are made for a standard auth flow. This makes it really easy to debug issues on your end by comparing the requests. I used it to diagnose the following problem.
Bad: When requesting an Access Token the request will fail if you include any parameters that it is not expecting. Google does not require a state or type parameter when getting the token like some other APIs do and will give you a 400 Bad Request with an invalid_request error if they are included.
Bad: The scopes options are not immediately obvious. There’s a huge list of services and you must enable them individually (good) in the ‘Services’ section of your project in the APIs Console. This page though does not list the scopes value to use. The Playground does have what appears to be a complete list.
Bad: If you just want to use OAuth with the Graph API, you still need to enable “Website with Facebook Login” in order to set the Site URL. This is hidden by default and took me a little bit to find it. This setting restricts which domains they will redirect back to.
Good: The Site URL only requires a domain instead of a full URL which means you can change your callback URL path without breaking your app.
37signals
Bad: When you create the app you select which services you want your app to have access to but during the auth flow only one of the services is displayed.
Bad: There’s no support for limiting access to read-only via scopes. The only option is full read/write for all of the apps selected.
Stripe
Bad: Stripe does not use a client_secret. Most client libraries and OAuth examples use it so it may be confusing for experienced developers wondering where that value is.
Bad: This is not technically wrong, but it isn’t common. When exchanging the code for an access token you are required to send an Authorization header with a value of Bearer and your Stripe account secret key (either test or live). I’d rather they just tell you to use the secret key as the client_secret and not require the additional header.
Bad: The docs say that the scope parameter is optional but will give you an error (400 OAuthException - Invalid scope field(s)) if it isn’t specified. You should specify at least ‘basic’.
Box
Bad: The redirect URL settings requires HTTPS which can be difficult if you’re trying to test locally (for instance my test app runs on http://localhost:5001 which is accepted every where else). Box has informed me this will be resolved soon.
Bad: Does not use scopes for read-only or read/write access (is configured with the application). Box has also told me they will be changing this once they have more than one scope.
Microsoft Live Connect
Good: Permissions are set via an extensive and clear list of scopes. Very nice.
Stack Exchange
Good: Callback URL validation is set via domain only (similar to Facebook).
GitHub
Bad: Scopes must be specified comma-separated, contrary to the OAuth2 spec. This is on the roadmap to be fixed.
App.net
Good: The application manager allows you to generate a token for yourself with custom scopes without having to go through the flow. This is extremely helpful during development.
Others
Here are some others that I tried that I didn’t have any notable issues with: MailChimp, Foursquare, Wordpress.
Here are the services I desperately wish would move from OAuth 1.0a to OAuth 2.0: Twitter, Dropbox, LinkedIn
If you’ve come across a unique implementation quirk of your own, post it below in the comments.
Related Posts
Age
This post is a little more personal and not at all technical. I realized I’ve been wanting to write about this for awhile.
On the latest episode of Hanselminutes two of my favorite internet friends had a discussion on age as they are nearing their 40th and 45th birthdays. I happened to come up a couple times as a reference point for The Young’uns.
Age has always been a sensitive issue for me. When I was 5 my mom homeschooled me and when she couldn’t do it anymore and it was time to go to public school I was effectively done with first grade so she bumped me ahead to second grade. The rest of my primary and secondary school years I trailed all my classmates in age by a year. I got my license my junior year, graduated at 17, etc. I played sports on teams consisting of all older players. I was always very determined to prove that my age didn’t matter.
When I started running companies when I was 15 my age was an advantage. It got me attention and customers. When I started working real jobs at 19 it was also an advantage because people couldn’t believe how mature and experienced I was “for his age.” At about 25 when all my peers had experience too (with degrees to boot) it wasn’t as advantageous.

Now I’m 31. In the SF tech scene I frequently feel old. My experience frequently gets deferred to (which often makes me slightly uncomfortable). Some of the younger engineers I’ve worked with lately have made me feel really old. They’re insanely smart but make me realize how much experience I actually have now (going on 16 years of doing computer stuff for money). 30 under 30 lists drive me crazy not because that’s my goal in life, but just because it’s impossible nonetheless. My wife consoles me by saying there’s plenty of time for 81 under 81.
Back to the Hanselminutes episode. Rob talks about a recent dinner we had together where he was giving me some advice (that I appreciated) and my reaction. I (not surprisingly) reacted by giving him a look that said I have it all under control. Almost certainly I was overcompensating for my age insecurities. I rarely feel like I do have everything under control and I crave insight from people more experienced than me.
At the same time, I do know some things now. More importantly I know what I don’t know. All of that experience has lead me to a position where I can be a founder of a startup. I’m not doing this because I’m young and impetuous and want to ride the wave of the current ‘bubble.’ I’m doing this because I know what it will take for me to be happy in my work and I’m not going to spend any more time not pursuing it. I’ve known that for a long time, but I’m at a point where my age is an asset in making this happen. So I’m going to.
Runscope
I’m very excited to announce that I have co-founded a company. If you use APIs in your mobile or web applications request an invite to our early preview. We’re still very early in this and will be talking about more details as we progress.
The plan when I moved out to San Francisco was always to eventually start something of my own. I learned a ton working at Twilio and IFTTT and now hope to apply that knowledge to build a great company. Now’s the time. We’ve got a great team and a giant problem to solve and I can’t wait to show it to all of you.
Follow Runscope on Twitter to track our progress.
» 2012 API Community Survey
I (via API Jobs) teamed up with Programmable Web, Mashery, 3scale and Layer7 to survey the API community landscape. One lucky participant will win an 11” MacBook Air or Surface Pro. If you’ve built or used an API in the last year, please take a few minutes to take the survey.
Box API v2: Less is More
Box has updated their API to version 2 and has simplified it along the way. The highlights:
- Consistent request/response models
- Convention-based attribute names (please do this in your APIs)
- No more XML, huzzah!
- Better events streams (I hope that Webhooks follows)
- Settled on OAuth2 standard
My favorite line:
There’s an inherent impedance mismatch between XML and regular humans.
These are all very developer-friendly changes. If you’re designing an API, there’s a lot to learn from Box’s experience.
» Traffic and Weather: My new Cloud/API Podcast
Steve Marx and I had such a great time with the conversation I posted here that we decided to do it every week. Check out Traffic and Weather, a (mostly) weekly news and commentary podcast about all things cloud and API. We’ve already done two episodes and I’m really happy with how they’ve turned out.
Subscribe to the RSS feed or subscribe in iTunes.
Lastly, thanks to my friends at SendGrid for sponsoring our first few episodes.
Craving Conversation

Twitter is my water cooler. I blow off steam, talk about what I’m working on, learn new things from others, etc. For the first few years I spent using the service it seemed like every night there was an awesome conversation going on. Lately it seems like people have been conversing less and retweeting more. I don’t know if it’s because I’ve shifted away from following people in a specific tech community (the .NET crew seems to have focused their conversing there more than the others I’ve observed) or just a general behavioral shift in how people use Twitter (or both) but lately I’ve been missing those great conversations.
Other social networks never really filled the gap. Google+ was OK, but activity tapered off pretty quickly after it launched. App.net is still promising, but nascent and hasn’t grabbed me yet. I almost started a site just to share links and discuss APIs just to have it. I’m not famous enough to bootstrap a discussion community though (learned that lesson once before).
Then Google+ Communities were launched a few days ago. You can create them by topic. They’re moderated. The posts work like any other G+ post so links, etc. are first-class and each item has comments. To me, this is the perfect application of the G+ stream structures and having them scoped by topic solves the problem of having to follow someone who may post a lot about stuff you’re not interested in.
Ultimately, it’s another message medium like many before. The quality will be determined by the people that contribute to the community. But it’s looking promising. You can find me chatting about APIs over there.
