Microsoft Graph WebHooks Update - January 2016

Hi, Gareth Jones here.  I recently joined the Microsoft Graph team from our friends over in OneNote. I'm beyond excited at the wonderful enthusiasm you've shown for the Microsoft Graph since we launched at Connect(); back in 2015 (wow, that sounds so retro now).


One area we didn't talk about too much at launch time was our preview of WebHooks for the API, so we wanted to dive in and explain a little more what you can do with the preview and talk about an upcoming breaking change to validate endpoints. If you're already using webhooks, skip ahead to the what's changing section at the end.


What's a webhook?

Webhooks are callbacks for the web. They let you create web apps that respond efficiently to change in your user's data. For example, if you want to keep up with changes to all the email messages in a user's Vacation folder, perhaps to extract hotel or flight information, you can create a webhook subscription and get notified whenever there's something new to process. This saves your app from having to regularly poll for changes.


So how do I get started?


If you're already coding with the Microsoft Graph API, you'll have an app registered, so you can authenticate and get an OAUTH token. If not, there's a walkthrough here.


Currently we support webhooks on mail, calendars and contacts, so you'll need to make sure you have requested one of the matching scopes: Mail.Read, Calendars.Read, or Contacts.Read.


Then you'll POST a request to the /subscriptions endpoint like so



POST https://graph.microsoft.com/beta/subscriptions
Content-type: application/json
Authorization: Bearer <YourOAuthToken>
{
  "changeType": "Created",
  "notificationUrl": "https://<YourAppURLHere>/api/webhookCallback",
  "resource": "me/messages"
}

This request asks for all changes to the user's mail to be sent to the '/api/webhookCallback' path on your app. Note that the URL for your app MUST be https. You can also ask for 'me/contacts" or "me/events" or a specific folder, such as 'me/folders('vacation')/messages'.

If all goes well, you'll get a 201 Created response with the details of the subscription including an expiration time. You'll need to replace your subscription after the expiration time with a new one. In future we'll allow renewing an existing subscription. Here's an example response:



HTTP/1.1 201 Created
{
  "@odata.context":"https://graph.microsoft.com/beta/$metadata#subscriptions/$entity",
  "subscriptionId":"7f105c7d-2dc5-4530-97cd-4e7af6534c07",
  "resource":"me/messages",
  "changeType":"Created",
  "notificationUrl":"https://<YourAppURLHere>/api/webhookCallback",
  "subscriptionExpirationDateTime":"2015-11-20T18:23:45.9356913Z"
}


What do I get?

As change to the user's email happens, your webhook callback will then start receiving notification packets. We'll send them batched up for efficiency, so you'll typically see an array:



POST https://<YourAppURLHere>/api/webhookCallback
Content-type: application/json
{
  "value":[
    {
      "subscriptionId":"7f105c7d-2dc5-4530-97cd-4e7af6534c07",
      "subscriptionExpirationDateTime":"2015-11-20T18:23:45.9356913Z",
      "changeType":"Created",
      "resource":"Users/ddfcd489-628b-7d04-b48b-20075df800e5@1717622f-1d94-c0d4-9d74-f907ad6677b4/messages/AAMkADMxZmEzMDM1LTFjODQtNGVkMC04YzY3LTBjZTRlNDFjNGE4MwBGAAAAAAAr-q_ZG7oXSaqxum7oZW5RBwCoeN6SYXGLRrvRm_CYrrfQAAAAAAEMAACoeN6SYXGLRrvRm_CYrrfQAACvtMe6AAA=",
      "resourceData":{
        "@odata.type":"#Microsoft.Graph.Message",
        "@odata.id":"Users/ddfcd489-628b-7d04-b48b-20075df800e5@1717622f-1d94-c0d4-9d74-f907ad6677b4/messages/AAMkADMxZmEzMDM1LTFjODQtNGVkMC04YzY3LTBjZTRlNDFjNGE4MwBGAAAAAAAr-q_ZG7oXSaqxum7oZW5RBwCoeN6SYXGLRrvRm_CYrrfQAAAAAAEMAACoeN6SYXGLRrvRm_CYrrfQAACvtMe6AAA=",
        "@odata.etag":"W/\"CQAAABYAAACoeN6SYXGLRrvRm+CYrrfQAACvvGdb\"",
        "Id":"AAMkADMxZmEzMDM1LTFjODQtNGVkMC04YzY3LTBjZTRlNDFjNGE4MwBGAAAAAAAr-q_ZG7oXSaqxum7oZW5RBwCoeN6SYXGLRrvRm_CYrrfQAAAAAAEMAACoeN6SYXGLRrvRm_CYrrfQAACvtMe6AAA="
      }
    }
  ]
}


That's all there is to it! From there you can go and retrieve more details about the changed messages.


As a note, webhooks currently only work with app+user tokens, as all subscriptions are for changes in data belonging to a specific user. You can find more details about Microsoft Graph webhooks here.


What's changing

As a preview, we're always taking feedback and making minor adjustments to our APIs as we get them ready for production primetime in future. In the coming week, we'll be tightening up our anti-spam protection a little with an extra validation check required before notifications start flowing.


As part of the act of subscribing, we'll send a POST request to validate that there's a real live callback URL waiting to receive the notifications.



POST https://<YourAppURLHere>/api/webhookCallback?validationtoken=<token>

We expect the <token> value to be echoed back in the response as plain/text within 10 seconds.


As ever, please let us know how you like Microsoft Graph and webhooks in particular.