Zapier’s Office 365 API Journey

Since we first heard about the new Office 365 product suite, we at Zapier have been eager to dig into the APIs that would accompany it. So earlier this year, when the Office 365 APIs preview launched at http://dev.office.com/, we jumped at it!

For those of you who aren’t familiar with the Office 365 APIs, the preview has these goodies:

A REST API for Office 365 for Business (Home & Outlook.com currently excluded)

Previously, much of the Microsoft development ecosystem focused on .NET code. While .NET SDKs still have superb support, this marks an exciting time where language-agnostic REST APIs are first class citizens. For example, Zapier is mostly written in Python and we found it a breeze to connect to the new REST/OAuth/OData Office 365 APIs. Here’s how we did it.

After you get all settled and are able to log on to https://outlook.office365.com/, you’re ready to explore the API. Currently, Basic Authentication is enabled (for testing purposes only) in addition to OAuth2. That means there is a really simple way to explore the API directly from your browser. Just visit https://outlook.office365.com/api/v1.0/Me and enter in your normal Office 365 login credentials; you should see some JSON containing a bunch of handy links.

Let’s tour a few of those more interesting links!

A quick tour

Explore the following links to get a list of calendars and events, contacts, and email messages:

I highly recommend keeping your browser session up and running, or using a tool like http://www.hurl.it/ to experiment with requests as you go.

It is also wise to read up on the MSDN REST API docs for more information about how to use the REST API. Additionally, read the OData URI conventions doc for more information about how to use OData query strings for filtering and performance tweaks.

Some real code

Ripped straight out of Zapier, here is some real production code that shows how to use some of the useful resource URLs listed above with Basic Auth (we’ll talk about OAuth in a moment!). Remember, these are the same calls you were making in your browser, just scripted!

If you are creating a prototype script, you can use Basic Auth to quickly try out the APIs, because it is really simple and easy. However, if you are performing these calls in production, or on behalf of others, don’t collect their passwords, just use OAuth (which is much more pleasant for everyone). Let’s cover that now.

After you have an Azure account created and connected to your Office 365 app, you’ll need to create a new Active Directory application. You might need to create a new directory under your Active Directory tab, but right alongside your Active Directory users, groups, domains, and so on you should see applications. You want to create one of those.

As you create and edit your app, you’ll be able to set up your logo, secret keys, redirect/reply URI, and all the other good bits you are familiar with around OAuth. The only difference is that you’ll need to select your scopes at application creation time, not in the redirect URI like most apps. You can do that in the “permissions to other applications” section:

Then you’ll want to set these values in the code powering your OAuth app:

It is worth reiterating that you don’t need to provide scopes, as those are encoded in the “permissions to other applications” section.

After you finish the flow, just use the access_token and refresh_token in the same way that most OAuth services do. You can learn more about OAuth 2.0 in Azure AD, which should cover much of the basics outlined above.

Putting it into production

Thanks to the adoption of standard web API patterns like OAuth and REST, our company Zapier was able launch its very own Office 365 Integration in just a few days using the same developer platform optimized for the most common web API patterns.

A quick checklist to run down before you go into production:

Make sure your refresh tokens swap for a new access token properly.

Use filter query strings like $filter=Price+lt+20 to reduce the number of records you request instead of requesting all records and doing it in memory.

Along with $top=100, consider using something like $orderby=DateTimeReceived+desc to get new records.

Use $select=DisplayName,EmailAddress1 to reduce the amount of data to only the bits you need. This is especially useful for email messages (which can be very large).

If you follow these tips, you can be sure that your API calls are quick, efficient and robust. Don’t forget to keep your eyes on the Office 365 documentation as they are often updated with new endpoints and features. Likewise, the Office 365 Dev Blog is indispensable!

This post brought to you by Bryan Helmig. Bryan is a co-founder and engineer at Zapier. In addition to being a blues/jazz guitarist and whiskey connoisseur, he’s hacked on just about every API available today and has helped design and build the Zapier platform which makes 10s of millions of API calls a day.

Using $filter=Importance eq Microsoft.Exchange.Services.OData.Model.Importance'Low' gives me no responses back when there should be items returned. This seems to be happening for me when trying to filter using the Microsoft.Exchange.Services.OData.Model namespace. Have you come across this?

Importance property actually works (my mistake), but not MeetingMessageType. I am specifically trying to filter MeetingMessageType to retrieve SeriesMaster types to reconstruct recurring meeting. The query gets a 200 response, but no values returned.

Roland: You can filter events but currently there is no DateTimeCreated property on the Event entity. That has been added in an update that is working it's way out to the service. Once that's available I expect you to be able to filter on DateTimeCreated.