Exchange Server 2016 REST Api

In this article I had already written that the new REST Api already works with local Exchange 2016 from CU3. The REST Api is a fairly new interface that was initially only available in Office 365 or Exchange Online. As of today (20.12.2016), I could not find any precise information as to whether this interface is supported for local installations. However, REST with exclusively local Exchange 2016 installations already works surprisingly well. Read more in this article.

Why REST rather than EWS?

There are now primarily two interfaces available for connecting tools and programs to Exchange Server:

Exchange Web Services (EWS) and REST Api

Both interfaces are provided via the IIS web server on the Exchange servers:

image

Both interfaces also use the HTTP (or HTTPS) protocol for communication. The two interfaces are therefore similar, but the REST Api has a decisive advantage:

The REST Api is complete Platform-independent. In contrast to EWS, no library needs to be installed for REST. To use EWS, the "Echange Web Services Managed API", the EWS Api requires .NET Framework and is only supported for Windows operating systems.

These dependencies do not exist with REST, as it uses simple HTTP requests that can be triggered by almost any device or program. The response to a request via REST Api is delivered in JSON format and is therefore easy to reuse. Access to Exchange data (mailboxes, calendars, tasks, etc.) is therefore possible via REST from almost any device, program or operating system. This is the big advantage over EWS.

Here you can find more information about REST and JSON:

 

Examples for accessing the REST Api

As already mentioned, accessing the REST Api is quite easy, so here are a few small examples:

PowerShell (Windows)

I have started my first attempts with PowerShell. The following one-liner is enough to retrieve the mails via REST Api:

$restdata = Invoke-RestMethod -Uri "https://mail.frankysweb.de/api/v2.0/me/messages" -Credential (Get-Credential)

REST Api

The variable $restdata now contains the data supplied by the Api.

The data in the $restdata object can now be easily accessed, here for example the recipients:

image

Or, for example, the time of receipt:

image

Curl (Linux)

Here is a small example using Curl on a Linux computer. In order for the authentication to work, I had to activate the "Standard authentication" on the "API" directory in the IIS:

image

I had to encode the user name and password as a Base64 string, which I could then use for authentication:

echo -n 'user@frankysweb.de:meinPassWort' | base64
curl -X GET -H "Authorization: Basic dXNlckBmcmFua3lzd2ViLmRlOm1laW5QYXNzV29ydA==" -H "Content-Type: application/json" https://mail.frankysweb.de/api/v2.0/me/messages

SNAGHTML88b7e0

SNAGHTML95e078

Of course, Curl initially only returns the "raw data" in JSON format. With the help of Python, the raw data can be formatted in a more readable way and saved as a file, for example:

curl -X GET -H "Authorization: Basic dXNlckBmcmFua3lzd2ViLmRlOm1laW5QYXNzV29ydA==" -H "Content-Type: application/json" https://mail.frankysweb.de/api/v2.0/me/messages | python3 -m json.tool >> /tmp/rest

SNAGHTML9eac1e

This makes it easier to understand the content:

image

How the REST Api works

The examples above are very simple, but the REST Api is much more powerful. For example, you can specify in the request which data you want to receive. This means you don't have to retrieve a lot of data in order to filter it again later.

For example, the following example only provides the sender and subject of sent mails:

$restdata = Invoke-RestMethod -Uri "https://mail.frankysweb.de/api/v2.0/me/MailFolders/sentitems/messages/?`$select=Sender,Subject" -Credential (get-credential)

image

The REST Api also allows data to be sent, for example an email:

$mail = '
{
"Message": {
"Subject": "Test via REST",
"Body": {
"ContentType": "Text",
"Content": "This is a test"
},
"ToRecipients": [
{
"EmailAddress": {
"Address": "frank@frankysweb.de"
}
}
]
},
"SaveToSentItems": "true"
}
'
invoke-RestMethod -Uri "https://mail.frankysweb.de/api/v2.0/me/sendmail" -Method Post -Body $mail -ContentType "application/json" -Credential (get-credential)

image

The same naturally also applies to other data types, such as calendar entries, tasks and contacts. To get an insight into the REST Api, simply take a look at the documentation.

Documentation for the REST Api

The documentation of the REST Api can be found here:

Some functions (e.g. Office 365 Groups / Office 365 Dataextensions) are only possible in conjunction with Office 365.

Customizations Sophos UTM Web Application Firewall for REST Api

In this article I described the configuration of the Sophos UTM Web Application Firewall (WAF) in conjunction with Exchange 2016. When the article was written, the REST Api did not yet exist in Exchange 2016 on-premises. Based on the article mentioned, only two small adjustments to the configuration are necessary for the REST Api to work with Sophos UTM Web Server Protection.

In the firewall profile, the following paths are added for the "Exchange Webservices" profile:

  • /api
  • /API

 

image

In addition, the following paths must be defined as exceptions for the "Webservices Hardening" rule:

  • /api/*
  • /API/*

image

No further adjustments are necessary.

Conclusion

The REST Api already works amazingly well. Unfortunately, I do not yet know why this interface has not yet been officially announced for local Exchange installations. There will probably still be changes to the interface, so it is better not to adapt any productive applications for the REST interface yet. However, it is very suitable for testing in the test environment.

10 thoughts on “Exchange Server 2016 REST Api”

  1. Hallo, Vielen Dank für diesen Artikel.

    Hast du/Ihr evtl. Erfahrungen wenn man Kalender abfragen macht und bei 98% funktioniert es und bei anderen erscheint eine nicht aussagekräftige Fehlermeldung.
    Abfrage: https://mail.domäne.com/api/v2.0/users/Hans.Muster@Domäne.com/calendarview?StartDateTime=2020-07-06T00:00:00&EndDateTime=2020-08-16T23:59:59&$top=1000&$select=Subject,Location,IsAllDay,Start,End,IsCancelled,Sensitivity

    Fehlermeldung:
    {„error“:{„code“:“ErrorItemNotFound“,“message“:“The specified object was not found in the store. REST APIs for this mailbox are currently in preview. You can find more information about the preview REST APIs at https://dev.outlook.com/.“}}

    Gruss und Danke

    Reply
  2. In Deinem Fazit, schreibst Du, dass Dir nicht bekannt ist wesshalb die Rest API in Exchange on Premis nicht bekannt gemacht worden ist. Das geht zwar aus dem Exchange Blog von Ross S. auch nicht hervor aber er schreibt, das es nur Hybriddeployments vorbehalten sein soll – in den Kommentaren schreibt er auch, das nicht geplant ist Onpremis-only Installationen zu unterstützen:

    https://blogs.technet.microsoft.com/exchange/2016/09/26/on-premises-architectural-requirements-for-the-rest-api/

    Reply
  3. Hallo vielen Dank für den „fast“ einzigen Artikel zu dieser Thematik.
    Ich entwickle gerade eine APP auf einen Raspberry Pi die Kalendereinträge des lokalen Exchange servers auslesen soll.
    Könntest du evtl. ein Beispiel mit dem Zugriffsverfahren mit Python zeigen? Damit wäre glaube ich vielen geholfen.

    Danke

    Reply
  4. Hallo Frank,
    vielen Dank für den wie gewohnt hervorragenden Artikel. Beim Herumprobieren ist mir folgendes aufgefallen: die meisten meiner Postfächer haben einen Kalenderordner mit dem Namen „:\Kalender“, bei ein paar Postfächern heißt er aber – scheinbar völlig wahllos – plötzlich „:\calendar“. Ich habe dazu nirgends eine Dokumentation finden können, hast Du eine Erklärung, was es damit auf sich haben könnte?
    Viele Grüße,
    Michael

    Reply
  5. Hi Markus,

    vielen Dank für den Hinweis mit dem Decodieren. Da stand ich völlig auf dem Schlauch bzw. fühlte mich gezwungen das komplett über die REST-API zu lösen.

    Hier meine Lösung (ohne PHP) nachdem man sich die Message-ID geholt hat:
    […]
    $urlattachment = „https://$exchangeserver/api/v2.0/me/messages/$messageid/attachments“
    $attachment = invoke-webrequest $urlattachment -credential $creds
    $attachmentanswer = $attachment.content | ConvertFrom-Json
    $attachmentbase64 = $attachmentanswer.value | select -ExpandProperty contentbytes

    $filename = $attachmentanswer.value.Name
    $path = „C:\….“
    $outfile = „$path“+$filename

    $bytes = [Convert]::FromBase64String($attachmentbase64)
    [IO.File]::WriteAllBytes($outfile, $bytes)

    Viele Grüße,
    Norbert

    Reply
  6. Hallo Norbert,
    das Attachment steht in ContentBytes des Reponse als Base64 String codiert. Diesen musst du decodiert in eine Datei schreiben mit korrektem ContentType (ebenfalls im Response zu finden). Ein PS-Script dafür habe ich nicht, aber ich habe es mit PHP gelöst.
    Gruß,
    Markus

    Reply
  7. Hi Frank,
    danke für den tollen Artikel :-)
    Wenn du einen POST-Request ohne Daten sendest, bekommst du einen kleinen Hinweis, dass die REST API noch Beta-Charakter hat:

    REST APIs for this mailbox are currently in preview. You can find more information about the preview REST APIs at https://dev.outlook.com/.

    Gruß,
    Markus

    Reply
  8. Hi,

    hast du schon getestet ob du ein Attachment herunterladen kannst? Ich bekomme das aktuell nicht hin bzw. finde auch keine Doku dazu. Die Attachment-ID kann man sich noch bequem anzeigen lassen; der Download ist mir noch nicht klar.

    Ich habe das hier gefunden, was sich aber auf Version 1.0 der API zu beziehen scheint und in Version 2.0, zumindest in meinen Tests noch nicht funktioniert:
    http://stackoverflow.com/questions/32749496/how-to-retrieve-itemattachment-contents-from-office-365-rest-api

    Grüße,
    Norbert

    Reply

Leave a Comment