Exchange Client Developer
Exchange Client Developer
Find in-depth developer documentation for Exchange Server, including Exchange Online
as part of Office 365 and Exchange Server on-premises versions.
You can use the how to, get started, new feature, and API reference documentation to
develop tools to access and manage mailbox data from services, websites, desktop
computers, and mobile devices, and to create custom solutions for email, calendar,
contacts, and other items that are stored in Exchange Online or on an Exchange 2010,
2013, 2016, and 2019 server.
You can use Graph API, REST API, Exchange Web Services (EWS), Autodiscover, Outlook
add-ins, or other APIs to develop your applications. This page helps you choose the
right Exchange technology.
7 Note
We’re removing the ability to use Basic authentication in Exchange Online for EWS
beginning October 2022. For more information, see Deprecation of Basic
authentication in Exchange Online. You should use OAuth authentication instead.
Authenticate an EWS application by using OAuth and Authenticate an IMAP, POP
or SMTP connection using OAuth.
) Important
Microsoft Graph is the recommended API to use for accessing Exchange Online
data. New applications designed to access Exchange Online data should use
Microsoft Graph.
A REST-based app to access Exchange Online as part of Office Microsoft Graph REST APIs for
365 mail, calendars, and contacts
A mailbox client that is not based on the .NET Framework or Explore the EWS Managed API,
Java EWS, and web services in
Exchange
A mailbox client that uses the .NET Framework to access EWS Get started with EWS Managed
API client applications
A mailbox client that uses Java to access EWS EWS Java API on GitHub
An application that customizes the Outlook user interface or Outlook VBA reference
relies on Outlook business logic
A custom management tool that uses Windows PowerShell Exchange Management Shell
from managed code
A solution to back up or restore Exchange data Backup and restore for Exchange
Message Exchange serves as a standard mail server for applications that send messages.
transport Exchange includes several APIs that transfer messages, including REST, EWS,
and the EWS Managed API.
Mailbox Exchange provides a hierarchical structure of folders, items, and properties for
storage applications that access data stored in mailboxes.
You can perform queries on the data, and Exchange manages access to the
stored data based on user and store permissions.
Applications that handle mailbox data typically use REST, EWS, or the EWS
Managed API.
server Applications can configure, control, and monitor current activity and the health
of Exchange servers across the organization.
See also
Server API reference for Exchange
Read about Exchange on Office Blogs
Get 101 code samples for Exchange 2013
Get the EWS Managed API (GitHub)
Get support for Exchange Server
Migrating to Exchange technologies
Article • 03/29/2023 • 4 minutes to read
If you're migrating from an earlier version of Exchange, use the information in this article
to find out which development technologies are supported in current product versions,
and which technology to migrate to.
Exchange Web X X X X X X
Services (EWS)
Outlook Object X X X X X X
Model (OOM)
Exchange X X X X X X
Management Shell
Transport agents
X X X X X
Technology Office 365 Exchange Exchange Exchange Exchange Exchange
and 2019 2016 2013 2010 2007
Exchange
Online
Active Directory X
Services Interface
(ADSI)
Collaborative Data X
Objects for
Exchange (CDOEX)
Collaborative Data X
Objects for
Windows 2000
(CDOSYS)
Exchange OLE DB X
Provider
(EXOLEDB)
Exchange Store X
Event Sinks
Incremental X
Change
Synchronization
(ICS)
Lightweight X
Directory Access
Protocol (LDAP)
Messaging API X X X X X X
(MAPI)
Web Distributed X
Authoring and
Versioning
(WebDAV)
¹REST API and Graph API require the Cumulative Update 3 for Exchange 2016.
²Only hybrid customers are able to take advantage of the REST APIs for both Office 365
and on-premises mailboxes.
Choose a development technology to migrate
to
If the technology your application uses is not supported or deemphasized in Exchange
Online or Exchange 2013, use the following table to decide which technology to migrate
to.
CDOEX No EWS The EWS Managed API and EWS can access the
Managed API same Exchange store that CDOEX provides.
or EWS
Unlike client applications built by using CDOEX,
you can run EWS applications on a local or
remote computer.
CDOEXM No
Exchange Exchange Management Shell commands control
Management Exchange servers, storage groups, databases,
Shell
and users more simply than the corresponding
CDOEXM APIs. Plus, you can easily migrate your
CDOEXM applications to Exchange
Management Shell commands.
CDOSYS
No
Transport Use transport agents for notification-based
agents applications that work with versions of
Exchange starting with Exchange 2010.
ExOLEDB No EWS The EWS Managed API and EWS provide the
Managed API same access to the Exchange store that
or EWS
ExOLEDB provides. Unlike client applications
built by using ExOLEDB, You can run EWS
applications on a local or remote computer.
ICS Yes, but EWS You can use the EWS Managed API or EWS to
deemphasized Managed API subscribe to notifications and synchronize
or EWS
mailbox data.
EWS
Managed If your MAPI application is performing simple
API, EWS
read, write, and update operations on mail,
calendar, or contact objects, and targets Office
365, Exchange 2019² or Exchange 2016¹ ² you
can use the Office 365 REST APIs for mail,
calendars, and contacts.
Store event No EWS You can use the EWS Managed API or EWS to
sinks Managed API subscribe to notifications and synchronize
or EWS
mailbox data.
or EWS
WebDAV No EWS You can use the EWS Managed API or EWS to
notifications Managed API subscribe to notifications.
or EWS
¹REST API and Graph API require the Cumulative Update 3 for Exchange 2016.
²Only hybrid customers are able to take advantage of the REST APIs for both Office 365
and on-premises mailboxes.
See also
Selecting an API or technology for developing solutions for Outlook
On-Premises Architectural Requirements for the REST API
Explore the EWS Managed API, EWS,
and web services in Exchange
Article • 06/14/2022 • 2 minutes to read
Use the EWS Managed API, EWS, Autodiscover, and other web services in Exchange to
create solutions for managing business email, calendar, and contacts on desktop and
mobile devices and online.
Exchange provides Exchange web services (EWS) and other web services that you can
use to implement client applications that access and manage Exchange store items.
7 Note
The terms specified in the License information topic apply to your use of this
content. Please review the terms carefully.
Get started with your first .NET Framework EWS client Get started with EWS Managed API
application. client applications
Get started with your first EWS client application. Get started with EWS client
applications
Find out about the latest new features in the EWS What's new in EWS in Exchange
Learn the fundamentals of web service development with Start using web services in Exchange
Exchange.
Check out some EWS Managed API code samples. Exchange 2013: 101 Code Samples
Find design guidance for EWS Managed API and EWS EWS client design overview for
applications. Exchange
Find how-to information and code examples for the EWS Develop web service clients for
Managed API and EWS. Exchange
See also
Sign up for an Exchange Online and Office 365 Developer Site
What's new in EWS and other web services
in Exchange
Article • 01/15/2020 • 7 minutes to read
Find out what's new in EWS and web services in Exchange and the EWS Managed API.
Table 1. New web service features in Exchange Online, Exchange 2013, and the EWS Managed
API
eDiscovery
Yes Yes Yes
Archiving
Yes Yes Yes
Personas
Yes Yes No
Retention policies
Yes Yes Yes
User photos
Yes Yes No
eDiscovery in EWS
eDiscovery is a federated query web service that enables external applications, such as
SharePoint 2013, to perform queries of Exchange data. Discovery consists of several phases,
including identifying and preserving key data, culling down and reviewing the data, and
producing data in court. eDiscovery queries facilitate the discovery process by providing a single
discovery workflow across Exchange and SharePoint.
Table 2. EWS operations and EWS Managed API methods for working with eDiscovery
GetHoldOnMailboxes ExchangeService.GetHoldOnMailboxes()
Gets the status of a
operation
query-based hold,
which is set by using
the
SetHoldOnMailboxes
operation.
GetNonIndexableItemDetails ExchangeService.GetNonIndexableItemDetails()
Gets details about
operation
items that cannot be
indexed. This
includes, but is not
limited to, the item
identifier, an error
code, an error
description, when an
attempt was made to
index the item, and
additional
information about
the item.
GetNonIndexableItemStatistics ExchangeService.GetNonIndexableItemStatistics()
Gets the count of
operation
items that cannot be
indexed in a mailbox.
GetSearchableMailboxes ExchangeService.GetSearchableMailboxes()
Gets a list of
operation
mailboxes that the
client has permission
to search or perform
eDiscovery on.
SearchMailboxes operation
ExchangeService.SearchMailboxes()
Searches for items in
specific mailboxes
that match query
keywords.
SetHoldOnMailboxes ExchangeService.SetHoldOnMailboxes()
Sets a query-based
operation
hold on items.
Archiving in EWS
Archive mailboxes are secondary mailboxes that are associated with a user. Archive mailboxes
are typically used to manage email storage limits. For example, older email items might
periodically be moved from the Inbox to the archive mailbox.
Exchange introduces two new EWS operations that you can use to archive a set of mail items
from a primary mailbox. Archiving Inbox items in this way preserves the folder hierarchy of the
items. In addition, archive mailboxes can now be stored either locally on a client, or remotely, in
a way that is mostly opaque to a user, by using a folder path to point to the contents of the
archive.
Table 3. EWS operations and EWS Managed API methods for working with archiving
Personas in EWS
A persona is a collection of data that is associated with an individual. The data can come from
one or more sources and is associated with the persona by means of a common link ID.
Personas in EWS enable you to link, search, browse, and retrieve information about a person
from multiple sources and organize that information into a single logical entity. Personas differ
from contacts in that a contact is a collection of data from a single source that is associated with
an individual; for example, a personal Outlook contact or an entry in a global address list (GAL).
7 Note
The Unified Contact Store also exposes persona functionality by means of the operations
that support that feature.
FindPeople Returns all persona objects from a specified contact folder or retrieves all contacts that
operation
match a specified query string.
Table 5. EWS operations for working with the Unified Contact Store
AddNewImContactToGroup Adds a new IM contact to a group. The Unified Contact Store can
operation
contain a maximum of 1000 contacts.
AddImContactToGroup operation
Adds an existing IM contact to a group. The Unified Contact Store
can contain a maximum of 1000 contacts.
AddImGroup operation
Adds a new IM group. The Unified Contact Store can contain a
maximum of 64 groups.
AddDistributionGroupToImList Adds a new distribution list group. The Unified Contact Store can
operation
contain a maximum of 64 groups.
GetImItemList operation
Retrieves a list of IM groups and IM contact personas.
GetImItems operation
Retrieves information about the specified IM groups and IM
contact personas.
RemoveImGroup operation
Removes the specified IM group.
SetImGroup operation
Changes the display name of a group.
Default policy tags that apply to mailbox items that have no other type of retention tag
applied.
System folder policy tags that are applied to default folders such as the Inbox.
Personal tags that a user can apply to folders they create or to individual items.
Only one retention policy can be assigned to a mailbox, but the policy can have one or more
retention tags of various types linked to it. Retention tags can be linked to or unlinked from a
retention policy at any time. EWS in Exchange exposes a new operation,
GetUserRetentionPolicyTags , and the EWS Managed API implements a new method,
ExchangeService.GetUserRetentionPolicyTags() , that provides a list of all the tags that are
linked to a retention policy. You can set and retrieve retention policy tags for items and folders
by using the CreateItem, CreateFolder, UpdateItem, UpdateFolder, GetItem, and GetFolder
operations.
The EWS Managed API does not implement this functionality. You can, however, use the EWS
Managed API to return user photos that are stored in a mailbox by getting the photo that is
attached to a contact.
Table 6. EWS operations and EWS Managed API methods for working with mail apps for
Outlook
DisableApp operation
ExchangeService.DisableApp()
Disables an installed app.
Operation name EWS Managed API method Description
GetAppManifests operation
ExchangeService.GetAppManifests()
Gets the app manifests for
a mailbox.
GetClientAccessToken ExchangeService.GetClientAccessToken()
Gets client access tokens.
operation
InstallApp operation
ExchangeService.InstallApp()
Installs an app for a
mailbox.
UninstallApp operation
ExchangeService.UninstallApp
Uninstalls an app from a
mailbox.
See also
Explore the EWS Managed API, EWS, and web services in Exchange
EWS client design overview for Exchange
Mail apps for Outlook and EWS in Exchange
Archiving in EWS in Exchange
eDiscovery in EWS in Exchange
People and contacts in EWS in Exchange
Start using web services in Exchange
Article • 01/15/2020 • 3 minutes to read
Find information to help you get started with EWS and other web services in Exchange.
The web services in Exchange provide access to mailbox data stored in Exchange Online,
Exchange Online as part of Office 365, and on-premises versions of Exchange starting
with Exchange Server 2007, and enable you to create custom applications that you can
use to manage that information according to the requirements of your organization.
While the range of EWS and web service applications that you can create is practically
infinite, certain fundamental concepts apply for any type of application. This section
provides information about the fundamental concepts you need to be familiar with in
order to start using EWS and other web services in Exchange.
Concept Summary
Architecture
Learn about how EWS works within the Exchange architecture and the
protocols it uses.
EWS application Find out about the most common types of applications that you can create
types
by using EWS in Exchange.
EWS access
Exchange administrators can limit access to EWS globally for the entire
organization, for individual users, and to individual applications. Find out
which access level is right for you.
Setup
Find information about the tasks you need to complete in order to create
applications that use the EWS Managed API or EWS to communicate with
Exchange.
Authentication
Learn about the authentication options for connecting to Exchange Online
and Exchange on-premises.
Autodiscover
Learn about the set of services that you can use to discover the URL
endpoint where a user's account can access information via EWS.
Concept Summary
Mailbox server
Find out about the primary repository of information made available to an
EWS client. EWS has access to a limited set of information stored in Active
Directory Domain Services (AD DS).
Mail apps for Find information about mail apps for Outlook and how they work with
Outlook and EWS
EWS in Exchange.
Office 365 REST APIs Learn about the Office 365 APIs that you can use to access mail, calendars,
for mail, calendars, and contacts in Exchange Online as part of Office 365.
and contacts
The EWS Managed Find information about the preferred client API for .NET Framework
API
developers.
EWS
Find information about creating your first application by using EWS XML
requests and responses.
EWS functionality in Find out what EWS functionality is available in version of Exchange.
Exchange product
versions
Trace and Find out how to trace EWS requests and responses in order to
troubleshoot
troubleshoot errors in your EWS Managed API application.
CodePlex
Many other samples are available in blogs, code demonstration sites, and forums. We
also recommend that you download the EWSEditor . This project implements most of
the EWS functionality; you can find examples of all the core EWS functionality here.
If you're not a .NET Framework developer, you can find many client libraries out there
for EWS development that use Java, Python, PHP, and other languages.
Contact Microsoft support if you need additional assistance. The Exchange Developer
support team is staffed with seasoned professionals who can help answer your
questions about Exchange development.
See also
Explore the EWS Managed API, EWS, and web services in Exchange
EWS client design overview for Exchange
Develop web service clients for Exchange
Web services reference for Exchange
EWS applications and the Exchange
architecture
Article • 01/18/2019 • 6 minutes to read
Learn about how EWS works within the Exchange architecture, and find out which
protocols EWS relies on.
Exchange Web Services (EWS) is a cross-platform API that enables applications to access
mailbox items such as email messages, meetings, and contacts from Exchange Online,
Exchange Online as part of Office 365, or on-premises versions of Exchange starting
with Exchange Server 2007. EWS applications can access mailbox items locally or
remotely by sending a request in a SOAP-based XML message. The SOAP message is
embedded in an HTTP message when sent between the application and the server,
which means that as long as your application can post XML through HTTP, it can use
EWS to access Exchange.
1. EWS application — This can be a client, portal, or service application and it can be
installed on a client or on an Exchange on-premises Client Access server. If you use
the EWS Managed API to develop the EWS application, the EWS Managed API
assemblies have to be installed on the client and redistributed by your application.
4. Load balancer — The load balancer distributes the message to a Client Access
server in the Client Access server array. This component is only visible in the
Exchange on-premises architecture.
5. Client Access server array — Client Access servers are organized into a load-
balanced group called a Client Access server array. Individual Client Access servers
provide authentication, limited redirection, and proxy services. The Client Access
servers themselves don't do any data rendering, and no data is queued or stored
on a Client Access server - it is thin and stateless; it simply authenticates the
request, performs an Autodiscover lookup, and then proxies the request to the
Mailbox server. The Client Access server does maintain a 1:1 relationship with the
Mailbox server that hosts the user's data. The HTTP protocol (secured via SSL using
a self-signed certificate) is used between the Client Access server and Mailbox
server. This component is only visible in the Exchange on-premises architecture.
Feature availability is based on the EWS schema version that your application
targets. Because EWS schemas are backward- and forward-compatible, if you
create an application that targets an earlier schema version, such as Exchange 2007
SP1, your application will also work against a later schema version, such as the
Exchange 2010 SP2 service, as well as Exchange Online. Because features and
feature updates are driven by the schema, we recommend that you use the earliest
common code base that targets the EWS features that you want to implement in
your client application. Many applications can target the Exchange2007_SP1
version, because the Exchange 2007 SP1 schema contains almost all the core
Exchange functionality for working with items and folders in the Exchange store.
For more information, see EWS client features.
8. Database Availability Group (DAG) — Mailbox servers are organized into a highly
available DAG, which can be deployed in one or more datacenters. The Mailbox
server contains the mailbox database and handles all activity for the active
mailboxes on that server. All components that process, render, and store data are
on the Mailbox server. Clients do not connect directly to the Mailbox server; all
connections are handled by the Client Access server. This component is only visible
in the Exchange on-premises architecture.
9. Exchange Online and Exchange Online as part of Office 365 — The hosted
messaging solution that delivers Exchange features as a cloud-based service.
When an EWS application requests information from the Exchange store, an XML
request message that complies with the SOAP standard is created and sent to the
Exchange server. When the Exchange server receives the request, it verifies the
credentials that are provided by the client and automatically parses the XML for the
requested data. The server then builds a SOAP response that contains XML data that
represents the requested strongly typed objects and their properties. The XML data is
sent back to the application in an HTTP response. The application then deserializes the
XML and uses the data to reform the strongly typed objects.
Table 1. Protocols
HTTP/S Enables EWS applications to access Exchange database data over the network,
regardless of whether the client is on the Internet or intranet.
SOAP 1.0 Forms an envelope around the messaging payload. EWS implements the SOAP
protocol by using different parts of the SOAP envelope to enable different
functionality. The SOAP header is used for impersonation and to provide versioning
data. The SOAP body provides information about the operation to run and the data
that is submitted to the operation. SOAP relies on WSDL to describe the operations to
call.
WSDL 1.0 Describes the bindings, the operations, and the properties that are used to call EWS
operations, in the Services.wsdl file. This file, along with the referenced schema files,
comprises the contract between an EWS application and the Exchange server, and is
often used along with vendor-specific tools to create platform-specific applications.
The WSDL file is located in the EWS virtual directory, which is at the root of the
website.
Protocol How it's used
Transport Provides secure web communications on the Internet or on intranet. TLS enables
Layer applications to authenticate servers or, optionally, servers to authenticate EWS
Security applications. It also provides a security channel by encrypting communications. TLS is
(TLS)/SSL the latest version of the Secure Sockets Layer (SSL) protocol.
XML/XSD Provides a universal message format for the exchange of information between the
Exchange server and the client. XML provides complex Exchange database data to
client applications, but in a defined structure. The beauty of XML is that it allows for
the exchange of data even when an EWS application and server do not share a
common platform.
Basic authentication over SSL, for applications that target Exchange Online or
Exchange on-premises.
NTLM authentication over SSL, for applications that support Exchange on-
premises.
See also
Start using web services in Exchange
Find out about the most common types of applications that you can create by using
EWS in Exchange.
The EWS and Exchange architecture provides a uniform development model that you
can use to create the most common types of applications in a consistent way, including
the following:
Each of these application models can use a common code base to retrieve information
from Exchange - so you don't need to change the EWS code used to retrieve item
information between a client, portal, or service application. What might change from
one application to the next is the mailbox access and authentication mechanism. For
example, client applications commonly use direct user access and basic or NTLM
authentication, whereas a service application likely uses impersonation for mailbox
access and OAuth authentication.
Client applications
An EWS client application is any standalone application that uses EWS to retrieve
information from the Exchange store. EWS client applications use direct client access or
delegate access to retrieve data from the mailbox store. The following are some
examples of client applications that use EWS:
Client applications commonly use direct access and basic or NTLM authentication, so
that users are limited to accessing information in their own mailbox with their own
logon credentials. Client applications should also support delegate access for users who
have been given permission to access another user's mailbox.
Portal applications
A portal application extends an existing web page or portal to include Exchange mailbox
information as a personalized component of the page. SharePoint web parts are the
most common portal applications and provide users with a personalized experience by
providing views into Exchange mailbox data, such as unread messages, most recent
messages, and calendar events, alongside their commonly viewed SharePoint portal
page. EWS portal applications can use direct client access, delegate access, or
impersonation to retrieve data from the mailbox store. Because Exchange 2013 and
SharePoint 2013 both support the OAuth authorization protocol for server-to-server
authentication, OAuth provides the most seamless and secure authentication method.
Service applications
A service application is usually a background job built into an existing application that
extends to Exchange to correlate data between the system and the Exchange store.
Service applications typically do not have a user interface and use impersonation or
OAuth for authentication and access. Creating a service account to impersonate users is
common in EWS service apps because you can grant a single account permission to
impersonate a set of users and perform mailbox operations for those accounts. For
example, an EWS service application can synchronize data between marketing lists in a
CRM solution and Exchange distribution groups by using a service account and
impersonation.
See also
Start using web services in Exchange
Develop a simple Hello World email client application for Exchange by using the EWS
Managed API.
The EWS Managed API provides an intuitive, easy-to-use object model for sending
and receiving web service messages from client applications, portal applications, and
service applications. You can access almost all the information stored in an Exchange
Online, Exchange Online as part of Office 365, or an Exchange server mailbox by using
the EWS Managed API. You can use the information in this article to help you develop
your first EWS Managed API client application.
7 Note
We’re removing the ability to use Basic authentication in Exchange Online for EWS
beginning October 2022: Deprecation of Basic authentication in Exchange Online.
You should use OAuth authentication instead. Authenticate an EWS application by
using OAuth
7 Note
The EWS Managed API is now available as an open source project on GitHub .
You can use the open source library to:
After you have verified that you can send and receive email from Exchange, you are
ready to set up your development environment. You can use the Exchange web client
Outlook Web App to verify that you can send email.
Any version of Visual Studio that supports the .NET Framework 4. Although
technically, you don't need Visual Studio because you can use any C# compiler, we
recommend that you use it.
The EWS Managed API . You can use either the 64-bit or 32-bit version,
depending on your system. Use the default installation location.
2. Create a C# Console Application. From the Templates pane, choose Visual C#, and
then choose Console Application.
Visual Studio creates the project and opens the Program.cs code document window.
2. In the Solution Explorer and the HelloWorld project, open the shortcut menu
(right-click) for References and choose Add Reference from the context menu. A
dialog box for managing project references will open.
3. Choose the Browse option. Browse to the location where you installed the EWS
Managed API DLL. The default path set by the installer is the following: C:\Program
Files\Microsoft\Exchange\Web Services<version>. The path can vary based on
whether you download the 32 or 64 bit version of the
Microsoft.Exchange.WebServices.dll. Choose Microsoft.Exchange.WebServices.dll
and select OK or Add. This adds the EWS Managed API reference to your project.
4. If you are using EWS Managed API 2.0, change the HelloWorld project to target
the .NET Framework 4. Other versions of the EWS Managed API might use a
different target version of the .NET Framework.
5. Confirm that you are using the correct target version of the .NET Framework. Open
the shortcut menu (right-click) for your HelloWorld project in the Solution
Explorer, and choose Properties. Verify that the .NET Framework 4 is selected in
the Target framework drop-down box.
Now that you have your project set up and you created a reference to the EWS
Managed API, you are ready to create your first application. To keep things simple, add
your code to the Program.cs file. Read Reference the EWS Managed API assembly for
more information about referencing the EWS Managed API. In the next step, you will
develop the basic code to write most EWS Managed API client applications.]
C#
if (redirectionUri.Scheme == "https")
result = true;
return result;
This validation callback will be passed to the ExchangeService object in step 4. You need
this so that your application will trust and follow Autodiscover redirects - the results of
the Autodiscover redirect provides the EWS endpoint for our application.
C#
using Microsoft.Exchange.WebServices.Data;
2. In the Main method, instantiate the ExchangeService object with the service
version you intend to target. This example targets the earliest version of the EWS
schema.
C#
3. If you are targeting an on-premises Exchange server and your client is domain
joined, proceed to step 4. If you client is targeting an Exchange Online or Office
365 Developer Site mailbox, you have to pass explicit credentials. Add the
following code after the instantiation of the ExchangeService object and set the
credentials for your mailbox account. The user name should be the user principal
name. Proceed to step 5.
C#
4. Domain-joined clients that target an on-premises Exchange server can use the
default credentials of the user who is logged on, assuming the credentials are
associated with a mailbox. Add the following code after the instantiation of the
ExchangeService object.
C#
service.UseDefaultCredentials = true;
If your client targets an Exchange Online or Office 365 Developer Site mailbox,
verify that UseDefaultCredentials is set to false, which is the default value. Your
client is ready to make the first call to the Autodiscover service to get the service
URL for calls to the EWS service.
C#
service.AutodiscoverUrl("[email protected]",
RedirectionUrlValidationCallback);
At this point, your client is set up to make calls to EWS to access mailbox data. If you run
your code now, you can verify that the AutodiscoverUrl method call worked by
examining the contents of the ExchangeService.Url property. If this property contains
a URL, your call was a success! This means that your application successfully
authenticated with the service and discovered the EWS endpoint for your mailbox. Now
you are ready to make your first calls to EWS. Read Set the EWS service URL by using the
EWS Managed API for more information about setting the EWS URL.
C#
EmailMessage email = new EmailMessage(service);
You now have an email message on which the service binding is set. Any calls
initiated on the EmailMessage object will be targeted at the service.
2. Now set the To: line recipient of the email message. To do this, change
[email protected] to use your SMTP address.
C#
email.ToRecipients.Add("[email protected]");
C#
email.Subject = "HelloWorld";
4. You are now ready to send your first email message by using the EWS Managed
API. The Send method will call the service and submit the email message for
delivery. Read Communicate with EWS by using the EWS Managed API to learn
about other methods you can use to communicate with Exchange.
C#
email.Send();
5. You are ready to run your Hello World application. In Visual Studio, select F5. A
blank console window will open. You will not see anything in the console window
while your application authenticates, follows Autodiscover redirections, and then
makes its first call to create an email message that you send to yourself. If you
want to see the calls being made, add the following two lines of code before the
AutodiscoverUrl method is called. Then press F5. This will trace out the EWS
requests and responses to the console window.
C#
service.TraceEnabled = true;
service.TraceFlags = TraceFlags.All;
You now have a working EWS Managed API client application. For your convenience, the
following example shows all the code that you added to Program.cs to create your Hello
World application.
C#
using System;
using Microsoft.Exchange.WebServices.Data;
namespace HelloWorld
class Program
service.TraceEnabled = true;
service.TraceFlags = TraceFlags.All;
service.AutodiscoverUrl("[email protected]",
RedirectionUrlValidationCallback);
email.ToRecipients.Add("[email protected]");
email.Subject = "HelloWorld";
email.Send();
if (redirectionUri.Scheme == "https")
result = true;
return result;
Next steps
If you're ready to do more with your first EWS Managed API client application, explore
the following resources:
If you run into any issues with your application, try posting a question or comment in
the forum (and don't forget to read the top post).
In this section
Reference the EWS Managed API assembly
Set the EWS service URL by using the EWS Managed API
Communicate with EWS by using the EWS Managed API
See also
Start using web services in Exchange
EWS client design overview for Exchange
Develop web service clients for Exchange
Trace requests and responses to troubleshoot EWS Managed API applications
Reference the EWS Managed API
assembly
Article • 03/04/2022 • 2 minutes to read
Find information about how to reference the EWS Managed API assembly.
The EWS Managed API provides a simple and full-featured interface for developing and
extending applications that use Exchange Web Services (EWS). Whether you are using
Visual Studio or another code editor to develop your EWS Managed API application, you
will need to make a reference to the EWS Managed API assembly. If you haven't
installed the EWS Managed API already, be sure to download the API .
7 Note
The EWS Managed API is now available as an open source project on GitHub .
You can use the open source library to:
2. In the Solution Explorer pane in Visual Studio, select References, and then choose
Add Reference. This opens the Add Reference window.
3. In the Add Reference window, navigate to the Browse tab, browse to the location
of the Microsoft.Exchange.WebServices.dll file, select that file, and then select OK.
4. To use the EWS Managed API in your application, add a using statement for the
Microsoft.Exchange.WebServices.Data namespace.
C#
using Microsoft.Exchange.WebServices.Data;
2. In your source code editor, add a using statement to the source code for the
Microsoft.Exchange.WebServices.Data namespace.
C#
using Microsoft.Exchange.WebServices.Data;
3. Run the command-line compiler to build the application. The following command
uses the .NET Framework C# compiler to build the Windows application defined in
the source code file "program.cs". It assumes that the compiler is located in the
default installation directory and that the Microsoft.Exchange.WebServices.dll file is
in a subdirectory of the current directory named "build".
C#
See also
Get started with EWS Managed API client applications
Setting up your Exchange application development environment
Communicate with EWS by using the EWS Managed API
Set the EWS service URL by using the
EWS Managed API
Article • 01/15/2020 • 2 minutes to read
Find information about how to set the EWS service URL in your EWS Managed API
application.
The service URL is the address that Exchange uses to communicate with Exchange Web
Services (EWS). After your EWS Managed API application has this address, and has
appropriate access to communicate with EWS, it can make calls to the ExchangeService
class . The service URL for an on-premises Exchange server might look like the
following.
HTML
https://computer.domain.contoso.com/EWS/Exchange.asmx
You can set the EWS URL in your application in a couple of ways. We recommend that
you use the Autodiscover service to get the URL because in a large forest of servers,
the URL can change if the mailbox is migrated to another server. However, because
calling Autodiscover can take some time and can slow down your application if you
need to make multiple calls in a short period of time, you might want to cache the URL
value you get from Autodiscover and manually set the EWS service URL with this cached
value. This will improve the performance of your application; just make sure that you use
Autodiscover to update your cached value periodically in case the value changes on the
server.
C#
service.AutodiscoverUrl("[email protected]");
C#
service.Url = new
Uri("https://computername.domain.contoso.com/EWS/Exchange.asmx");
See also
Get started with EWS Managed API client applications
Setting up your Exchange application development environment
Control access to EWS in Exchange
Communicate with EWS by using the EWS Managed API
Use Autodiscover to find connection points
Communicate with EWS by using the
EWS Managed API
Article • 03/04/2022 • 3 minutes to read
Find information about how to use the EWS Managed API to communicate with EWS in
Exchange.
7 Note
We’re removing the ability to use Basic authentication in Exchange Online for EWS
beginning October 2022 Deprecation of Basic authentication in Exchange Online.
You should use OAuth authentication instead. Authenticate an EWS application by
using OAuth
The ExchangeService class in the EWS Managed API contains the methods and
properties that you use to set user credentials, identify the EWS endpoint, send and
receive SOAP messages, and configure the binding to communicate with EWS. Before
you can use the EWS Managed API to perform any task, you have to create an instance
of the ExchangeService class and bind it to EWS.
After you set up an ExchangeService object with user credentials and the EWS
endpoint, any mailbox object that references the ExchangeService object can use the
following method types to communicate with EWS:
Table 1. Mailbox item and folder type methods that communicate with EWS
Load
Gets properties on an item, attachment, or user configuration GetItem operation
object.
GetAttachment
operation
GetUserConfiguration
operation
Bind
Populates a new item on the client with information from an GetItem operation
Save
Saves the copy of the client item on the server. UpdateItem
operation
UpdateFolder
operation
CreateItem
operation
CreateFolder
operation
Update Updates the server with the changes made on the client.
UpdateItem
operation
Delete
Deletes an item on the server.
DeleteItem
operation
For items and folders, the Delete method uses the and the
DeleteFolder operation . DeleteFolder
operation
Copy
Creates a copy of the item or folders on the server. CopyItem
operation
CopyFolder
operation
Move
Moves items or folders on the server. MoveItem
operation
MoveFolder
operation
C#
ExchangeService service = new ExchangeService();
7 Note
2. Set the credentials of the user who sends requests to the Exchange server. If you
want to connect to EWS from a computer that is logged on to the domain, using
the credentials of the authenticated user, set the UseDefaultCredentials property
on the ExchangeService object to true.
C#
service.UseDefaultCredentials = true;
If you do not want to connect by using the default user credentials, set the
Credentials property on the ExchangeService object to explicitly specify the
credentials of a different user. If you are using Exchange Online or Exchange
Online as part of Office 365, you'll use basic authentication, with just a user name
and password. A domain name is required for NTLM authentication.
C#
You can also specify the credentials of the user by using the user's domain name
and password.
C#
7 Note
3. Set the URL of the EWS endpoint. This URL locates the exchange.asmx file on Client
Access server.
C#
service.AutodiscoverUrl("[email protected]");
7 Note
Although you can explicitly set the Url property of the ExchangeService to a
hardcoded value, we recommend that you use the Autodiscover service
instead, for the following reasons:
See also
Get started with EWS Managed API client applications
Use Autodiscover to find connection points
Develop web service clients for Exchange
Trace requests and responses to
troubleshoot EWS Managed API apps
Article • 01/15/2020 • 2 minutes to read
Find out how to trace EWS requests and responses to troubleshoot errors in your EWS
Managed API application.
If you are using EWS, you already have access to the XML request and response; you can
put a break point in your code to review the server's response to your request in order
to troubleshoot an issue. If you're using the EWS Managed API, you don't have direct
access to the EWS request and response. However, you can use tracing methods on the
ExchangeService object to capture the XML request and response, and you can then
use the XML to determine why your code is not working.
For example, if you did not set a property correctly, you might get an unexpected
response, and you can use the trace output to look at the XML request and response to
identify the error. The trace output from the EWS Managed API can also help you
manually build the XML request to create your EWS application. If you are using EWS,
you can create a small application by using EWS Managed API, trace it, and then use the
XML request information to help you build your EWS request.
C#
service.TraceListener = ITraceListenerInstance;
service.TraceEnabled = true;
After you set the TraceEnabled property to true, all requests that match the trace flags
will be sent to the specified trace listener. You can specify a single trace flag, or you can
specify multiple trace flags by combining them with a logical OR. You can use the
TraceFlags enumeration to specify values for EWS and for Autodiscover requests and
responses.
C#
CreateXMLTextFile(traceType, traceMessage.ToString());
#endregion
try
xmlDoc.Load(traceContent);
xmlDoc.Save(fileName + ".xml");
catch
See also
Start using web services in Exchange
Handling Autodiscover error messages
Reference the EWS Managed API assembly
Communicate with EWS by using the EWS Managed API
Get started with EWS client applications
Article • 03/04/2022 • 10 minutes to read
Create your first application by using Exchange Web Services (EWS) in Exchange.
EWS is a comprehensive service that your applications can use to access almost all the
information stored in an Exchange Online, Exchange Online as part of Office 365, or
Exchange on-premises mailbox. EWS uses standard web protocols to provide access to
an Exchange server; libraries like the EWS Managed API wrap the EWS operations to
provide an object-oriented interface. After you've run the examples in this article, you
will have a basic understanding of what you can do with EWS.
You can call EWS operations from any operating system or language, because the EWS
requests and responses use the SOAP protocol. The examples in this article are written
using C# and make use of the .NET Framework HttpWebRequest and
HttpWebResponse objects; however, the important part of the code is the XML used
to make the EWS request and the XML response returned from the server. The code
examples emphasize the XML transactions and not processing the XML.
7 Note
We’re removing the ability to use Basic authentication in Exchange Online for EWS
beginning October 2022 Deprecation of Basic authentication in Exchange Online.
You should use OAuth authentication instead. Authenticate an EWS application by
using OAuth
Get an Office 365 Developer Site(recommended). This is the quickest way for you
to get an Exchange mailbox.
After you've verified that you can send and receive email from your Exchange server you
are ready to set up your development environment. You can use Outlook Web App to
verify that you can send email.
You'll also need to know the URL of the EWS endpoint for your server. In a production
application, you'd use Autodiscover to determine the EWS URL. The examples in this
article use the Office 365 EWS endpoint URL,
https://outlook.office365.com/EWS/Exchange.asmx . The Next steps section has links to
more information about Autodiscover when you're ready.
If you are testing your application using an Exchange server that has the default self-
signed certificate, you'll need to create a certificate validation method that meets the
security requirements of your organization.
Any version of Visual Studio that supports the .NET Framework 4.0.
An Internet connection that your development machine can use to contact your
Exchange server. If you can use Outlook Web App with a DNS name rather than an
IP address to connect to your Exchange server, you are set up.
1. Get information from an Exchange mailbox and display that information to the
user.
2. Perform an action, such as sending an email, and check the response to see if the
action succeeded.
C#
using System;
using System.IO;
namespace Microsoft.Exchange.Samples.EWS
class Tracing
Console.Write(format, args);
if (logFileWriter != null)
logFileWriter.Write(format, args);
Console.WriteLine(format, args);
if (logFileWriter != null)
logFileWriter.WriteLine(format, args);
logFileWriter.Flush();
logFileWriter.Close();
Next, open the Program.cs file. You will put the rest of the code for the example in this
file.
1. Create a log file so that the request and response can be written to disk for later
study.
2. Get the email address and password of the account that you'll access.
3. Call the sample methods.
Replace the Main method in the Program.cs with the following code.
C#
static void Main(string[] args)
Tracing.OpenLog("./GetStartedWithEWS.log");
if (!isValidEmailAddress)
if (password.Length == 0)
// ShowNumberOfMessagesInInbox(userCredentials);
// SendTestEmail(userCredentials);
Tracing.CloseLog();
Console.ReadLine();
The last thing that you need to do is add the GetPasswordFromConsole static method.
This method returns a SecureString object that contains a password typed at the
console.
C#
while (readingPassword)
switch (userInput.Key)
case (ConsoleKey.Enter):
readingPassword = false;
break;
case (ConsoleKey.Escape):
password.Clear();
readingPassword = false;
break;
case (ConsoleKey.Backspace):
if (password.Length > 0)
password.RemoveAt(password.Length - 1);
Console.SetCursorPosition(Console.CursorLeft - 1,
Console.CursorTop);
Console.Write(" ");
Console.SetCursorPosition(Console.CursorLeft - 1,
Console.CursorTop);
break;
default:
if (userInput.KeyChar != 0)
password.AppendChar(userInput.KeyChar);
Console.Write("*");
break;
Console.WriteLine();
password.MakeReadOnly();
return password;
C#
/// This is the XML request that is sent to the Exchange server.
var getFolderSOAPRequest =
"<soap:Envelope xmlns:soap=\"https://schemas.xmlsoap.org/soap/envelope/\"\n"
+
"
xmlns:t=\"https://schemas.microsoft.com/exchange/services/2006/types\">\n" +
"<soap:Header>\n" +
" </soap:Header>\n" +
" <soap:Body>\n" +
" <GetFolder
xmlns=\"https://schemas.microsoft.com/exchange/services/2006/messages\"\n" +
"
xmlns:t=\"https://schemas.microsoft.com/exchange/services/2006/types\">\n" +
" <FolderShape>\n" +
" <t:BaseShape>Default</t:BaseShape>\n" +
" </FolderShape>\n" +
" <FolderIds>\n" +
" </FolderIds>\n" +
" </GetFolder>\n" +
" </soap:Body>\n" +
"</soap:Envelope>\n";
// Write the get folder operation request to the console and log file.
Tracing.WriteLine(getFolderSOAPRequest);
getFolderRequest.AllowAutoRedirect = false;
getFolderRequest.Credentials = userCredentials;
getFolderRequest.Method = "POST";
getFolderRequest.ContentType = "text/xml";
requestWriter.Write(getFolderSOAPRequest);
requestWriter.Close();
try
if (responseEnvelope != null)
Tracing.WriteLine("Response:");
settings.Indent = true;
responseEnvelope.Save(writer);
writer.Close();
Tracing.WriteLine(stringBuilder.ToString());
("
{https://schemas.microsoft.com/exchange/services/2006/messages}ResponseCode"
)
select errorCode;
if (errorCode.Value != "NoError")
switch (errorCode.Parent.Name.LocalName.ToString())
case "Response":
case "UserResponse":
responseEnvelope.Descendants
("
{https://schemas.microsoft.com/exchange/services/2006/messages}Folders")
select folderElement;
folder.Descendants
("
{https://schemas.microsoft.com/exchange/services/2006/types}DisplayName")
select folderElement.Value;
Tracing.WriteLine(folderName.ElementAt(0));
folder.Descendants
("
{https://schemas.microsoft.com/exchange/services/2006/types}TotalCount")
select folderElement.Value;
Tracing.WriteLine(totalCount.ElementAt(0));
folder.Descendants
("
{https://schemas.microsoft.com/exchange/services/2006/types}UnreadCount")
select folderElement.Value;
Tracing.WriteLine(unreadCount.ElementAt(0));
Tracing.WriteLine(ex.Message);
Tracing.WriteLine(ex.Message);
Parsing the returned XML response to determine if the email was correctly sent.
Add the following code to the SendTestEmail method that was stubbed out after the
main method. After you run the application, you can open the GetStartedWithEWS.log
file to see the XML request that was sent to the Exchange server and the response that
the server returned.
C#
var createItemSOAPRequest =
"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-
instance\" \n" +
"
xmlns:m=\"https://schemas.microsoft.com/exchange/services/2006/messages\"
\n" +
"
xmlns:t=\"https://schemas.microsoft.com/exchange/services/2006/types\" \n" +
"
xmlns:soap=\"https://schemas.xmlsoap.org/soap/envelope/\">\n" +
" <soap:Header>\n" +
" </soap:Header>\n" +
" <soap:Body>\n" +
" <m:SavedItemFolderId>\n" +
" </m:SavedItemFolderId>\n" +
" <m:Items>\n" +
" <t:Message>\n" +
" <t:ToRecipients>\n" +
" <t:Mailbox>\n" +
" <t:EmailAddress>[email protected]</t:EmailAddress>\n" +
" </t:Mailbox>\n" +
" </t:ToRecipients>\n" +
" </t:Message>\n" +
" </m:Items>\n" +
" </m:CreateItem>\n" +
" </soap:Body>\n" +
"</soap:Envelope>\n";
// Write the create item operation request to the console and log
file.
Tracing.WriteLine(createItemSOAPRequest);
getFolderRequest.AllowAutoRedirect = false;
getFolderRequest.Credentials = userCredentials;
getFolderRequest.Method = "POST";
getFolderRequest.ContentType = "text/xml";
requestWriter.Write(createItemSOAPRequest);
requestWriter.Close();
try
if (responseEnvelope != null)
Tracing.WriteLine("Response:");
settings.Indent = true;
responseEnvelope.Save(writer);
writer.Close();
Tracing.WriteLine(stringBuilder.ToString());
("
{https://schemas.microsoft.com/exchange/services/2006/messages}ResponseCode"
)
select errorCode;
if (errorCode.Value != "NoError")
switch (errorCode.Parent.Name.LocalName.ToString())
case "Response":
case "UserResponse":
Tracing.WriteLine(ex.Message);
Tracing.WriteLine(ex.Message);
Next steps
Now that you've written your first EWS application, you're ready to discover other ways
to use EWS. Here are some ideas to get you started:
Implement Autodiscover in your application so that your application will connect
to the correct Exchange server based on the user's email address. See also the
Exchange 2013: Get user settings with Autodiscover sample.
See the EWS operations for information about the operations that are available.
Use EWS Editor to see the SOAP traffic sent to and from the server.
If you run into any issues with your application, try posting a question or comment in
the forum (and don't forget to read the first post).
See also
Start using web services in Exchange
Explore the EWS Managed API, EWS, and web services in Exchange
EWS client design overview for Exchange
Develop web service clients for Exchange
Get started with EWS Managed API client applications
EWS functionality in Exchange product
versions
Article • 09/15/2021 • 2 minutes to read
EWS implements new functionality in new product releases. Use the information in this
article to determine whether the version of Exchange you're targeting includes support
for the data or features you need access to.
The following table lists the versions of Exchange that include EWS and the major
features that were introduced in each version.
Office 365 Includes all the features in the current version of Exchange in addition to any new
and features that are added for online clients.
Exchange
Online
Exchange Includes all features introduced in Exchange 2013. The following features were
2013 SP1 introduced in Exchange 2013 SP1:
Read receipts can now be suspended for updates and deletions.
You can get moderated transport approval information.
Voting responses can be viewed.
The SetHoldOnMailboxes method and SetHoldOnMailboxes operation
accept all the parameters in a single object.
eDiscovery searches can specify a language for search queries and a
culture-specific format for date ranges.
The StreamingSubscriptionConnection object can now access the
StreamingSubscription objects.
Conversations have a setting to indicate whether they contain email
messages that are protected by IRM.
Meeting attendees can propose new start and end times for meetings and
include them in their meeting response.
The SOAP Autodiscover GetUserSettings method now returns the
GroupingInformation setting that is used maintain affinity for a multiple
mailbox event subscription.
Product Features
version
Exchange Includes all features introduced in Exchange 2010 SP2. The following features
2013 were introduced in Exchange 2013:
Archiving
eDiscovery
Personas
Retention policies
Unified Contact Store
User photos
Exchange Includes all the features introduced in Exchange 2010 SP1. The following features
2010 SP2 were introduced in Exchange 2010 SP2:
Get Password Expiration
DateTime precision
Updated property identifiers for contacts
New impersonation scenarios
Exchange Includes all the features introduced in Exchange 2010. The following features
2010 SP1 were introduced in Exchange 2010 SP1:
Create, retrieve and modify Inbox rules
Programmatic access to Archive Mailbox
Conversations actions
Firewall traversing notifications
Improved administration features
Improved mixed version support
Throttling protection support
Control of application access to EWS
Client certificate authentication support
Exchange Includes all features introduced in Exchange 2007 SP1. The following features
2010 were introduced in the initial release version of Exchange 2010:
Full Private Distribution List
User Configuration Objects
Folder Associated Items
Message tracking
Unified Messaging
SOAP Autodiscover
Enhanced Time Zone support
Room resource availability information
Indexed search
Dumpster access
MailTips information
Product Features
version
Exchange Includes all the features introduced in Exchange 2007. The following features
2007 SP1 were introduced in Exchange 2007 SP1:
Delegate management
Folder permissions
Public folders
Post items
ID conversion
Exchange The following features were introduced in the initial release version of Exchange
2007 2007:
Full access to items, folders, and attachments (Create, Get, Update, Delete)
Availability
Out of Office settings
Notifications
Synchronization
Name resolution
Distribution list (DL) expansion
Search
See also
Start using web services in Exchange
Migrating to Exchange technologies
Explore the EWS Managed API, EWS, and web services in Exchange
Setting up your EWS application
Article • 01/18/2019 • 2 minutes to read
Find information about the tasks you need to complete in order to create applications
that use the EWS Managed API or EWS to communicate with Exchange.
When you create a client application that calls web services on Exchange Online,
Exchange Online as part of Office 365, or a version of Exchange starting with Exchange
2013, you'll need to set up your application to communicate with the Exchange server.
The articles in this section provide code examples that show you how to use the
Exchange Web Services (EWS) Managed API or EWS XML requests and responses to set
up your application.
In this section
Setting up your Exchange application development environment
See also
Start using web services in Exchange
Learn about how to set up your development environment to create an EWS application
that communicates with Exchange.
Before you start writing your Exchange Web Services (EWS) application, you'll need to
make sure that your development environment meets a few minimum requirements.
You can use the EWS Managed API, the standard client access API for .NET Framework
applications, to develop your application, or you can use EWS on its own, with our
without an autogenerated proxy. In general, we recommend that you use the EWS
Managed API; however, you can explore the difference between these two options in
more detail to find out which one is right for you.
7 Note
The EWS Managed API is now available as an open source project on GitHub .
You can use the open source library to:
You can store the EWS Managed API files anywhere on your computer; by default,
they are installed in the Program Files\Microsoft\Exchange\Web Services<version
number> folder.
A mailbox on an Exchange server that is running Exchange Online, Exchange
Online as part of Office 365, or a version of Exchange starting with Exchange
Server 2007.
You can get an Exchange Online plan for business, including a free trial, from the
Office 365 site . In order to connect to the mailbox you must have the user name
and credentials of the account associated with the mailbox.
A version of Visual Studio starting with Visual Studio 2005. If you don't currently
have Visual Studio, you can download a free version .
A version of the .NET Framework starting with the .NET Framework 3.5. You can
download the .NET Framework 3.5 from the Microsoft Download Center .
In addition, it is helpful if you have some familiarity with C#. Although Visual Studio
supports other languages in addition to C#, most of the sample code available for the
EWS Managed API is written in C#.
A simple text editor, like Notepad, to edit your XML request. Any text editor will
do, although you might want one that will help with your XML syntax validation
like XMetal.
A tool or application that can send and receive SOAP XML requests and responses,
in order to communicate with Exchange.
When you work with raw XML, it's also helpful to have a basic understanding of XML
formatting.
The second way to use EWS is to create an autogenerated proxy that enables you to
work with the operations by using a .NET language like C#. Here is what you need to
work with an autogenerated proxy:
A version of Visual Studio starting with Visual Studio 2005, to create a proxy
reference. You can download a free version .
A version of the .NET Framework starting with the .NET Framework 2.0. You can
download the .NET Framework 3.5 from the Microsoft Download Center .
If you use an autogenerated proxy, you'll want to have some familiarity with C#
programming.
7 Note
If you're a .NET Framework developer, we encourage you to use the EWS Managed
API rather than autogenerated proxies to develop against EWS. The EWS Managed
API object model is easier to use than autogenerated proxy object models. Also,
the EWS Managed API implements Autodiscover and includes client-side logic.
See also
Setting up your Exchange application development environment
EWS client design overview for Exchange
Control access to EWS in Exchange
EWS generated object models for Exchange
Controlling client application access to
EWS in Exchange
Article • 06/14/2022 • 2 minutes to read
Learn about the options for managing client application access to EWS.
Any EWS client application that you create must be granted access to Exchange Online,
Exchange Online as part of Office 365, or version of Exchange starting with Exchange
2013 before it can call EWS operations. Test or production server administrators can use
the Exchange Management Shell to limit access to EWS either for all users and
applications, for individual users, or for individual applications. Access control for EWS is
based on domain accounts. When a connection is made with credentials that are
authenticated by the local security authority, the server returns an error that indicates
that only domain accounts can connect.
By allowing any client application to connect except those that are specifically
blocked.
Applications are identified by the user agent string that they send in the HTTP web
request.
) Important
Application-level blocking is not a security feature. The user agent string is easily
spoofed. If an application is allowed access to EWS, the application must still
present credentials that the server authenticates before the application can connect
to EWS.
Administrators can also configure access control for mailbox owners that connect to
EWS in the following ways:
Specific access control settings override general access control settings. For example, if
an organization denies EWS access but an individual mailbox owner is allowed
application access, the individual setting prevails and access is allowed.
Add the Authenticated Users group to the Pre-Win2K Compatible Access Group.
Add the Exchange Servers group to the Windows Authorization Access group.
Exchange Management Shell cmdlets for access
management
Administrators use the following Exchange Management Shell cmdlets to configure EWS
access controls:
Get-CASMailbox
Set-CASMailbox
Get-OrganizationConfig
Set-OrganizationConfig
See also
Start using web services in Exchange
Control access to EWS in Exchange
Exchange Server PowerShell (Exchange Management Shell)
Windows PowerShell
Control access to EWS in Exchange
Article • 06/14/2022 • 2 minutes to read
Find out how to control access to EWS for users, applications, or the entire organization.
Whether you are using the EWS Managed API, or EWS directly, in your application, you
can control access to Exchange Web Services (EWS). If you have administrator access to
your Exchange server, you can manage access to EWS by using the Exchange
Management Shell to control access globally, for each user, and for each application.
Get-CASMailbox - Shows you what parameters are set for a particular mailbox.
Set-CASMailbox - Sets parameters for a particular mailbox.
Get-OrganizationConfig - Shows you the parameters for the entire organization.
Set-OrganizationConfig - Sets the parameters for the entire organization.
See also
Setting up your EWS application
Controlling client application access to EWS in Exchange
Exchange Server PowerShell (Exchange Management Shell)
Windows PowerShell
Managing user access by using EWS in
Exchange
Article • 06/14/2022 • 2 minutes to read
Find out what your options are for managing user account access to your Exchange
server.
Exchange Web Services (EWS) and the EWS managed API provide a limited number of
operations that you can use to manage accounts on Exchange Online, Exchange Online
as part of Office 365, or a version of Exchange starting with Exchange 2013. You can use
the operations shown in the following figure to manage delegates and to set folder
access permissions for other accounts.
If your application needs additional control over the accounts on an Exchange server,
you can use Exchange Management Shell cmdlets to manage the accounts. You can call
the Exchange Management Shell cmdlets by doing one of the following:
See also
Setting up your EWS application
Exchange 2013 Cmdlets
Validate a server certificate for the EWS
Managed API
Article • 02/11/2022 • 3 minutes to read
Learn how to create and reference a certificate validation callback method so that you
can make EWS Managed API requests to an Exchange server.
By default, versions of Exchange starting with Exchange 2007 SP1 use self-signed X509
certificates to authenticate calls from EWS. When you are using the EWS Managed API,
you need to create a certificate validation callback method; otherwise, EWS Managed
API requests will fail. If you are using the Autodiscover service, the call to the EWS
Managed API Autodiscover method will fail with an AutodiscoverLocalException error.
If you are using a web-generated web service proxy, you might also have to create a
validation callback method, depending on how the proxy is created.
Your Exchange server is using a self-signed certificate for EWS. If the administrator
has installed a valid certificate that traces to a root certificate, you do not need to
create a validation callback method.
You are creating a managed application that includes a reference to the following
required .NET Framework namespaces:
System.Net
System.Net.Security
System.Security.Cryptography.X509Certificates
C#
object sender,
System.Security.Cryptography.X509Certificates.X509Certificate
certificate,
System.Security.Cryptography.X509Certificates.X509Chain chain,
System.Net.Security.SslPolicyErrors sslPolicyErrors)
if (sslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
return true;
if ((sslPolicyErrors &
System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors) != 0)
foreach
(System.Security.Cryptography.X509Certificates.X509ChainStatus status in
chain.ChainStatus)
(status.Status ==
System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.Untrusted
Root))
continue;
else
if (status.Status !=
System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.NoError)
return false;
return true;
else
return false;
You use the ServicePointManager class in the .NET System.Net namespace to hook up a
validation callback method by setting the ServerCertificateValidationCallback property.
You can use code similar to the following code example to set the
ServerCertificateValidationCallback property.
C#
ServicePointManager.ServerCertificateValidationCallback =
CertificateValidationCallBack;
Next steps
After you have created the validation callback method for the EWS Managed API, you
can use the Autodiscover service to get connection points and user and domain settings
from an Exchange server. For more information, see the following articles:
See also
Setting up your EWS application
Start using web services in Exchange
Authentication and EWS in Exchange
Article • 06/14/2022 • 4 minutes to read
Find information to help you choose the right authentication standard for your EWS
application that targets Exchange.
Authentication is a key part of your Exchange Web Services (EWS) application. Exchange
Online, Exchange Online as part of Office 365, and on-premises versions of Exchange
starting with Exchange Server 2013 support standard web authentication protocols to
help secure the communication between your application and the Exchange server.
If you're targeting Exchange Online, the authentication method that you choose must
use HTTPS to encrypt the requests and responses that your application sends. Although
you can use HTTP with Exchange on-premises servers, we recommend that you use
HTTPS for any request that your application sends to an EWS endpoint to help secure
communication between your application and an Exchange server.
Exchange provides the following authentication options for you to choose from:
The authentication method that you choose depends on the security requirements of
your organization, whether you are using Exchange Online or Exchange on-premises,
and whether you have access to a third-party provider that can issue OAuth tokens. This
article provides information that will help you select the authentication standard that's
right for your application.
OAuth authentication
We recommend that all new applications use the OAuth standard to connect to
Exchange Online services. The advantage in security over basic authentication is worth
the additional work required to implement OAuth in your application. For the record,
however, there are also some disadvantages that you should be aware of.
Advantages Disadvantages
Advantages Disadvantages
credentials.
To help minimize the disadvantages, you can use the Microsoft Azure AD Authentication
Library (ADAL) to authenticate users to Active Directory Domain Services (AD DS) in the
cloud or on-premises and then obtain access tokens for securing calls to an Exchange
server. Exchange Online requires tokens issued by the Azure Active Directory service,
which is supported by the ADAL; however, you can use any third-party library.
To learn more about using OAuth authentication in your EWS application, see the
following resources:
Office 365 trial, to set up an Exchange server to use to test your client application.
Review the sample code in Authenticate an EWS application by using OAuth for
example code that you can study.
NTLM authentication
NTLM authentication is only available for Exchange on-premises servers. For
applications that run inside the corporate firewall, integration between NTLM
authentication and the .NET Framework provides a built-in means to authenticate your
application.
Advantages Disadvantages
Advantages Disadvantages
Works "out of the box" with your Exchange server. You Users must be logged on to a domain
can configure access to Exchange services by using an to use NTLM authentication.
Code samples are available that use the logged on Service applications must have a
user's credentials for authentication to an on-premises domain account to take advantage of
Exchange server. NTLM authentication.
Basic authentication
Basic authentication provides a, well, basic level of security for your client application.
We do recommend that all new applications use either NTLM or the OAuth protocol for
authentication; however, basic authentication can be the correct choice for your
application in some circumstances.
Advantages Disadvantages
Works "out of the box" with your Exchange server. Requires your application to collect and
You can configure access to Exchange services by store the user's credentials.
Many code samples are available that show you If a security breach occurs in your
how to call EWS using basic authentication. application, it can expose the user's email
address and password to the attacker.
You need to decide if basic authentication meets the security requirements of your
organization and customers. Basic authentication can be the right choice if you want to
avoid extensive setup tasks, for example for simple test or demonstration applications.
7 Note
See also
Authenticate an EWS application by using OAuth
Start using web services in Exchange
Adding Sign-On to Your Web Application Using Microsoft Azure AD
Control access to EWS in Exchange
Controlling client application access to EWS in Exchange
Supported token and claim types
Authenticate an EWS application by
using OAuth
Article • 10/31/2022 • 6 minutes to read
Learn how to use OAuth authentication with your EWS Managed API applications.
You can use the OAuth authentication service provided by Azure Active Directory to
enable your EWS Managed API applications to access Exchange Online in Office 365. To
use OAuth with your application you will need to:
7 Note
To use the code in this article, you will need to have access to the following:
A Microsoft 365 account with an Exchange Online mailbox. If you do not have a
Microsoft 365 account, you can sign up for the Microsoft 365 Developer Program
to get a free Microsoft 365 subscription.
The Microsoft Authentication Library for .NET.
The EWS Managed API .
There are two types of OAuth permissions that can be used to access EWS APIs in
Exchange Online. Before you proceed with the tutorial, you will need to choose the
specific permission type to use.
Delegated permissions are used by apps that have a signed-in user present. For
these apps, either the user or an administrator consents to the permissions that
the app requests and the app can act as the signed-in user when making API calls.
Application permissions are used by apps that run without a signed-in user
present; for example, apps that run as background services or daemons and can
access multiple mailboxes.
Register your application
To use OAuth, an application must have an application ID issued by Azure Active
Directory. In this tutorial, it is assumed that the application is a console application, so
you need to register your application as a public client with Azure Active Directory. You
can register an application in the Azure Active Directory admin center or by using
Microsoft Graph.
1. Open a browser and navigate to the Azure Active Directory admin center and
login using a personal account (aka: Microsoft Account) or Work or School
Account.
2. Select Azure Active Directory in the left-hand navigation, then select App
registrations under Manage.
3. Select New registration. On the Register an application page, set the values as
follows.
4. Choose Register. On the next page, copy the values of the Application (client) ID
and Directory (tenant) ID and save them, you will need them later.
2. Locate the requiredResourceAccess property in the manifest, and add the following
inside the square brackets ( [] ):
JSON
{
"resourceAppId": "00000002-0000-0ff1-ce00-000000000000",
"resourceAccess": [
"id": "3b5f3d61-589b-4a3c-a359-5dd4b5ee5bd5",
"type": "Scope"
3. Select Save.
2. Locate the requiredResourceAccess property in the manifest, and add the following
inside the square brackets ( [] ):
JSON
"resourceAppId": "00000002-0000-0ff1-ce00-000000000000",
"resourceAccess": [
"id": "dc890d15-9560-4a4c-9b7f-a736ec74ec40",
"type": "Role"
3. Select Save.
5. Select Grant admin consent for org and accept the consent dialog.
7. Select New client secret, enter a short description and select Add.
8. Copy the Value of the newly added client secret and save it, you will need it later.
ClientId = ConfigurationManager.AppSettings["appId"],
TenantId = ConfigurationManager.AppSettings["tenantId"]
};
.CreateWithApplicationOptions(pcaOptions).Build();
.Create(ConfigurationManager.AppSettings["appId"])
.WithClientSecret(ConfigurationManager.AppSettings["clientSecret"])
.WithTenantId(ConfigurationManager.AppSettings["tenantId"])
.Build();
C#
To use application permissions, you will also need to explicitly impersonate a mailbox
that you would like to access.
C#
ewsClient.ImpersonatedUserId = new
ImpersonatedUserId(ConnectingIdType.SmtpAddress,
"[email protected]");
Code samples
Delegated authentication
The following is the complete code sample that demonstrates making an OAuth-
authenticated EWS request using delegated authentication.
C#
using Microsoft.Exchange.WebServices.Data;
using Microsoft.Identity.Client;
using System;
using System.Configuration;
namespace EwsOAuth
class Program
ClientId = ConfigurationManager.AppSettings["appId"],
TenantId = ConfigurationManager.AppSettings["tenantId"]
};
.CreateWithApplicationOptions(pcaOptions).Build();
try
ewsClient.Url = new
Uri("https://outlook.office365.com/EWS/Exchange.asmx");
ewsClient.Credentials = new
OAuthCredentials(authResult.AccessToken);
var folders =
ewsClient.FindFolders(WellKnownFolderName.MsgFolderRoot, new
FolderView(10));
Console.WriteLine($"Folder: {folder.DisplayName}");
Console.WriteLine($"Error: {ex}");
if (System.Diagnostics.Debugger.IsAttached)
Console.ReadKey();
App-only authentication
The following is the complete code sample that demonstrates making an OAuth-
authenticated EWS request using app-only authentication.
7 Note
When using impersonation you must always use the X-AnchorMailbox request
header, which should be set to the SMTP address of the impersonated mailbox.
C#
using Microsoft.Exchange.WebServices.Data;
using Microsoft.Identity.Client;
using System;
using System.Configuration;
namespace EwsOAuth
class Program
.Create(ConfigurationManager.AppSettings["appId"])
.WithClientSecret(ConfigurationManager.AppSettings["clientSecret"])
.WithTenantId(ConfigurationManager.AppSettings["tenantId"])
.Build();
try
.ExecuteAsync();
ewsClient.Url = new
Uri("https://outlook.office365.com/EWS/Exchange.asmx");
ewsClient.Credentials = new
OAuthCredentials(authResult.AccessToken);
ewsClient.ImpersonatedUserId =
new ImpersonatedUserId(ConnectingIdType.SmtpAddress,
"[email protected]");
ewsClient.HttpHeaders.Add("X-AnchorMailbox",
"[email protected]");
var folders =
ewsClient.FindFolders(WellKnownFolderName.MsgFolderRoot, new
FolderView(10));
Console.WriteLine($"Folder: {folder.DisplayName}");
Console.WriteLine($"Error: {ex}");
if (System.Diagnostics.Debugger.IsAttached)
Console.ReadKey();
The sample code in both cases requires an App.config file with the following entries:
XML
<configuration>
<startup>
</startup>
<appSettings>
<!-- The application's client secret from your app registration. Needed
for application permission access -->
</appSettings>
</configuration>
See also
Authentication and EWS in Exchange
What to do with EWS Managed API PowerShell scripts that use Basic
Authentication
Autodiscover for Exchange
Article • 09/14/2022 • 5 minutes to read
The Exchange Autodiscover service provides an easy way for your client application to
configure itself with minimal user input. Most users know their email address and
password, and with those two pieces of information, you can retrieve all the other
details you need to get up and running. For Exchange Web Services (EWS) clients,
Autodiscover is typically used to find the EWS endpoint URL, but Autodiscover can also
provide information to configure clients that use other protocols. Autodiscover works
for client applications that are inside or outside firewalls and will work in resource forest
and multiple forest scenarios.
Active For domain-joined clients, this is the first place to look. Exchange publishes service
Directory connection point (SCP) objects in AD DS, which allows Autodiscover requests to be
Domain routed to servers based on Active Directory sites. The results of an SCP lookup
Services should be at the top of your candidate list.
(AD DS)
NOTE: SCP lookup isn't available for clients that are not joined to a domain or that
do not have access to Active Directory servers. In this case, you should skip SCP
lookup.
The user's Autodiscover defines two standard endpoint URL forms that are derived from the
email domain portion of the user's email address:
address "https://" + domain + "/autodiscover/autodiscover" + *fileExtension*
domain "https://autodiscover." + domain + "/autodiscover/autodiscover" +
*fileExtension*
The value of fileExtension depends on which Autodiscover access method you are
using, SOAP or POX . The SOAP service uses a ".svc" file extension; POX uses
".xml".
That the SSL certificate presented by the server is valid and from a trusted
authority.
7 Note
These are just basic security suggestions. Whenever you are working with
authentication, make sure that your code meets the security requirements of your
organization.
The type of request you send depends on how you are accessing the Autodiscover
service.
The POX Autodiscover service An HTTP POST with an Autodiscover request body .
The first thing to try is to send an unauthenticated GET request to an endpoint derived
from the user's email address. The format of that endpoint is "http://autodiscover." +
domain + "/autodiscover/autodiscover.xml". Note that this is NOT an SSL endpoint. If
the server returns a 302 redirect response, you can then attempt to resend the
Autodiscover request to the endpoint URL in the Location header of the response.
EWS Managed Implements Limited to the user settings that are available in the
API
the Microsoft.Exchange.WebServices.Autodiscover.UserSettingName
Autodiscover enumeration.
process for
you.
Only available for .NET Framework applications.
Uses both
the SOAP
and POX
Autodiscover
services.
Works with
Exchange
Online,
Exchange
Online as
part of Office
365, or a
version of
Exchange
starting with
Exchange
2007 SP1.
Easy to use.
Allows you
to request
just the
settings you
are
interested in.
Option Pros Cons
Supported in
Exchange
Online and
all versions
of Exchange
starting with
Exchange
2007 SP1.
In this section
Find Autodiscover endpoints by using SCP lookup in Exchange
See also
Start using web services in Exchange
Develop web service clients for Exchange
Find Autodiscover endpoints by using
SCP lookup in Exchange
Article • 11/18/2020 • 8 minutes to read
Find out how to locate Autodiscover SCP objects in Active Directory Domain Services
(AD DS) and use them to find Autodiscover endpoint URLs to use with the Exchange
Autodiscover service.
A client computer that is joined to the domain that the Exchange server is installed
in.
Also, before you begin, you'll want to be familiar some basic concepts. The following are
some resources that you'll find helpful.
Table 1. Related articles for finding Autodiscover endpoints from SCP objects
Publishing with Service Connection How SCP objects are used to publish service-specific
Points
data.
SCP pointers — These contain information that points to specific LDAP servers that
should be used to locate Autodiscover SCP objects for the user's domain. SCP
pointers are stamped with the following GUID: 67661d7F-8FC4-4fa7-BFAC-
E1D7794C1F68.
SCP URLs — These contain URLs for Autodiscover endpoints. SCP URLs are
stamped with the following GUID: 77378F46-2C66-4aa9-A6A6-3E7A48B19596.
2. Search for SCP objects in the configuration naming context that have either the
SCP pointer GUID or the SCP URL GUID in the keywords property.
3. Check the SCP objects you found for an SCP pointer that is scoped to the user's
domain by checking the keywords property for an entry equal to "Domain=
<domain>" . For example, if the user's email address is [email protected], you
would look for an SCP pointer with an entry in the keywords property that is equal
to "Domain=contoso.com" . If a matching SCP pointer is found, discard the set of SCP
objects and start over at step 1 using the value of the serviceBindingInformation
property as the server to connect to for the Root DSE entry.
4. If you don't find any SCP pointers scoped to the user's domain, check for any SCP
pointers that aren't scoped to any domain, and save the value of the
serviceBindingInformation property as a "fallback" server, in case the current
server doesn't give you any results.
5. If you didn't find any SCP pointers scoped to the domain, you're ready to move on
to the next step: generating a prioritized list of Autodiscover endpoints from your
results.
2. Check the keywords property on each SCP URL in the set of SCP objects you
found, and assign a priority to the URL based on the following rules:
If the keywords property does not contain an entry with a value that starts with
"Site=" , assign the URL a priority of 2.
C#
using System;
using System.Collections.Generic;
using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
namespace ScpLookup
// This sample is for demonstration purposes only. Before you run this
sample, make sure
class Program
if (string.IsNullOrEmpty(ldapServer))
rootDSEPath = "LDAP://RootDSE";
else
try
string configPath =
rootDSE.Properties["configurationNamingContext"].Value as string;
// Set the search filter to find SCP URLs and SCP pointers.
configSearch.Filter = "(&
(objectClass=serviceConnectionPoint)" +
configSearch.PropertiesToLoad.Add("keywords");
configSearch.PropertiesToLoad.Add("serviceBindingInformation");
scpEntries = configSearch.FindAll();
Console.WriteLine(ex.ToString());
return null;
ResultPropertyValueCollection entryKeywords =
scpEntry.Properties["keywords"];
if (CollectionContainsExactValue(entryKeywords,
ScpPtrGuidString))
string ptrLdapPath =
scpEntry.Properties["serviceBindingInformation"][0] as string;
if (CollectionContainsExactValue(entryKeywords,
"Domain=" + domain))
else
if (entryKeywords.Count == 1 &&
string.IsNullOrEmpty(fallBackLdapPath))
fallBackLdapPath = ptrLdapPath;
try
ActiveDirectorySite site =
ActiveDirectorySite.GetComputerSite();
computerSiteName = site.Name;
Console.WriteLine(ex.ToString());
if (!string.IsNullOrEmpty(computerSiteName))
{
ResultPropertyValueCollection entryKeywords =
scpEntry.Properties["keywords"];
if (CollectionContainsExactValue(entryKeywords,
ScpUrlGuidString))
string scpUrl =
scpEntry.Properties["serviceBindingInformation"][0] as string;
scpUrl = scpUrl.ToLower();
if (CollectionContainsExactValue(entryKeywords,
"Site=" + computerSiteName))
// Priority 1.
if (!scpUrlList.Contains(scpUrl.ToLower()))
scpUrlList.Add(scpUrl);
else
else
if (CollectionContainsPrefixValue(entryKeywords,
"Site="))
// Priority 3.
if (!priorityThreeUrls.Contains(scpUrl))
{
Console.WriteLine("Adding priority 3 SCP
URL: {0}", scpUrl);
priorityThreeUrls.Add(scpUrl);
}
else
{
Console.WriteLine("Priority 3 SCP URL
already found: {0}", scpUrl);
}
}
else
// Priority 2.
if (!priorityTwoUrls.Contains(scpUrl))
{
Console.WriteLine("Adding priority 2 SCP
URL: {0}", scpUrl);
priorityTwoUrls.Add(scpUrl);
}
else
{
Console.WriteLine("Priority 2 SCP URL
already found: {0}", scpUrl);
}
}
if (!scpUrlList.Contains(priorityTwoUrl))
scpUrlList.Add(priorityTwoUrl);
if (!scpUrlList.Contains(priorityThreeUrl))
scpUrlList.Add(priorityThreeUrl);
return scpUrlList;
if (entry != null)
return true;
return false;
if (entry != null)
if (entry.StartsWith(value))
return true;
return false;
Next steps
The next step in the Autodiscover process is to send Autodiscover requests to the URLs
that you found, starting with priority 1 URLs, then priority 2 URLs, and finally priority 3
URLs. To learn more about how to send Autodiscover requests and handle responses,
read the following articles:
See also
Autodiscover for Exchange
Setting up your EWS application
Generate a list of Autodiscover
endpoints
Article • 01/15/2020 • 3 minutes to read
The first task in the Autodiscover process is to generate a list of Autodiscover endpoints
for your application to try. These Autodiscover endpoints can come from an SCP lookup
or can be derived from the user's email address. In the end, you can end up with a large
number of endpoints. Let's take a look at how you can organize them by priority.
1. Autodiscover endpoints from SCP objects scoped to the Active Directory site that
the client computer belongs to.
2. Autodiscover endpoints from SCP objects not scoped to any Active Directory site.
After you have the results of the SCP lookup process, you can add endpoints that derive
from the user's email address. These can serve as a default set of endpoints and a
fallback in case there are no SCP results or the endpoints returned from the SCP lookup
are not sufficient.
After you compile the list of endpoint URLs that derive from both SCP lookup and the
user's email address, you might need to revise file name extensions in those URLs,
depending on whether you're using the SOAP Autodiscover web service or the POX
Autodiscover web service .
By default, the Autodiscover endpoint URLs returned from an SCP lookup are POX URLs.
However, if you are using SOAP Autodiscover, you can simply change the file name
extension from ".xml" to ".svc" and try a SOAP request.
For the derived Autodiscover endpoint URLs, the file extension is omitted. Add the
appropriate file extension for the Autodiscover web service you are using prior to trying
the URL.
The EWS application in this example prefers the SOAP Autodiscover web service, so it
changes the file name extension for the SCP results to ".svc" before sending SOAP
requests to them.
Next steps
After you generate a list of Autodiscover endpoints, try them by sending requests to
those endpoints.
See also
Autodiscover for Exchange
Find out how to use the Autodiscover service to direct your client application to the
correct Exchange server.
The Exchange Autodiscover service provides your client application with configuration
settings for email accounts that are hosted on Exchange Online, Exchange Online as part
of Office 365, or an Exchange server running a version of Exchange starting with
Exchange 2013. The Autodiscover service is a web service that provides configuration
settings. The Autodiscover service is a web service that provides Exchange server
configuration information to your client application. Client applications use
Autodiscover to determine the endpoint of the Autodiscover service for a specific
mailbox. This article explains how to follow the responses from an Exchange server to
find the correct endpoint.
For information about how to get email address configuration settings, see Get user
settings from Exchange by using Autodiscover and Get domain settings from an
Exchange server.
7 Note
The process for finding the correct endpoint is part of the request for user or
domain settings. The Autodiscover service uses a series of redirect responses to
send the client application to the correct endpoint for an email address.
You can use one of the following Exchange development technologies to access the
Autodiscover service:
EWS
If you are using EWS, you can use the following methods to retrieve user settings:
For more information about these Exchange development technologies, see Explore the
EWS Managed API, EWS, and web services in Exchange.
The EWS Managed API provides an object-based interface for retrieving user settings. If
your client application uses managed code, we recommend that you use the EWS
Managed API. The EWS Managed API interface is better optimized for a simple object
model than the typical autogenerated web service proxy.
If you are using EWS, we suggest that you use the SOAP Autodiscover service, because it
supports a richer set of features than the POX Autodiscover service.
An account that is authorized to use EWS. For information about how to configure
an account, see Controlling client application access to EWS in Exchange.
7 Note
If you are using the EWS Managed API, you must provide a certificate validation
callback in some circumstances. You may also need a certificate validation callback
with some generated proxy libraries, such as those created by Visual Studio. For
more information, see Validate a server certificate for the EWS Managed API.
Concept Description
Concept Description
If you are using the EWS Managed API, you use the
Microsoft.Exchange.WebServices.Data.ExchangeService class in the
Microsoft.Exchange.WebServices.Data namespace to manage your connection to EWS.
To use the EWS Managed API code samples in this article, you need to reference the
following namespaces in your code:
System.Net
Microsoft.Exchange.WebServices.Data.ExchangeService
C#
service.Credentials = credentials;
service.AutodiscoverUrl("[email protected]");
XML
<soap:Envelope
xmlns:a="https://schemas.microsoft.com/exchange/2010/Autodiscover"
xmlns:wsa="http://www.w3.org/2005/08/addressing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<a:RequestedServerVersion>Exchange2013</a:RequestedServerVersion>
<wsa:Action>https://schemas.microsoft.com/exchange/2010/Autodiscover/Autodis
cover/GetUserSettings</wsa:Action>
<wsa:To>https://mail.microsoft.com/autodiscover/autodiscover.svc</wsa:To>
</soap:Header>
<soap:Body>
<a:GetUserSettingsRequestMessage
xmlns:a="https://schemas.microsoft.com/exchange/2010/Autodiscover">
<a:Request>
<a:Users>
<a:User>
<a:Mailbox>[email protected]</a:Mailbox>
</a:User>
</a:Users>
<a:RequestedSettings>
<a:Setting>InternalEwsUrl</a:Setting>
<a:Setting>ExternalEwsUrl</a:Setting>
</a:RequestedSettings>
</a:Request>
</a:GetUserSettingsRequestMessage>
</soap:Body>
</soap:Envelope>
) Important
For criteria for validating a redirection response, see Autodiscover for Exchange.
If the Autodiscover service returns a redirection response, indicated by the ErrorCode
element of the UserResponse element, your client application should use the
RedirectTarget element to construct a new settings request that is sent to the server
specified in the redirection response. The following example shows a redirection
response from the server.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/"
xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action
s:mustUnderstand="1">https://schemas.microsoft.com/exchange/2010/
Autodiscover/Autodiscover/GetUserSettingsResponse</a:Action>
<h:ServerVersionInfo
xmlns:h="https://schemas.microsoft.com/exchange/2010/Autodiscover"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<h:MajorVersion>15</h:MajorVersion>
<h:MinorVersion>0</h:MinorVersion>
<h:MajorBuildNumber>682</h:MajorBuildNumber>
<h:MinorBuildNumber>1</h:MinorBuildNumber>
<h:Version>Exchange2013</h:Version>
</h:ServerVersionInfo>
</s:Header>
<s:Body>
<GetUserSettingsResponseMessage
xmlns="https://schemas.microsoft.com/exchange/2010/Autodiscover">
<Response xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<ErrorCode>NoError</ErrorCode>
<ErrorMessage />
<UserResponses>
<UserResponse>
<ErrorCode>RedirectAddress</ErrorCode>
<ErrorMessage>Redirection address.</ErrorMessage>
<RedirectTarget>[email protected]</RedirectTarget>
<UserSettingErrors />
<UserSettings />
</UserResponse>
</UserResponses>
</Response>
</GetUserSettingsResponseMessage>
</s:Body>
</s:Envelope>
After a redirection, the client uses the redirection URL to prepare another request. The
following code shows an example of the request that you create from the redirection
response.
XML
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope
xmlns:a="https://schemas.microsoft.com/exchange/2010/Autodiscover"
xmlns:wsa="http://www.w3.org/2005/08/addressing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<a:RequestedServerVersion>Exchange2013</a:RequestedServerVersion>
<wsa:Action>https://schemas.microsoft.com/exchange/2010/
Autodiscover/Autodiscover/GetUserSettings</wsa:Action>
<wsa:To>https://autodiscover.exchange.microsoft.com/autodiscover/autodiscove
r.svc</wsa:To>
</soap:Header>
<soap:Body>
<a:GetUserSettingsRequestMessage
xmlns:a="https://schemas.microsoft.com/exchange/2010/Autodiscover">
<a:Request>
<a:Users>
<a:User>
<a:Mailbox>[email protected]</a:Mailbox>
</a:User>
</a:Users>
<a:RequestedSettings>
<a:Setting>InternalEwsUrl</a:Setting>
<a:Setting>ExternalEwsUrl</a:Setting>
</a:RequestedSettings>
</a:Request>
</a:GetUserSettingsRequestMessage>
</soap:Body>
</soap:Envelope>
When the client application has been directed to the correct endpoint for the
Autodiscover service, the server will send a response with the ErrorCode element of
the UserResponse element set to NoError and containing the requested user settings.
Only the requested user settings, InternalEwsUrl and ExternalEwsUrl, are returned. The
following example shows the response from the server.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/"
xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action
s:mustUnderstand="1">https://schemas.microsoft.com/exchange/2010/
Autodiscover/Autodiscover/GetUserSettingsResponse</a:Action>
<h:ServerVersionInfo
xmlns:h="https://schemas.microsoft.com/exchange/2010/Autodiscover"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<h:MajorVersion>15</h:MajorVersion>
<h:MinorVersion>0</h:MinorVersion>
<h:MajorBuildNumber>160</h:MajorBuildNumber>
<h:MinorBuildNumber>4</h:MinorBuildNumber>
<h:Version>Exchange2013</h:Version>
</h:ServerVersionInfo>
</s:Header>
<s:Body>
<GetUserSettingsResponseMessage
xmlns="https://schemas.microsoft.com/exchange/2010/Autodiscover">
<Response xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<ErrorCode>NoError</ErrorCode>
<ErrorMessage />
<UserResponses>
<UserResponse>
<ErrorCode>NoError</ErrorCode>
<ErrorMessage>No error.</ErrorMessage>
<UserSettingErrors />
<UserSettings>
<UserSetting i:type="StringSetting">
<Name>InternalEwsUrl</Name>
<Value>https://server.Contoso.com/ews/exchange.asmx</Value>
</UserSetting>
<UserSetting i:type="StringSetting">
<Name>ExternalEwsUrl</Name>
<Value>https://server.Contoso.com/ews/exchange.asmx</Value>
</UserSetting>
</UserSettings>
</UserResponse>
</UserResponses>
</Response>
</GetUserSettingsResponseMessage>
</s:Body>
</s:Envelope>
Next steps
Finding the endpoint by following the Autodiscover process returns the requested
domain or user settings. For information about making a request for specific settings,
see the following articles:
See also
Setting up your EWS application
Autodiscover for Exchange
Autodiscover web service reference for Exchange
EWS reference for Exchange
Get user settings from Exchange by
using Autodiscover
Article • 01/15/2020 • 5 minutes to read
Learn how to get user configuration settings from an Exchange server by using
Autodiscover.
You can use one of the following development technologies to retrieve user settings
from the Autodiscover service:
The EWS Managed API provides an object-based interface for retrieving user settings. If
your client application uses managed code, we recommend that you use the EWS
Managed API. If you are using the EWS Managed API, determine whether the settings
that you need are available in the
Microsoft.Exchange.WebServices.Autodiscover.UserSettingName enumeration. If they
aren't, you might want to use the SOAP or POX Autodiscover services.
If you are using a web service, we suggest that you use the SOAP Autodiscover service,
because it supports a richer set of features than the POX Autodiscover service. If the
SOAP Autodiscover service isn't available, the POX Autodiscover service is a good
alternative.
If you are using the EWS Managed API or the POX-based Autodiscover service,
Exchange Online, Exchange Online as part of Office 365, or a server that is running
a version of Exchange starting with Exchange 2007 SP1.
If you are using the SOAP-based Autodiscover service, Exchange Online or a
version of Exchange starting with Exchange 2010.
7 Note
If you are using the EWS Managed API, you will need to provide a certificate
validation callback method in some circumstances. You might also need a
certificate validation callback method with some generated proxy libraries, such as
those created by Visual Studio.
C#
using System;
using System.Net;
using Microsoft.Exchange.WebServices.Autodiscover;
AutodiscoverService service,
string emailAddress,
int maxHops,
service.Url = url;
if (response.ErrorCode == AutodiscoverErrorCode.RedirectAddress)
else
return response;
You can parse the collection returned to access each key/value pair in the user settings
array. The following example shows how to parse through each returned element and
display the name and value of each key/value pair.
C#
// Display each retrieved value. The settings are part of a key/value pair.
Alternatively, you can obtain the value of a specific setting. In the following example, the
UserDisplayName setting is to be displayed.
C#
Console.WriteLine(userresponse.Settings[UserSettingName.UserDisplayName]);
To get user settings, use the GetUserSettings operation (SOAP) . The requested
settings are returned as UserSetting elements .
The following example shows a SOAP Autodiscover request to get user settings from the
server.
XML
<soap:Envelope
xmlns:a="https://schemas.microsoft.com/exchange/2010/Autodiscover"
xmlns:wsa="http://www.w3.org/2005/08/addressing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<a:RequestedServerVersion>Exchange2013</a:RequestedServerVersion>
<wsa:Action>https://schemas.microsoft.com/exchange/2010/Autodiscover/Autodis
cover/GetUserSettings</wsa:Action>
<wsa:To>https://autodiscover.exchange.microsoft.com/autodiscover/autodiscove
r.svc</wsa:To>
</soap:Header>
<soap:Body>
<a:GetUserSettingsRequestMessage
xmlns:a="https://schemas.microsoft.com/exchange/2010/Autodiscover">
<a:Request>
<a:Users>
<a:User>
<a:Mailbox>[email protected]</a:Mailbox>
</a:User>
</a:Users>
<a:RequestedSettings>
<a:Setting>UserDisplayName</a:Setting>
<a:Setting>UserDN</a:Setting>
<a:Setting>UserDeploymentId</a:Setting>
<a:Setting>InternalMailboxServer</a:Setting>
<a:Setting>MailboxDN</a:Setting>
<a:Setting>PublicFolderServer</a:Setting>
<a:Setting>ActiveDirectoryServer</a:Setting>
<a:Setting>ExternalMailboxServer</a:Setting>
<a:Setting>EcpDeliveryReportUrlFragment</a:Setting>
<a:Setting>EcpPublishingUrlFragment</a:Setting>
<a:Setting>EcpTextMessagingUrlFragment</a:Setting>
<a:Setting>ExternalEwsUrl</a:Setting>
<a:Setting>CasVersion</a:Setting>
<a:Setting>EwsSupportedSchemas</a:Setting>
<a:Setting>GroupingInformation</a:Setting>
</a:RequestedSettings>
</a:Request>
</a:GetUserSettingsRequestMessage>
</soap:Body>
</soap:Envelope>
The following example shows the SOAP response that is returned by the server after it
parses the request from the client. The response contains only the settings that are
requested, if they exist.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/"
xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action
s:mustUnderstand="1">https://schemas.microsoft.com/exchange/2010/
Autodiscover/Autodiscover/GetUserSettingsResponse</a:Action>
<h:ServerVersionInfo
xmlns:h="https://schemas.microsoft.com/exchange/2010/Autodiscover"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<h:MajorVersion>15</h:MajorVersion>
<h:MinorVersion>0</h:MinorVersion>
<h:MajorBuildNumber>160</h:MajorBuildNumber>
<h:MinorBuildNumber>4</h:MinorBuildNumber>
<h:Version>Exchange2013</h:Version>
</h:ServerVersionInfo>
</s:Header>
<s:Body>
<GetUserSettingsResponseMessage
xmlns="https://schemas.microsoft.com/exchange/2010/Autodiscover">
<Response xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<ErrorCode>NoError</ErrorCode>
<ErrorMessage />
<UserResponses>
<UserResponse>
<ErrorCode>NoError</ErrorCode>
<ErrorMessage>No error.</ErrorMessage>
<UserSettingErrors />
<UserSettings>
<UserSetting i:type="StringSetting">
<Name>UserDisplayName</Name>
<Value>Mara Whitley</Value>
</UserSetting>
<UserSetting i:type="StringSetting">
<Name>UserDN</Name>
</UserSetting>
<UserSetting i:type="StringSetting">
<Name>UserDeploymentId</Name>
<Value>649d50b8-a1ce-4bac-8ace-2321 e463f701</Value>
</UserSetting>
<UserSetting i:type="StringSetting">
<Name>CasVersion</Name>
<Value>15.01.0160.004</Value>
</UserSetting>
<UserSetting i:type="StringSetting">
<Name>EwsSupportedSchemas</Name>
</UserSetting>
<UserSetting i:type="StringSetting">
<Name>InternalMailboxServer</Name>
<Value>mail.contoso.com</Value>
</UserSetting>
<UserSetting i:type="StringSetting">
<Name>ActiveDirectoryServer</Name>
<Value>dc.contoso.com</Value>
</UserSetting>
<UserSetting i:type="StringSetting">
<Name>MailboxDN</Name>
(FYDIBOHF23SPDLT)/cn=Configuration/cn=Servers/cn=mail.contoso.com/cn=Contoso
Private MDB</Value>
</UserSetting>
<UserSetting i:type="StringSetting">
<Name>PublicFolderServer</Name>
<Value>public.contoso.com</Value>
</UserSetting>
<UserSetting i:type="StringSetting">
<Name>EcpDeliveryReportUrlFragment</Name>
<Value>PersonalSettings/DeliveryReport.aspx?
exsvurl=1&amp;IsOWA=&lt;IsOWA&gt;&amp;MsgID=&lt;MsgID&am
p;gt;&amp;Mbx=&lt;Mbx&gt;</Value>
</UserSetting>
<UserSetting i:type="StringSetting">
<Name>EcpTextMessagingUrlFragment</Name>
<Value>?p=sms/textmessaging.slab&amp;exsvurl=1</Value>
</UserSetting>
<UserSetting i:type="StringSetting">
<Name>EcpPublishingUrlFragment</Name>
<Value>customize/calendarpublishing.slab?
exsvurl=1&amp;FldID=&lt;FldID&gt;</Value>
</UserSetting>
<UserSetting i:type="StringSetting">
<Name>ExternalEwsUrl</Name>
<Value>https://mail.contoso.com/EWS/Exchange.asmx</Value>
</UserSetting>
<UserSetting i:type="StringSetting">
<Name>ExternalMailboxServer</Name>
<Value>mail.contoso.com</Value>
</UserSetting>
<UserSetting i:type="StringSetting">
<Name>GroupingInformation</Name>
<Value>CONTOSO-1</Value>
</UserSetting>
</UserSettings>
</UserResponse>
</UserResponses>
</Response>
</GetUserSettingsResponseMessage>
</s:Body>
</s:Envelope
The following example shows a POX Autodiscover request to get user settings from the
server. The following XML is sent to the server via an HTTP POST.
XML
<Autodiscover
xmlns="https://schemas.microsoft.com/exchange/autodiscover/outlook/requestsc
hema/2006">
<Request>
<EMailAddress>[email protected]</EMailAddress>
<AcceptableResponseSchema>https://schemas.microsoft.com/exchange/autodiscove
r/outlook/responseschema/2006a</AcceptableResponseSchema>
</Request>
</Autodiscover>
The following example shows the POX response that is returned by the server.
XML
<Autodiscover
xmlns="https://schemas.microsoft.com/exchange/autodiscover/responseschema/20
06">
<Response
xmlns="https://schemas.microsoft.com/exchange/autodiscover/outlook/responses
chema/2006a">
<User>
<DisplayName>Mara Whitley</DisplayName>
<AutoDiscoverSMTPAddress>[email protected]</AutoDiscoverSMTPAddress>
<DeploymentId>50817eff-b925-4578-a0db-13bfc635e7a5</DeploymentId>
</User>
<Account>
<AccountType>email</AccountType>
<Action>settings</Action>
<MicrosoftOnline>False</MicrosoftOnline>
<Protocol>
<Type>EXCH</Type>
<Server>[email protected]</Server>
<ServerVersion>73C08204</ServerVersion>
<PublicFolderServer>public.contoso.com</PublicFolderServer>
<AD>dc.contoso.com</AD>
<ASUrl>https://mail.contoso.com/EWS/Exchange.asmx</ASUrl>
<EwsUrl>https://mail.contoso.com/EWS/Exchange.asmx</EwsUrl>
<EmwsUrl>https://mail.contoso.com/EWS/Exchange.asmx</EmwsUrl>
<EcpUrl>https://mail.contoso.com/ecp/</EcpUrl>
<EcpUrl-um>?
rfr=olk&amp;p=customize/voicemail.aspx&amp;exsvurl=1&amp;realm=c
ontoso.com</EcpUrl-um>
<EcpUrl-aggr>?
rfr=olk&amp;p=personalsettings/EmailSubscriptions.slab&amp;exsvurl=1
&amp;realm=contoso.com</EcpUrl-aggr>
<EcpUrl-mt>PersonalSettings/DeliveryReport.aspx?
rfr=olk&amp;exsvurl=1&amp;IsOWA=&lt;IsOWA&gt;&amp;MsgID=
&lt;MsgID&gt;&amp;Mbx=&lt;Mbx&gt;&amp;realm=contoso.
com</EcpUrl-mt>
<EcpUrl-ret>?
rfr=olk&amp;p=organize/retentionpolicytags.slab&amp;exsvurl=1&am
p;realm=contoso.com</EcpUrl-ret>
<EcpUrl-sms>?
rfr=olk&amp;p=sms/textmessaging.slab&amp;exsvurl=1&amp;realm=con
toso.com</EcpUrl-sms>
<EcpUrl-publish>customize/calendarpublishing.slab?
rfr=olk&amp;exsvurl=1&amp;FldID=&lt;FldID&gt;&amp;realm=
contoso.com</EcpUrl-publish>
<EcpUrl-photo>PersonalSettings/EditAccount.aspx?
rfr=olk&amp;chgPhoto=1&amp;exsvurl=1&amp;realm=contoso.com</EcpU
rl-photo>
<EcpUrl-tm>?
rfr=olk&amp;ftr=TeamMailbox&amp;exsvurl=1&amp;realm=contoso.com<
/EcpUrl-tm>
<EcpUrl-tmCreating>?
rfr=olk&amp;ftr=TeamMailboxCreating&amp;SPUrl=&lt;SPUrl&gt;&
amp;amp;Title=&lt;Title&gt;&amp;SPTMAppUrl=&lt;SPTMAppUrl&am
p;gt;&amp;exsvurl=1&amp;realm=contoso.com</EcpUrl-tmCreating>
<EcpUrl-tmEditing>?
rfr=olk&amp;ftr=TeamMailboxEditing&amp;Id=&lt;Id&gt;&amp
;exsvurl=1&amp;realm=contoso.com</EcpUrl-tmEditing>
<EcpUrl-extinstall>Extension/InstalledExtensions.slab?
rfr=olk&amp;exsvurl=1&amp;realm=contoso.com</EcpUrl-extinstall>
<OOFUrl>https://mail.contoso.com/EWS/Exchange.asmx</OOFUrl>
<UMUrl>https://mail.contoso.com/EWS/UM2007Legacy.asmx</UMUrl>
<OABUrl>https://mail.contoso.com/OAB/c21c7bc2-53b3-4ddc-ad89-
1219b486c37c/</OABUrl>
<ServerExclusiveConnect>off</ServerExclusiveConnect>
</Protocol>
<Protocol>
<Type>EXPR</Type>
<Server>mail.contoso.com</Server>
<SSL>Off</SSL>
<AuthPackage>Ntlm</AuthPackage>
<ServerExclusiveConnect>on</ServerExclusiveConnect>
<CertPrincipalName>None</CertPrincipalName>
</Protocol>
<Protocol>
<Type>WEB</Type>
<Internal>
<OWAUrl AuthenticationMethod="Basic,
Fba">https://mail.contoso.com/owa/</OWAUrl>
<Protocol>
<Type>EXCH</Type>
<ASUrl>https://mail.contoso.com/EWS/Exchange.asmx</ASUrl>
</Protocol>
</Internal>
</Protocol>
</Account>
</Response>
</Autodiscover>
Next steps
After you've retrieved the necessary configuration details for your user from the server,
you are ready to communicate with Exchange to do the things your application needs to
do. What you do next depends on how you communicate with Exchange and what you
want to accomplish. If you need some inspiration, and you're using EWS, you might
explore the Exchange 101 code samples for some ideas.
See also
Autodiscover for Exchange
Learn how to get domain settings from an Exchange server by using the Autodiscover
service.
You can retrieve configuration information for an email domain by using the
Autodiscover service. The Autodiscover service provides your application with a process
for connecting to the correct service endpoint for a specific domain.
You can use one of the following development technologies to access the Autodiscover
service:
EWS
If you are using EWS, you can use the following methods to retrieve user settings:
For more information about these methods, see Autodiscover for Exchange.
The EWS Managed API provides an object-based interface for retrieving user settings. If
your client application uses managed code, we recommend that you use the EWS
Managed API. The EWS Managed API interface is better optimized for a simple object
model than the typical autogenerated web service proxy.
If you are using EWS, we suggest that you use the SOAP Autodiscover service, because it
supports a richer set of features than the POX Autodiscover service.
The Autodiscover service returns only the requested configuration settings. The
following table lists the domain configuration settings that the Autodiscover service can
return.
ExternalEwsVersion The version of the Exchange server that hosts the EWS URL.
An account that is authorized to use EWS. For information about how to configure
an account, see Controlling client application access to EWS in Exchange.
7 Note
If you are using the EWS Managed API, you must provide a certificate validation
callback in some circumstances. You may also need a certificate validation callback
with some generated proxy libraries, such as those created by Visual Studio. For
more information, see Validate a server certificate for the EWS Managed API.
Concept Description
Use Autodiscover to find Describes the process used by the Autodiscover service to redirect
connection points
your client application to the correct service endpoint.
If you are using the EWS Managed API, you use the
Microsoft.Exchange.WebServices.Data.ExchangeService class in the
Microsoft.Exchange.WebServices.Data namespace to manage your connection to EWS.
The code examples in this section assume that you reference the following namespaces
in your code:
System.Net
Microsoft.Exchange.WebServices.Data.ExchangeService
C#
// Submit a request and get the settings. The response contains only the
GetDomainSettingsResponse domainresponse =
autodiscoverService.GetDomainSettings(
"domain",
ExchangeVersion.Exchang2013,
DomainSettingName.ExternalEwsUrl,
DomainSettingName.ExternalEwsVersion);
You can parse the collection returned to access each key/value pair. The following
example shows how to parse through each returned element and display the name and
value of each key/value pair.
C#
// Display each retrieved value. The settings are part of a key/value pair.
Alternatively, you can obtain the value of a specific setting. In the following example, the
ExternalEwsUrl setting is to be displayed.
C#
Console.WriteLine(domainresponse.Settings[DomainSettingName.ExternalEwsUrl])
;
XML
<soap:Envelope
xmlns:a="https://schemas.microsoft.com/exchange/2010/Autodiscover"
xmlns:wsa="http://www.w3.org/2005/08/addressing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<a:RequestedServerVersion>Exchange2013</a:RequestedServerVersion>
<wsa:Action>https://schemas.microsoft.com/exchange/2010/Autodiscover/Autodis
cover/GetDomainSettings</wsa:Action>
<wsa:To>https://autodiscover.exchange.microsoft.com/autodiscover/autodiscove
r.svc</wsa:To>
</soap:Header>
<soap:Body>
<a:GetDomainSettingsRequestMessage
xmlns:a="https://schemas.microsoft.com/exchange/2010/Autodiscover">
<a:Request>
<a:Domains>
<a:Domain>domain</a:Domain>
</a:Domains>
<a:RequestedSettings>
<a:Setting>ExternalEwsUrl</a:Setting>
<a:Setting>ExternalEwsVersion</a:Setting>
</a:RequestedSettings>
<a:RequestedVersion>Exchange2013</a:RequestedVersion>
</a:Request>
</a:GetDomainSettingsRequestMessage>
</soap:Body>
</soap:Envelope>
The following example shows the XML response that is returned by the server after it
parses the request from the client.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/"
xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action
s:mustUnderstand="1">https://schemas.microsoft.com/exchange/2010/
Autodiscover/Autodiscover/GetDomainSettingsResponse</a:Action>
<h:ServerVersionInfo
xmlns:h="https://schemas.microsoft.com/exchange/2010/Autodiscover"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<h:MajorVersion>15</h:MajorVersion>
<h:MinorVersion>0</h:MinorVersion>
<h:MajorBuildNumber>160</h:MajorBuildNumber>
<h:MinorBuildNumber>4</h:MinorBuildNumber>
<h:Version>Exchange2013</h:Version>
</h:ServerVersionInfo>
</s:Header>
<s:Body>
<GetDomainSettingsResponseMessage
xmlns="https://schemas.microsoft.com/exchange/2010/Autodiscover">
<Response xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<ErrorCode>NoError</ErrorCode>
<ErrorMessage />
<DomainResponses>
<DomainResponse>
<ErrorCode>NoError</ErrorCode>
<ErrorMessage>No error.</ErrorMessage>
<DomainSettingErrors />
<DomainSettings>
<DomainSetting i:type="DomainStringSetting">
<Name>ExternalEwsUrl</Name>
<Value>https://failover.exchange.microsoft.com/ews/exchange.asmx</Value>
</DomainSetting>
<DomainSetting i:type="DomainStringSetting">
<Name>ExternalEwsVersion</Name>
<Value>15.00.0085.000</Value>
</DomainSetting>
</DomainSettings>
</DomainResponse>
</DomainResponses>
</Response>
</GetDomainSettingsResponseMessage>
</s:Body>
</s:Envelope>
Next steps
Domain settings provide the basic information that your client needs to connect to EWS.
You can use this information to connect to EWS, or you can retrieve additional
configuration settings for an email account from the server. For more information, see
the following article:
See also
Setting up your EWS application
Learn how and when to refresh configuration information for your Exchange connection
by using Autodiscover.
When your EWS application runs for the first time, Autodiscover provides a great way
for you to collect the information you need in order to connect to your user's Exchange
mailbox. But Autodiscover isn't just for first time use. Using Autodiscover on a regular
basis can help keep your application connected by enabling it to respond to changes in
the Exchange deployment.
Autodiscover As When you save the Autodiscover endpoint that returned a successful
endpoint long response, you do not have to repeat the process of generating a list of
as it Autodiscover endpoints and trying them until you get a successful
works response.
NOTE: The EWS Managed API does not support caching the
Autodiscover endpoint.
Setting to Valid Details
cache for…
EWS URL and One By saving the EWS URL and other related settings, you do not have to
any other week send a new Autodiscover request for each EWS request or if your
settings application restarts. However, even if an EWS URL works for your user, a
retrieved from server might be available that is more optimal.
the
Autodiscover For example, the user's mailbox might have moved to a new mailbox
response server, resulting in a new preferred EWS endpoint. We recommend that
you refresh your user settings by sending a new Autodiscover request
after one week has passed since your last Autodiscover request. This
time can be adjusted to meet the requirements of your application.
A Connection-related error occurs AND your cached information was last refreshed
over an hour ago.
If the request succeeds, compare the EWS endpoint in the response with the
cached EWS endpoint, and do the following:
If they are different, use the new EWS endpoint. If you're refreshing to recover
from an error, retry the failed request with the new endpoint.
If they are the same, continue to use the original EWS endpoint. If you're
refreshing to recover from an error, handle the error as appropriate.
If the request fails, start the Autodiscover process from the beginning. After you
get a successful response, replace the cached Autodiscover endpoint with the
Autodiscover endpoint that succeeded and continue to use the new EWS endpoint.
If you do not get a successful response, continue to use the original Autodiscover
endpoint and EWS endpoint. If you're refreshing to recover from an error, handle
the error as appropriate.
Connection-related errors
Refreshing your cached configuration information can help with some errors, but not all.
DNS or network ServiceRemoteException Any error that indicates that the server could
failure errors
not be found or could not be reached might
be resolved by trying Autodiscover.
Example:
ErrorConnectionFailed However, the following specifically indicate
that the configuration information needs to
be updated:
- ErrorConnectionFailed
- ErrorMailboxMoveInProgress
See also
Autodiscover for Exchange
Generate a list of Autodiscover endpoints
Get user settings from Exchange by using Autodiscover
Handling Autodiscover error messages
Article • 01/15/2020 • 5 minutes to read
Learn about the different types of Autodiscover errors and what to do with them.
301 Redirect Resend your request to the URI contained in the "Location" HTTP
or error response header. For details, see Handling redirect errors.
302
401 Unauthorized Because the Autodiscover process involves trying multiple potential
error URLs, you could get this on one URL only to have the next one accept
your credentials. For this reason, you shouldn't consider a single 401
error to indicate that the credentials are invalid. However, if you receive
401 errors from multiple URLs, you might want to prompt the user to
reenter their password (if possible).
Any Invalid Consider the URL that returns any other non-200 status code to be
other Autodiscover invalid, and continue trying the next URL in your list.
non- endpoint
200 error
status
Autodiscover errors
Even if you get a 200 (OK) status code after sending an Autodiscover request, that
doesn't mean that the server sent the information you need. The 200 status only means
that you have an Autodiscover response, and that response might contain an error
within the payload. The location of the error information differs depending on whether
the format is SOAP or POX.
Let's take a look at an example of a response. In this example, the ErrorCode element
under the Response element has a value of "NoError", which indicates overall success.
However, the ErrorCode element under the UserResponse element has a value of
"RedirectAddress", which indicates that an error occurred for that particular user.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/"
xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action
s:mustUnderstand="1">https://schemas.microsoft.com/exchange/2010/Autodiscove
r/Autodiscover/GetUserSettingsResponse</a:Action>
<h:ServerVersionInfo
xmlns:h="https://schemas.microsoft.com/exchange/2010/Autodiscover"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<h:MajorVersion>14</h:MajorVersion>
<h:MinorVersion>3</h:MinorVersion>
<h:MajorBuildNumber>136</h:MajorBuildNumber>
<h:MinorBuildNumber>1</h:MinorBuildNumber>
<h:Version>Exchange2010_SP2</h:Version>
</h:ServerVersionInfo>
</s:Header>
<s:Body>
<GetUserSettingsResponseMessage
xmlns="https://schemas.microsoft.com/exchange/2010/Autodiscover">
<Response xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<ErrorCode>NoError</ErrorCode>
<ErrorMessage />
<UserResponses>
<UserResponse>
<ErrorCode>RedirectAddress</ErrorCode>
<ErrorMessage>Redirection address.</ErrorMessage>
<RedirectTarget>[email protected]</RedirectTarget>
<UserSettingErrors />
<UserSettings />
</UserResponse>
</UserResponses>
</Response>
</GetUserSettingsResponseMessage>
</s:Body>
</s:Envelope>
The ErrorCode (SOAP) article contains a full list of possible errors. Most of these
indicate an unrecoverable error, but a few warrant special handling.
ErrorCode To handle…
value
RedirectAddress Restarting Autodiscover with a new email address with the email address in the
RedirectTarget (SOAP) element.
RedirectUrl Resending your request to a new URL to the URL in the RedirectTarget
element.
ServerBusy Retry this URL after a small delay. You might wait a set amount of time or
simply move this URL to the end of your list of URLs to try. If you receive this
error multiple times from a URL, you should consider the URL to be invalid.
Redirect errors are contained in the Action (POX) element. Any value of the Action
element other than "settings" indicates a redirect error.
redirectAddr Restarting Autodiscover with a new email address with the email address in the
RedirectAddr (POX) element.
redirectUrl Resending your request to a new URL to the URL in the RedirectUrl (POX)
element.
In this example, the Action element has a value of "redirectAddr", which indicates that a
new request should be sent with the new email address contained in the RedirectAddr
element.
XML
<Autodiscover
xmlns="https://schemas.microsoft.com/exchange/autodiscover/responseschema/20
06">
<Response
xmlns="https://schemas.microsoft.com/exchange/autodiscover/outlook/responses
chema/2006a">
<Account>
<Action>redirectAddr</Action>
<RedirectAddr>[email protected]</RedirectAddr>
</Account>
</Response>
</Autodiscover>
Verify that you have not received an error from this URL with the current email
address before.
If applicable to your application, inform the user of the redirection and get their
permission to follow the redirect.
Send a request to the URL and verify that the SSL certificate presented by the
server is valid.
If the URL passes validation, resend the request to this new URL.
See also
Autodiscover for Exchange
ErrorCode (SOAP)
ErrorCode (POX)
Improving performance when using
Autodiscover for Exchange
Article • 09/15/2021 • 2 minutes to read
Learn about ways to improve the performance of the Autodiscover process in your
application.
There are a lot of reasons to like Autodiscover. Configuring your application to connect
to Exchange with no user intervention is great! If you're reading this article, you
probably already know all the reasons to use and love Autodiscover, so we won't list
them here. Instead, we're going to talk about a potential downside: performance.
Autodiscover isn't inherently a slow process, but it's not inherently fast either. The
Autodiscover process involves a lot of network activity, and that introduces a lot of
potential for delays. The Autodiscover process has three phases; all three have the
potential to affect performance:
On the surface this might not seem like much. However, imagine a scenario where the
Autodiscover endpoint candidate pool is more than one or two URLs, and you don't find
a working one until the last URL in your pool. The delay can become a bit more
noticeable. So, what can you do?
Even if you are already caching, evaluate how long you cache configuration information.
The standard is to refresh Autodiscover information every 24 hours, but you might be
able to extend that time. You should test with your target environments and come up
with a "time-to-live" for your configuration that works for you.
If you're using the POX Autodiscover service, you cannot request specific properties.
See also
Autodiscover for Exchange
ExchangeService class
AutodiscoverService class
Outlook add-ins and EWS in Exchange
Article • 06/14/2022 • 4 minutes to read
Find information about Outlook add-ins and how they work with EWS in Exchange.
Outlook add-ins provide a single interface and programming model that uses web
standards to enable you to create a custom experience for your email users. You can
create mail apps that display contextual or helpful information in an HTML5 frame
hosted in Outlook; for example, a mail app can show a Bing map with an address
highlighted when an email message contains an address. Or when a user is composing a
message, a mail app can show additional information about the recipient, and insert a
standard greeting into the email at the touch of a button.
7 Note
"Outlook" in this article refers to the Outlook rich client, Outlook RT, Outlook Web
App, and OWA for Devices.
The mail apps interface is part of the JavaScript API for Office. You can use the API to
access information in Exchange to enable your mail app to:
Make EWS requests to the Exchange server that hosts the user's mailbox. A mail
app can, for example, get a list of folders so that the user can choose one to store
the message, or show all the items in a conversation, or mark an email message as
junk.
Get a token that enables a third-party service to make EWS requests on behalf of
the user, for example, to extract the attachments from an item, or to get an item
from the Exchange server for further processing.
You can use mail apps to customize the Outlook Web App experience for your users; if,
however, you want to customize the "look and feel" of Outlook Web App, see these
articles on TechNet:
Create a theme for Outlook Web App
Customize the Outlook Web App sign-in, language selection, and error pages
Your organization can install mail apps on an internal server to limit access to authorized
users, or you and other mail app developers can put mail apps on the Office Store for
sale to the general public. Anyone who is running Outlook can download, install, and
use mail apps from the marketplace.
If you want to learn more about creating mail apps, check out the Outlook add-ins
documentation or the Make an EWS request sample.
Like any other application, a mail app needs permissions to work. Your administrator
needs to:
You also need to make sure that your app requests the read/write mailbox permission in
the apps for Office permission model.
When these steps are complete, a subset of folder and item EWS operations are
available for the mail app to use.
Table 1. EWS folder and item operations that mail apps can use
CreateFolder operation
CopyItem operation
FindFolder operation
CreateItem operation
GetFolder operation
FindItem operation
UpdateFolder operation
FindConversation operation
GetConversationItems operation
GetItem operation
MarkAsJunk operation
MoveItem operation
SendItem operation
UpdateItem operation
The service callback token is an opaque token that the third-party service attaches to
the EWS request in a bearer authentication header. The token identifies the mail app
and the mailbox to help secure the EWS request. To learn how to use service callback
tokens, see the Outlook add-ins: Get attachments from an Exchange server sample.
See also
Controlling client application access to EWS in Exchange
Outlook add-ins
Set-WebServicesVirtualDirectory
Outlook add-ins: Make an EWS request
Find information about the Microsoft Graph APIs that you can use to access mail,
calendars, and contacts in Office 365, Exchange Online, or Exchange Server in hybrid
deployments.
Office 365, Exchange Online, and Exchange Server in hybrid deployments provide a new
way to work with email, calendars, and contacts. The Microsoft Graph Mail, Calendar,
and Contact REST APIs provide a powerful, easy-to-use way to access and manipulate
Exchange data. These APIs are based on open standards: OAuth version 2.0 for
authentication, and OData version 4.0 and JSON for data abstraction. This provides the
following advantages:
Because these APIs require OAuth for authentication, your application does not
have to handle or store user credentials.
OAuth makes it possible to request tightly scoped permissions to user data. For
example, you might design your application to request permission and read only a
user's calendar.
Also be sure to check out the quick starts and code samples to see these APIs in action.
See also
Microsoft Graph documentation
On-premises requirements for the REST API
License information
Article • 09/15/2021 • 2 minutes to read
Notwithstanding any other terms that may be applicable to your use of the EWS
Content (defined below), the following restrictions apply to your use of documentation,
software code or other materials made available by Microsoft from this web site that are
associated with Microsoft Exchange Web Services Managed API, version 1.1 or later, or
Exchange Web Services in Exchange Server 2010 SP1 or later versions of the Exchange
Server product, including any pre-release or finalized versions thereof (collectively, "EWS
Content"): you may use the EWS Content solely in programs developed by you that
interoperate with Microsoft Exchange Server.
EWS client design overview for
Exchange
Article • 03/04/2022 • 6 minutes to read
Learn about the design considerations for developing with EWS for Exchange.
This article provides overview information about designing an Exchange Web Services
(EWS) application. You can use this information to determine whether EWS is the right
API for your application, and if so, what type of client implementation you should use.
This article also provides best practice information for designing applications that can
target Office 365, Exchange Online, and versions of Exchange starting with Exchange
2007, in one code base, and important decision points for targeting on-premises
Exchange servers versus targeting Exchange Online.
EWS is the primary client access API for your Exchange client applications. However, in
some cases, you might consider other Exchange APIs for client application development.
For example, Exchange ActiveSync provides the following advantages over EWS:
The XML structure has been tokenized to make Exchange ActiveSync a more
compact protocol.
Exchange ActiveSync contains a policy mechanism to control client access and to
provide other robust enterprise mobile messaging solutions.
7 Note
You need a license in order to develop Exchange ActiveSync clients. To learn about
the differences between Exchange ActiveSync and EWS, see Choosing between
Exchange ActiveSync and Exchange Web Services (EWS) .
MAPI RPC over HTTP is another programmability option for Exchange client
applications. However, MAPI RPC over HTTP does not provide an intuitive interface for
communicating between clients and the server.
For more information about Exchange development technologies, see Explore the EWS
Managed API, EWS, and web services in Exchange.
The following are some of the benefits of using the EWS Managed API:
Note, however, that the EWS Managed API is not a complete solution. Some
functionality is not implemented in the EWS Managed API. Although the EWS Managed
API doesn't implement all EWS functionality, it might be the best choice for your client
application development, for the following reasons:
You might choose to use the EWS web service API instead of the EWS Managed API for
any of the following reasons:
To more, see Get started with EWS Managed API client applications.
7 Note
The EWS Managed API is now available as an open source project on GitHub .
You can use the open source library to:
Because features and feature updates are driven by the schema, we recommend that
you use the earliest common code base that targets the EWS features that you want to
implement in your client application. Many applications can target the
Exchange2007_SP1 version, because the Exchange 2007 SP1 schema contains almost all
the core Exchange functionality for working with items and folders in the Exchange
store. We recommend that you maintain code forks for each EWS schema version. The
following are the schema versions that are currently available.
XML
<xs:simpleType name="ExchangeVersionType">
<xs:restriction base="xs:string">
</xs:restriction>
</xs:simpleType>
In this section
Web service API feature availability in Exchange and the EWS Managed API
EWS schema versions in Exchange
Configuration options for EWS in Exchange
Comparing Exchange Online and Exchange on-premises client programming
EWS throttling in Exchange
Redistribution requirements for the EWS Managed API
Instrumenting client requests for EWS and REST in Exchange
See also
Start using web services in Exchange
Develop web service clients for Exchange
EWS application types
Web service API feature availability in
Exchange and the EWS Managed API
Article • 09/15/2021 • 3 minutes to read
Learn about which EWS and web service API features are available in each version of Exchange and
the EWS Managed API.
Exchange client applications often target many versions of Exchange. For this reason, you might
want to design your application such that you can turn EWS client features on and off based on the
version of Exchange that hosts your users' mailbox. This article provides information about which
service API features are available in different versions of Exchange and the EWS Managed API. Use
this information to design your application to apply broadly to customers running multiple
versions of Exchange.
For detailed information about the differences between versions of Exchange, review the EWS
schema files and the associated reference documentation .
The following table indicates which API features are available in each version of Exchange and
versions of the EWS Managed API starting with version 2.0. Because your application might target
multiple versions of Exchange, it will be helpful for you to know which versions support the
features that your client implements. You can use the Autodiscover service to discover which
version of Exchange a client targets for a user so that you can turn features on and off depending
on whether they are available to your users.
Table 1. Web service feature availability in versions of Exchange and the EWS Managed API
API feature Exchange EWS Exchange Exchange Exchange Exchange Exchange Exchange
Online Managed 2013 2010 SP2 2010 SP1 2010 2007 SP1 2007
(Office API
365)
Ambiguous X X X X X X X X
name
resolution
Apps for X X X
Outlook
management
API feature Exchange EWS Exchange Exchange Exchange Exchange Exchange Exchange
Online Managed 2013 2010 SP2 2010 SP1 2010 2007 SP1 2007
(Office API
365)
Archive mailbox X X X X X
access
Autodiscover X X X X X X X X
(POX)
Autodiscover X X X X X
(SOAP)
Automatic X X X X X X X X
replies (OOF)
Availability X X X X X X X X
Availability X X X X X X
(Rooms)
Bulk transfer X X X X
Contact groups X X X X X X
Conversation X X X X X
management
DateTime X X X X
precision
Delegate X X X X X X X
management
Distribution list X X X X X X X X
expansion
Dumpster X X X X X X
access
eDiscovery
X X X
Enhanced time X X X X X X
zones
Folder X X X X X X X
permissions
Identifier X X X X X X X
conversion
Inbox X X X X X
management
API feature Exchange EWS Exchange Exchange Exchange Exchange Exchange Exchange
Online Managed 2013 2010 SP2 2010 SP1 2010 2007 SP1 2007
(Office API
365)
Mailbox events X X X X X X X X
(pull and push)
Mailbox events X X X X X
(streaming)
Mailtips X X X X X
Password X X X X
expiration
Personas
X X
Post items X X X X X X X
Public folder X X X X X X X
access
Retention X X X
policies
Search X X X X X X
(indexed)
Search (store)
X X X X X X X X
Synchronization X X X X X X X X
Unified Contact X X
Store
Unified X X X X X X X
Messaging Web
Service
Unified X X X X X X
Messaging
(EWS-based)
User X X X X X X
configuration
objects
User photos
X X
You can find more information about the web service features that are available in different
versions of Exchange by reading about the EWS operations , the Autodiscover service , and the
ExchangeService methods .
To learn more
If you want to go deeper to understand the specific differences between Exchange versions, you
can do any of the following:
Explore the EWS schema to investigate the differences between each version of EWS in
more detail.
Download EWSEditor . You can use EWSEditor to specify different target schema versions
and submit queries based on the target schema version.
See also
EWS client design overview for Exchange
Get started with EWS Managed API client applications
What's new in EWS and other web services in Exchange
EWS schema versions in Exchange
Article • 01/15/2020 • 6 minutes to read
Learn about the EWS schema and how to design your application to work with it, as well
as the features that are available with each schema version, and how the schema relates
to the Exchange service version.
The EWS schema defines the data structures that can be sent to and returned by
Exchange. Each new version of Exchange that contains a significant change to EWS
functionality will contain a new schema. EWS and the EWS schema are both backward,
and in some cases, forward compatible - applications designed against earlier versions
of EWS will work, in most cases, with later versions of EWS, and applications that target
later versions of EWS will work if the same functionality was included in an earlier
version. This article will help you understand the role of the EWS schema, how schema
versioning works, the relationship between the schema version and the service version,
and how to design your application to work with the EWS schema.
Defines the feature set that is available to a client. A client can get the list of the
supported schema versions by using the SOAP Autodiscover service. The client can
then determine which features it can access, because each schema version
represents an EWS feature set. Each new schema released for EWS contains of the
schema entities from the previous version plus the schema definitions for any new
functionality. This way, EWS supports applications that target an earlier version of
EWS.
Provides a general description of the API contract. You can use this contract to
determine the data structures that can be sent to and received from Exchange.
C#
PropertySet props;
else
return props;
Version your requests with the earliest version of the EWS schema that supports
the functionality you want to use. This will make your client applicable to a larger
number of potential Exchange servers. This is less important if you're developing a
line-of-business application to target your organization's servers only, but is very
important if you're building an application for a wider Exchange audience.
Exchange The latest schema Includes all the features in the current version of Exchange in
Online version. addition to any new features that are added for online clients.
2013 SP1
The following features were introduced in Exchange 2013 SP1:
Exchange Exchange2013 Includes all features introduced in Exchange 2007 and Exchange
2013 2010.
Archiving
eDiscovery
Personas
Retention policies
Unified Contact Store
User photos
Exchange Exchange2010_SP2 Includes all the features introduced in Exchange 2010 SP1.
2010 SP2
The following features were introduced in Exchange 2010 SP2:
2010 SP1
The following features were introduced in Exchange 2010 SP1:
2010
The following features were introduced in the initial release
version of Exchange 2010:
2007 SP1
The following features were introduced in Exchange 2007 SP1:
Delegate management
Folder permissions
Public folders
Post items
ID conversion
Product Associated Features
version schema version
Exchange Exchange2007 The following features were introduced in the initial release
2007 version of Exchange 2007:
Full access to items, folders, and attachments (Create, Get,
Update, Delete)
Availability
Out of Office settings
Notifications
Synchronization
Name resolution
Distribution list (DL) expansion
Search
While the EWS schema defines the contract, in some scenarios, the service version is the
only way for a client to determine how it is supposed to interact with the service. Service
behavior changes that aren't reflected in the schema can only be determined by the
service version returned in all EWS responses. For example, when public folders were
redesigned in Exchange 2013, the operations that are used to move and copy public
folders changed. If you designed a client to copy public folders in Exchange 2010, you
would need to update it to use different operations to get the same result in Exchange
2013.
Before the EWS schema is updated for a new version, the current version of the schema
is forked and renamed using the following convention:
<schemaname>-<majorserverversion><servicepack>.xsd
The original file name then represents the latest schema. All new features are added to
the latest schema, with the exception of updates and fixes to the earlier versions of the
schema.
See also
EWS schema versions in Exchange
Autodiscover for Exchange
Develop web service clients for Exchange
Configuration options for EWS in
Exchange
Article • 09/15/2021 • 2 minutes to read
Find information about configuration settings that your EWS client can access, and the
configurable Exchange settings that can affect your EWS client.
Many configuration settings can affect what your EWS client application can do. These
configuration settings are either:
A client can access settings on Exchange Online, Exchange Online as part of Office 365,
and an on-premise Exchange server. All on-premise Exchange server settings are
available to Exchange administrators; however, not all of these settings are available to
Exchange Online tenant administrators. This article describes which configuration
settings clients, Exchange Server administrators, and Exchange Online tenant
administrators can access.
Table 1. Web service features that provide configuration options for EWS clients
Feature Description
Autodiscover The Autodiscover service provides your client applications with configuration
service information so that your client can automatically configure itself to communicate
with EWS.
Custom You can use one of several options to store custom configuration information in
configuration your mailbox: user configuration objects, custom items, or extended properties.
information
stored in a
mailbox
Feature Description
Delegate EWS provides CRUD operations for managing delegate access to a mailbox.
management Delegates are users who have been given permission to access another user's
mailbox.
- ExchangeService.AddDelegates
- ExchangeService.GetDelegates
- ExchangeService.UpdateDelegates
- ExchangeService.RemoveDelegates
eDiscovery eDiscovery client applications can get search configuration information that
search includes an eDiscovery search query, a list of searchable mailboxes, and the
configuration identifier of in-place mailbox holds.
Folder Folder permissions limit what a user can do in a public folder, and in the case of
permissions delegate access, what a delegate can do in another user's folder. You can use
either the Folder.Bind method or the GetFolder operation to access the
permission set of every folder, including public folders, shared private folders, or
folders to which users have delegate access.
Set-
WebServicesVirtualDirectory
Autodiscover No Get-
AutodiscoverVirtualDirectory
Set-
AutodiscoverVirtualDirectory
eDiscovery
Retention hold
See also
Get service configuration information by using EWS in Exchange
EWS client design overview for Exchange
Start using web services in Exchange
Develop web service clients for Exchange
Get service configuration information
by using EWS in Exchange
Article • 09/15/2021 • 2 minutes to read
Find out how to get service configuration information for UM, policy nudges, mail tips,
and protection rules from EWS in Exchange.
Does your EWS application work with Unified Messaging (UM), policy nudges, mail tips,
or protection rules? If so, your application will need to call the GetServiceConfiguration
operation to get the service configuration information that it needs. The
GetServiceConfiguration operation returns configuration information that is specific to
each of these EWS features.
7 Note
Mail tips A value that indicates whether mail tips are enabled.
The maximum number of recipients per request.
The maximum message size.
The large audience threshold.
A value that indicates whether the number of external recipients is shown.
A list of internal domains.
A value that indicates whether policy tips are enabled.
The large audience cap threshold for indicating whether your mail is
considered to have a large number of recipients.
C#
// XML for the GetServiceConfiguration request SOAP envelope for mail tips
configuration information.
"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-
instance\"\n" +
"
xmlns:m=\"http://schemas.microsoft.com/exchange/services/2006/messages\"\n"
+
"
xmlns:t=\"http://schemas.microsoft.com/exchange/services/2006/types\" \n" +
"
xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"\n" +
" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n" +
" <soap:Header>\n" +
" </soap:Header>\n" +
" <soap:Body>\n" +
" <m:GetServiceConfiguration>\n" +
" <m:ActingAs>\n" +
" <t:EmailAddress>[email protected]</t:EmailAddress>\n" +
" <t:RoutingType>SMTP</t:RoutingType>\n" +
" </m:ActingAs>\n" +
" <m:RequestedConfiguration>\n" +
" <m:ConfigurationName>MailTips</m:ConfigurationName>\n" +
" </m:RequestedConfiguration>\n" +
" </m:GetServiceConfiguration>\n" +
" </soap:Body>\n" +
"</soap:Envelope>";
byte[] payload =
System.Text.Encoding.UTF8.GetBytes(getServiceConfigurationRequest);
try
request.AllowAutoRedirect = false;
request.Credentials = creds;
request.Method = "POST";
request.ContentType = "text/xml";
requestStream.Write(payload, 0, payload.Length);
requestStream.Close();
if (response.StatusCode == HttpStatusCode.OK)
reader.Close();
responseStream.Close();
else
catch (WebException e)
Console.WriteLine(e.Message);
}
Next steps
After you request service configuration information, use the XmlDocument class to
load the response XML so that you can parse it. Then, depending on your scenario, you
can do one of the following:
Use the GetMailTips operation to get mail tips for client applications to display
to users.
If UM is enabled, learn about how to play mailbox items over your phone.
See also
Configuration options for EWS in Exchange
Setting up your EWS application
Develop web service clients for Exchange
Comparing Exchange Online and
Exchange on-premises client
programming
Article • 09/15/2021 • 5 minutes to read
Learn about the design considerations for creating an EWS Managed API or EWS client
application that works against Exchange Online and Exchange on-premises.
For the most part, clients and the web services in Exchange they target will work the
same way regardless of whether the target is an Exchange Online, Exchange Online as
part of Office 365, or Exchange on-premises server. There are, however, some
exceptions, and you'll want to make sure that your application can handle them. Use the
information in this article to help you design your client to target both Exchange Online
and Exchange on-premises.
SOAP Autodiscover
Exchange Online and versions of Exchange on-premises starting
with Exchange 2010
Service connection point Versions of Exchange on-premises starting with Exchange 2007
(SCP) lookup
In addition to the client configuration information, that SOAP and POX Autodiscover
also return the Exchange service version and indicate whether the service is hosted by
Exchange Online. This information is returned in different elements, depending on the
type of Autodiscover you use.
Table 2. Autodiscover elements that return service version and Exchange Online
hosting information
Autodiscover XML element that contains XML element that indicates whether the
service type service version user has an Exchange Online account
SOAP Setting (SOAP) element with Setting (SOAP) element with the
Autodiscover the CasVersion text value. UserMSOnline text value.
Autodiscover
Ensure that your client captures this information so that it can target the feature set that
is available on the Exchange server. This can be useful to determine whether your client
can expect different behavior based on whether the user's mailbox is located in an
Exchange Online or Exchange on-premises organization.
Tip
You can use the EWSRelentless tool to perform an EWS load test. You can use
this tool with a test server, the EWS protocol logs, EWS performance counters,
service events, and the EWS throttling settings to better understand how EWS
performs under load.
Throttling settings
Authentication settings
For details about the cmdlets that are available for Exchange Online, see PowerShell
cmdlets in Exchange Online . For more about cmdlets that are available for Exchange
on-premises, see Exchange 2013 cmdlets .
Authentication
Clients can authenticate with Exchange Online by using either Basic or OAuth. Versions
of Exchange on-premises starting with Exchange 2013 use NTLM by default; however,
it's possible to configure Exchange on-premises to use Basic authentication as well.
The following EWS Managed API functionality is only applicable to Exchange Online:
Basic pre-authentication
Because feature availability can change, we recommend that you check the Exchange
Online plans and Exchange Server editions to evaluate how feature availability might
affect your client. You can also design your client to check feature availability by using
the GetServiceConfiguration operation or by sending test requests for the operations
that implement the features. If the feature isn't available, the response from the server
will indicate as such.
Other considerations
You can do the following when targeting Exchange on-premises but not Exchange
Online:
Create a client that is installed on the Exchange server.
Install custom transport agents that can affect the delivery and content of
messages you create and send with EWS and other clients.
See also
EWS client design overview for Exchange
Comparing Exchange Online and Exchange Server 2013
Compare all Office 365 for business plans
EwsRelentless - EWS load generation tool
Web service API feature availability in Exchange and the EWS Managed API
EWS throttling in Exchange
EWS throttling in Exchange
Article • 02/11/2022 • 25 minutes to read
Learn about the throttling policies that affect EWS when you are using Exchange.
The article provides information about EWS throttling in Exchange Online, Exchange
Online as part of Office 365, and on-premises versions of Exchange starting with
Exchange 2010. Throttling in Exchange helps to ensure server reliability and uptime by
limiting the amount of server resources that a single user or application can consume.
Throttling is a reactive response to overuse of system resources that may affect service
reliability and functionality. Exchange constantly monitors the health of critical
infrastructure resources, such as mailbox databases. When high load factors are
detected that degrade the performance of these resources, EWS connections are
throttled proportionally based on the amount that each caller has contributed to this
high load condition. The result is that a user may be within their throttling limit and still
experience slowdowns until the health of the resource is back to operational levels.
Each client access protocol in Exchange, including EWS, has a throttling policy. When
you design applications that use EWS, it is important to account for throttling policies,
to help ensure application reliability and the health of your Exchange server. This article
identifies the different throttling policies and service limits for EWS, whether you are
targeting Exchange Online or versions of Exchange on-premises starting with Exchange
Server 2010. As applicable, this article also identifies differences in throttling policies in
different versions of Exchange.
) Important
If you are an application developer, you need to factor throttling into your application
design. Different versions of Exchange have different default values for the EWS
throttling parameters. Client and service applications that are designed to access
different versions of Exchange will need to account for these settings, whether they be
default values, custom values set by an Exchange administrator, or, as for Exchange
Online, set by default and not discoverable. Because throttling parameter values cannot
be discovered programmatically, your client design specifications should include a plan
for the application to adapt to different potential throttling limits. When you design
multi-threaded applications that will access a large number of mailboxes, or when many
clients are accessing the same mailbox, consider the limits on concurrency that the
default policy applies to Exchange.
The CPUStartPercent throttling policy can affect EWS performance when you are
running Exchange 2010. When the average CPU utilization of Exchange processes
running on the Client Access server — including, but not limited to, the EWS process —
exceeds the value specified by this policy, inbound requests will be delayed to reduce
CPU utilization. You cannot change the value of this policy, but knowing about it can
help you troubleshoot performance issues. The sampling logic the Client Access server
performs for this value is an average over a 10 second rolling window. This allows the
process to respond appropriately to quick spikes in CPU utilization. When this threshold
is exceeded, inbound connections to EWS are delayed. This delay is capped at 500
milliseconds (msecs) at a theoretical 100% CPU usage per EWS request. If a batch EWS
request to get 100 items is passed, the server will check the CPU usage 100 times (once
per item) for a maximum delay of 50 seconds. The delay time is linearly proportional to
CPU usage. At CPUStartPercent, the delay is 0 (a thread yield) and it increases linearly
up to 500 msec at 100% CPU usage. Because throttling policies apply to all Exchange
users, it's unlikely that CPU usage would exceed the CPUStartPercent limit on an
Exchange Client Access server, because individual users or applications cannot gain
enough CPU utilization to affect server operation.
The following table lists the throttling policy parameters that affect applications that use
EWS.
U Caution
Do not set throttling polices to null. This will set the policy to equal unlimited,
which indicates that a throttling policy isn't set.
Use the following cmdlets to display throttling polices for an on-premises Exchange
Server deployment:
Use the following command to show the default throttling policy for Exchange 2010.
Use the following command to show the global throttling policy (which equates to the
default throttling policy in Exchange 2010) in Exchange 2013.
Use the following command to show the throttling policy associated with a user in
Exchange 2010 or Exchange 2013. Replace the user name [email protected] with the
user name of the target user for whom you want to get throttling policy information.
PowerShell
PS C:\>Get-ThrottlingPolicyAssociation [email protected]
RunspaceId : 72153d6-9dce-2fae-8dbd-5ca5f760g2df
ObjectId : john
ThrottlingPolicyId :
Name : john
Identity : FHXB-28178dom.contoso.com/Users/john
IsValid : True
NeedsToSuppressPii : False
DistinguishedName : CN=john,CN=Users,DC=FHXB-
28178dom,DC=contoso,DC=com
Guid : 2c10dab6-de28-1937-ad8g-535832613a08
7 Note
When the ThrottlingPolicyId property is blank, the default policy is applied to the
mailbox.
You can set throttling policy on an Exchange server by using the Set-ThrottlingPolicy
and Set-ThrottlingPolicyAssociation cmdlets. You can create and remove non-default
throttling policies by using the New-ThrottlingPolicy and Remove-ThrottlingPolicy
cmdlets.
Tip
When impersonation is used, the budgets for all the throttling thresholds apply
differently depending on the version of Exchange. The budget is either calculated
against the account that is impersonated, or the service account. If your application is
multi-threaded and makes concurrent requests against multiple mailboxes, you should
consider how the throttling threshold will affect your application's performance. In
general, be aware of the following limits on service accounts when you create a service-
based application that uses impersonation to access all mailboxes:
When you use Impersonation, the service account has a separate budget for the
following policy parameters:
EWSMaxConcurrency
EWSPercentTimeInAD
EWSPercentTimeInCAS
EWSPercentTimeInMailboxRPC
EWSMaxSubscriptions
EWSFastSearchTimeoutInSeconds
EWSFindCountLimit
The EWSMaxConcurrency budget is shared for the service account and the
account being impersonated for all connections to versions of Exchange earlier
than Exchange 2010 Service Pack 2 (SP2) Update Rollup 4 (RU4). Starting with
Exchange 2010 SP2 RU4, and including Exchange Online, the service account
access uses a separate budget from the user EWSMaxConcurrency budget. For
more information about the update to the Exchange concurrent connection
throttling policy for EWS, see Description of Update Rollup 4 for Exchange Server
2010 Service Pack 2 .
For example, let's assume that EWSMaxConcurrency is equal to five. A user can
have five open pull notification connections, while an service account can have five
concurrent pull notification connections against the user's mailbox at the same
time as the user.
Exchange Charged against the calling account. Starting with Exchange 2010 SP2 RU4,
2010 SP2 the budget is charged against the target mailbox.
To determine the optimum batch size for an application, perform unit testing using
various input sets to ensure that the application does not encounter any errors in a
production environment.
Both of these types of searches can result in timeouts. When possible, use the Exchange
Search service because these searches are often targeted against mailbox indexes and
use AQS queries. The following example shows how to perform an AQS search of the
Inbox by using EWS and the Exchange Search service.
C#
FindItemsResults<Item> fiitems =
service.FindItems(WellKnownFolderName.Inbox, "subject:football", iv);
If you can't use an AQS search, avoid using overly complex search filters. Also try to
avoid creating search filters based on computed values if the query involves extended
MAPI properties. AQS search was introduced in Exchange 2010.
7 Note
The first time you run a complex Exchange store search query, it runs very slowly
and may time out. After that, the query will respond more quickly. For more
information about the backend Exchange server processes that occur during
Exchange store search queries, see Understanding the Performance Impact of
High Item Counts and Restricted Views on TechNet. Using a SearchFilter creates
a dynamic restriction that helps similar queries in the future, but because these
restrictions are dynamic in nature, they are not permanent or reliable, and are
deleted after a maximum of three days.
The EWSFindCountLimit policy parameter specifies the maximum number of items from
the results of a FindItem or FindFolder operation that can exist in memory on a Client
Access server at the same time for one user. Every item or folder that EWS processes in a
FindItem or FindFolder request is counted against the budget specified in the
EWSFindCountLimit element. When the response is sent back to the requester, the find
count charge for the current call is released. The response the server returns to a
requester when the budget is exceeded is based on the RequestServerVersion element
value and whether the requester specified paging. When the value of the
RequestServerVersion element indicates Exchange 2010 or an earlier version of
Exchange, the server sends a failure response with error code ErrorServerBusy. If the
value of the RequestServerVersion element indicates a version of Exchange starting with
Exchange 2010 SP1 or Exchange Online, and the client is using paging, EWS may return
a partial result set instead of an error. Your application should expect that EWS might
not return all items. If the value of the IncludesLastItemInRange element is false, the
application should make another FindItem or FindFolder request with the new offset
and continue until the IncludesLastItemInRange element returns true.
When you use a FindItem or FindFolder operation, it is important to use paging. The
EWS Managed API enforces the use of paging, but if you are using other methods, such
as EWS proxy objects or raw SOAP, you need to explicitly set paging. The following
example shows how to use paging in the EWS Managed API.
C#
ItemView iv = new ItemView(1000);
FindItemsResults<Item> fiFindItemResults =
service.FindItems(WellKnownFolderName.Inbox, iv);
7 Note
The default policy in Exchange limits the page size to 1000 items. Setting the page
size to a value that is greater than this number has no practical effect.
Applications should also account for the fact that the EWSFindCountLimit throttling
parameter value may result in a partial result set being returned for applications that
make concurrent requests. The following example shows how to use the MoreAvailable
property in the EWS Managed API to ensure that all results are included in a query.
C#
service.TraceEnabled = false;
Do
The EWSFindCountLimit policy parameter specifies the maximum result size a FindItem
or FindFolder operation can use on a Client Access server at the same time for one user.
If an application (or potentially multiple applications) makes two concurrent EWS
FindItem requests that return 100 items each for a specific user, the
EWSFindCountLimit charge against that specific user's budget will be 200. When the
first request returns, the budget drops to 100, and when the second request returns, the
budget drops to zero. If the same application were to make two simultaneous requests
for 1000 items, the budget value would be 2000 items, which exceeds the
EWSFindCountLimit value. If the user's budget for items drops below zero, the next
request results in an error until the user's budget recharges to one or more.
The EWSMaxConcurrency policy parameter can also be an issue for EWS notifications;
for example:
When EWS increments the connection count for the owner of the subscription
while the notification is being generated by a push subscription.
EWSPercentTimeInAD
EWSPercentTimeInCAS
EWSPercentTimeInMailboxRPC
The values specified in the PercentTimeIn policy parameters indicate the amount of
time that one thread making one request is allocated. For example, assuming a
EWSPercentTimeInCAS value of 90, if a process makes two concurrent requests that
spend 54 seconds each running code on the Client Access server, the process uses 108
seconds in a 60 second window. This represents an EWSPercentTimeInCAS parameter
value of 180 percent.
7 Note
The amount of CPU time an application may take in a 60-second period might exceed
these throttling limits; therefore, it is important to consider the volume and type of
requests that are being made. For example, a large batch of ResolveNames operations
that are made simultaneously can exceed the EWSPercentTimeInAD policy parameter
value. The policy values that are contained in the default throttling policy are designed
to allow most EWS applications to function without issue; however, when multi-
threaded high-volume applications place a large volume of requests on one particular
Client Access server, this can create problems. To avoid this, consider limiting the size of
batches that are going to execute against the server.
7 Note
In general, we recommend that you do not use EWS to send bulk email. Use an
SMTP host that specializes in bulk mail services to submit frequent large bulk email
messages.
The MessageRateLimit policy parameter specifies the number of messages per minute
that can be submitted by any Exchange client, including EWS. By default, this policy is
set to 30 messages per minute in Exchange Online (it's unlimited in Exchange Server).
For ordinary users in Exchange Online, this rate limit is generally sufficient. However,
applications that send large batches of email messages, for example as part of an
invoicing program, can run into problems. When this policy limit is exceeded, message
delivery for the mailbox is delayed. Specifically, messages will appear in the Outbox or
Drafts folder for longer periods of time when a user or application submits a larger
number of messages than the value specified by the MessageRateLimit parameter. Be
sure to consider this when you are developing a delivery tracking system, especially if
your application uses a mailbox that users connect to via Outlook. When deferred items
are stored in the Outbox or drafts folder, users might interpret that as an error.
The RecipientRateLimit policy parameter specifies the limit on the number of recipients
that a user can address in a 24-hour period. For example, if this value is set to 500, it
means that a single Exchange mailbox account can send messages to no more than 500
recipients each day. This limit applies to messages to recipients that are inside and
outside the organization. This default limit might cause problems for some line-of-
business applications that do end-of-month invoice runs and need to send messages to
more than this number of recipients. You can use external services that enable batch
processing of messages or separate on-premises outbound relay solutions to work
around this limitation.
The ForwardeeLimit policy parameter specifies the maximum number of recipients that
messages can be forwarded or redirected to by means of Inbox rules. This parameter
doesn't limit the number of messages that can be forwarded or redirected to the
recipients.
ErrorServerBusy EWSPercentTimeInMailboxRPC
Occurs when the server is
EWSPercentTimeInCAS
busy. The
EWSPercentTimeInAD BackOffMilliseconds value
returned with
ErrorServerBusy errors
indicates to the client the
amount of time it should
wait until it should resubmit
the request that caused the
response that returned this
error code.
The following table lists the HTTP status codes that are returned by throttling errors.
HTTP Description
status
code
HTTP Indicates that EWS requests are queuing with IIS. The client should delay sending
503 additional requests until a later time.
HTTP Indicates an internal server error with the ErrorServerBusy error code. This indicates that
500 the client should delay sending additional requests until a later time. The response may
contain a back off hint called BackOffMilliseconds. If present, the value of
BackOffMilliseconds should be used as the duration until the client resubmits a request.
Find out how you can redistribute the EWS Managed API assemblies with your
application.
As you design your EWS Managed API application, you'll also want to consider how you
will release it to your users.
The EWS Managed API was designed such that you can download it and distribute
it with your application that targets an Exchange server. Alternatively, your
application can download the EWS Managed API.
You can use the EWS Managed API to communicate with an Exchange server
running Exchange Online, Exchange Online as part of Office 365, or an on-
premises version of Exchange starting with Exchange Server 2007.
In versions of the EWS Managed API starting with version 2.1, you can install the
API in the Global Assembly Cache (GAC). The MSI will automatically add the DLL to
the GAC and will be accessible on per computer basis, not on a per user basis.
The license terms are included in the EWS Managed API download. Review the terms for
the authoritative information about what you can do with the EWS Managed API.
See also
EWS client design overview for Exchange
Learn about the HTTP headers in EWS and REST requests and responses that can help
you monitor and troubleshoot your Exchange application.
Has this ever happened to you? A user of your application reports an unexpected error.
You want to investigate, but you can't reproduce it. The error has disappeared for the
user, and you're left with very little actionable data. Frustrating, isn't it? Let's look at how
you can proactively prepare for this scenario and hopefully avoid frustration in the
future.
User-Agent ExchangeService.UserAgent
Set this to a unique value that
identifies your client application.
client- ExchangeService.ClientRequestId
Set this to a different unique value
request-id for every request your application
sends.
X- ExchangeService.SendClientLatencies
Used to report EWS latencies to
ClientStatistics Microsoft if your application is
accessing Exchange Online or
Exchange Online as part of Office
365.
7 Note
If you are using the EWS Managed API, there is no direct equivalent for the HTTP
headers. However, all HTTP response headers can be accessed via the
ExchangeService.HttpResponseHeaders property.
id
This header is only present if the request contains the return-client-request-id
header with a value of true.
X-FEServer The FQDN of the Client Access server that processed the request.
x-ms- This header is only applicable if OAuth authentication is used in the request.
diagnostics
It contains an explicit error code that specifies why an OAuth authentication
failed.
The errorId field is an integer, and the error_type field is the string
representation of that integer, as follows:
2000000: invalid_signature
2000001: invalid_token
2000002: token_expired
2000003: invalid_resource
2000004: invalid_tenant
2000005: invalid_user
2000006: invalid_client
2000007: internal_error
2000008: invalid_grant
milliseconds>,SoapAction=<EWS operation>
We maintain reports for these latencies and use them to continuously improve EWS
services in Exchange Online.
Next steps
After you've added client instrumentation to your application, you're better prepared if
something goes wrong. If that happens, you can use your instrumentation data to
troubleshoot your application.
See also
EWS client design overview for Exchange
Trace requests and responses to troubleshoot EWS Managed API applications
Tools and resources for troubleshooting EWS applications for Exchange
Develop web service clients for
Exchange
Article • 09/14/2022 • 2 minutes to read
Find information to help you develop EWS and web service client applications for
Exchange.
The articles in this section explain how to use EWS and web services in your Exchange
client applications for Exchange Online, Exchange Online as part of Office 365, and on-
premises versions of Exchange starting with Exchange 2013, and provide examples that
show you how to perform specific tasks.
In this section
Archiving in EWS in Exchange
Identifiers in Exchange
See also
Explore the EWS Managed API, EWS, and web services in Exchange
Start using web services in Exchange
EWS client design overview for Exchange
Web services reference for Exchange
Archiving in EWS in Exchange
Article • 09/15/2021 • 2 minutes to read
Archive mailboxes are secondary mailboxes that are associated with a user. Archive
mailboxes are typically used to manage email storage limits. For example, older email
items might periodically be moved from the Inbox to the archive mailbox.
Exchange Online, Exchange Online as part of Office 365, and Exchange Server 2013
introduce two new Exchange Web Services (EWS) operations that you can use to archive
a set of mail items from a primary mailbox. Archiving Inbox items in this way preserves
the folder hierarchy of the items. In addition, archive mailboxes can now be stored either
locally on a client, or remotely, in a way that is mostly opaque to a user, by using a
folder path to point to the contents of the archive.
ArchiveItem
Moves an item from the primary mailbox to the archive mailbox.
CreateFolderPath
Creates a URI that points to the storage location for the archive mailbox.
See also
Develop web service clients for Exchange
Learn about attachments and how your EWS Managed API or EWS in Exchange client
represents them.
Usually, attachments are associated with email items, but in fact, all EWS items — email
messages, calendar items, contacts, tasks — can include attachments.
Types of attachments
EWS categorizes attachments into two groups: file attachments and item attachments.
File attachments: Any file, such as a .txt, .jpg, .zip, .pdf, or even a .msg file. A file
attachment only has a few properties, one of which is the base-64 encoded
content of the file.
When you add or retrieve attachments from an item, you'll do it differently depending
on whether it's a file attachment or an item attachment. For example, to add a file
attachment to an item, you can just pass in the location of the file. To add an existing
item as an item attachment, you actually have to copy the properties or the MIME
content of the existing item to a new item attachment; you can't just bind to the existing
item. So distinguishing between the two types of attachments is important. More details
about the differences between item attachments and file attachments are discussed in
the articles In this section.
Attachment ID Attachment.Id
AttachmentId
ItemAttachment<TItem>
Inline attachments
Inline attachments are a special breed of attachment. Both file attachments and item
attachments can be inline attachments. An inline attachment appears as part of the
body content and retains its position relative to the rest of the content in the item.
Note that the EWS Managed API HasAttachments property and the EWS
HasAttachments element do not reflect the existence of inline attachments, and that's
why inline attachments are also called hidden attachments. So if you set the EWS
Managed API IsInline property or the EWS IsInline element to true, and the item has
no other attachments, HasAttachments will be set to false. If your client uses
HasAttachments to populate an attachment indicator or icon on an email, be aware that
the icon will not appear for emails with inline attachments.
In this section
Add attachments by using EWS in Exchange
See also
Develop web service clients for Exchange
Learn how to create new items with attachments, or add attachments to existing items
by using the EWS Managed API or EWS in Exchange.
You can add file attachments or item attachments to new or existing items by using the
EWS Managed API or EWS. If you are using the EWS Managed API, you use the same
method to add attachments to new or existing items; however, the method changes if
you're using a file or item attachment. Conversely, if you are using EWS, you use the
same operation to add either a file or item attachment to an item, but the operation
changes if you're adding the attachment to a new or existing item.
Table 1. EWS Managed API methods and EWS operations for adding attachments
This code example shows the four ways in which a file attachment can be added to an
item by using the EWS Managed API:
By using a stream.
Note that the item attachment in this example is created at the same time as the email
message. To add an existing email message as an item attachment, see Add an existing
item to a new email by using the MimeContent and the EWS Managed API.
This example assumes that service is a valid ExchangeService object and that the user
has been authenticated to an Exchange server.
C#
message.ToRecipients.Add("[email protected]");
message.ToRecipients.Add("[email protected]");
message.Attachments.AddFileAttachment("C:\\temp\\FileAttachment.txt");
message.Attachments.AddFileAttachment("SecondAttachment.txt",
"C:\\temp\\FileAttachment2.txt");
// Add a file attachment by using a byte array.
message.Attachments.AddFileAttachment("ThirdAttachment.jpg", theBytes);
ItemAttachment<EmailMessage> itemAttachment =
message.Attachments.AddItemAttachment<EmailMessage>();
itemAttachment.Item.ToRecipients.Add("[email protected]");
itemAttachment.Item.ToRecipients.Add("[email protected]");
// Send the mail and save a copy in the Sent Items folder.
message.SendAndSaveCopy();
Note that the item attachment in this example is created at the same time as the email
message. To add an existing email message as an item attachment, see Add an existing
item to a new email by using the MimeContent and the EWS Managed API.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:CreateItem MessageDisposition="SaveOnly">
<m:Items>
<t:Message>
<t:Attachments>
<t:FileAttachment>
<t:Name>FileAttachment.txt</t:Name>
<t:IsInline>false</t:IsInline>
<t:IsContactPhoto>false</t:IsContactPhoto>
<t:Content>VGhpcyBpcyBhIGZpbGUgYXR0YWNobWVudC4=</t:Content>
</t:FileAttachment>
<t:FileAttachment>
<t:Name>SecondAttachment.txt</t:Name>
<t:IsInline>false</t:IsInline>
<t:IsContactPhoto>false</t:IsContactPhoto>
<t:Content>VGhpcyBpcyB0aGUgc2Vjb25kIGZpbGUgYXR0YWNobWVudC4=
</t:Content>
</t:FileAttachment>
<t:FileAttachment>
<t:Name>ThirdAttachment.jpg</t:Name>
<t:IsInline>false</t:IsInline>
<t:IsContactPhoto>false</t:IsContactPhoto>
<t:Content>nAoAXNIZMVEZs5GKhdzRcLH/9k=</t:Content>
</t:FileAttachment>
<t:FileAttachment>
<t:Name>FourthAttachment.txt</t:Name>
<t:IsInline>false</t:IsInline>
<t:IsContactPhoto>false</t:IsContactPhoto>
<t:Content>obWVudC4=…</t:Content>
</t:FileAttachment>
<t:ItemAttachment>
<t:IsInline>false</t:IsInline>
<t:Message>
<t:ToRecipients>
<t:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:Mailbox>
<t:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:Mailbox>
</t:ToRecipients>
</t:Message>
</t:ItemAttachment>
</t:Attachments>
<t:ToRecipients>
<t:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:Mailbox>
<t:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:Mailbox>
</t:ToRecipients>
</t:Message>
</m:Items>
</m:CreateItem>
</soap:Body>
</soap:Envelope>
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="15"
MinorVersion="0"
MajorBuildNumber="939"
MinorBuildNumber="12"
Version="V2_11"
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:CreateItemResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:CreateItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:Message>
<t:ItemId Id="upV4AAA="
ChangeKey="CQAAABYAAAAFI5DJmZv+TLtyLOLIF1S5AAAXuktU"
/>
<t:Attachments>
<t:FileAttachment>
</t:FileAttachment>
<t:FileAttachment>
</t:FileAttachment>
<t:FileAttachment>
</t:FileAttachment>
<t:FileAttachment>
</t:FileAttachment>
<t:ItemAttachment>
</t:ItemAttachment>
</t:Attachments>
</t:Message>
</m:Items>
</m:CreateItemResponseMessage>
</m:ResponseMessages>
</m:CreateItemResponse>
</s:Body>
</s:Envelope>
1. If you're working with email messages specifically, you can copy the value of the
MimeContent property from the email into the newly created item attachment.
You will lose some properties during this process, such as follow up flags and
categories, but it works great for standard email messages.
2. If you need full fidelity for all item types, you can bind to an existing item and copy
all the properties and extended properties into the new attachment.
The following code example shows the first approach, copying the MimeContent into
the new item attachment. Following this example is a procedure that shows how you
can modify the code to use the second approach.
This example assumes that service is a valid ExchangeService object and that the user
has been authenticated to an Exchange server, and that the itemId is the ItemId of the
item to attach.
C#
message.ToRecipients.Add("[email protected]");
// Add an email message item attachment and set properties on the item.
ItemAttachment<EmailMessage> itemAttachment =
message.Attachments.AddItemAttachment<EmailMessage>();
itemAttachment.Item.MimeContent = msgToAttach.MimeContent;
itemAttachment.Name = msgToAttach.Subject;
// Send the mail and save a copy in the Sent Items folder.
message.SendAndSaveCopy();
To modify this example to copy each of the properties on the existing item into the new
item attachment, do the following:
C#
2. Remove the following line, because you do not need the MimeContent property.
C#
itemAttachment.Item.MimeContent = msgToAttach.MimeContent;
3. Repeat this line for each property to copy from the existing item to the new
attachment. Do not copy the ItemId into the new item attachment because that's a
read-only property.
C#
itemAttachment.Item.Subject = msgToAttach.Subject;
C#
ExtendedPropertyDefinition sent = new ExtendedPropertyDefinition(3591,
MapiPropertyType.Integer);
msgToAttach.Item.SetExtendedProperty(sent, "1");
1. If you're working with email messages specifically, you can copy the value of the
MimeContent element from the email into the newly created item attachment.
You will lose some properties during this process, such as follow up flags and
categories, but it works great for standard email messages.
2. If you need full fidelity for all item types, you can bind to an existing item and copy
all the properties and extended properties into the new attachment.
The following code example shows how to use the MimeContent element to copy the
content of the original item into the MimeContent value of the new item attachment.
The example uses the following operations:
1. GetItem — To get the MimeContent and Subject of the message that will
become the item attachment on the new message.
The example starts by retrieving the MimeContent and the Subject of the existing item.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<m:GetItem>
<m:ItemShape>
<t:BaseShape>IdOnly</t:BaseShape>
<t:AdditionalProperties>
</t:AdditionalProperties>
</m:ItemShape>
<m:ItemIds>
</m:ItemIds>
</m:GetItem>
</soap:Body>
</soap:Envelope>
The server responds to the GetItem request with a GetItemResponse message that
includes a ResponseCode value of NoError, which indicates that the email was
retrieved successfully, and the MimeContent and Subject of the email.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="15"
MinorVersion="0"
MajorBuildNumber="944"
MinorBuildNumber="11"
Version="V2_12"
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:GetItemResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:GetItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:Message>
<t:MimeContent CharacterSet="UTF-8">tDQe/Eo=…</t:MimeContent>
<t:ItemId Id="jCrTAAA="
ChangeKey="CQAAABYAAAAFI5DJmZv+TLtyLOLIF1S5AAAZi+7u"
/>
<t:Subject>Play tennis?</t:Subject>
</t:Message>
</m:Items>
</m:GetItemResponseMessage>
</m:ResponseMessages>
</m:GetItemResponse>
</s:Body>
</s:Envelope>
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:CreateItem MessageDisposition="SaveOnly">
<m:Items>
<t:Message>
<t:ToRecipients>
<t:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:Mailbox>
</t:ToRecipients>
</t:Message>
</m:Items>
</m:CreateItem>
</soap:Body>
</soap:Envelope>
Next, create the new item attachment by using the MimeContent and Subject retrieved
by the GetItem operation. The value of the ParentItemId element is populated by
using the ItemId value returned in the CreateItem response.
XML
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:CreateAttachment>
<m:Attachments>
<t:ItemAttachment>
<t:Name>Play tennis?</t:Name>
<t:IsInline>false</t:IsInline>
<t:Message>
<t:MimeContent CharacterSet="UTF-8">tDQe/Eo=…</t:MimeContent>
</t:Message>
</t:ItemAttachment>
</m:Attachments>
</m:CreateAttachment>
</soap:Body>
</soap:Envelope>
Now that the new message has been created, and the item was attached, you can send
this newly created message by calling the SendItem operation.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:SendItem SaveItemToFolder="true">
<m:ItemIds>
<t:ItemId Id="jDKsAAA="
ChangeKey="CQAAABYAAAAFI5DJmZv+TLtyLOLIF1S5AAAZi/q/" />
</m:ItemIds>
<m:SavedItemFolderId>
</m:SavedItemFolderId>
</m:SendItem>
</soap:Body>
</soap:Envelope>
The server responds to the SendItem request with a SendItemResponse message that
includes a ResponseCode value of NoError, which indicates that the email was sent
successfully.
This example assumes that service is a valid ExchangeService object and that the user
has been authenticated to an Exchange server.
C#
// Create the HTML body with the content identifier of the attachment.
<head>
</head>
<body>
</body>
</html>";
message.ToRecipients.Add("[email protected]");
message.Attachments.AddFileAttachment("Party.jpg", file);
message.Attachments[0].IsInline = true;
message.Attachments[0].ContentId = "Party.jpg";
// Send the mail and save a copy in the Sent Items folder.
message.SendAndSaveCopy();
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:CreateItem MessageDisposition="SaveOnly">
<m:Items>
<t:Message>
<t:Subject>Inline Attachment</t:Subject>
<t:Body BodyType="HTML">
&lt;html&gt;
&lt;head&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;/body&gt;
&lt;/html&gt;
</t:Body>
<t:ToRecipients>
<t:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:Mailbox>
</t:ToRecipients>
</t:Message>
</m:Items>
</m:CreateItem>
</soap:Body>
</soap:Envelope>
This example assumes that service is a valid ExchangeService object and that the user
has been authenticated to an Exchange server.
XML
message.Attachments.AddFileAttachment("C:\\temp\\FileAttachment.txt");
message.Update(ConflictResolutionMode.AlwaysOverwrite);
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:TimeZoneContext>
<t:TimeZoneDefinition Id="Central Standard Time" />
</t:TimeZoneContext>
</soap:Header>
<soap:Body>
<m:CreateAttachment>
<m:Attachments>
<t:FileAttachment>
<t:Name>FileAttachment.txt</t:Name>
<t:Content>VGhpcyBpcyBhIGZpbGUgYXR0YWNobWVudC4=</t:Content>
</t:FileAttachment>
</m:Attachments>
</m:CreateAttachment>
</soap:Body>
</soap:Envelope>
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="15"
MinorVersion="0"
MajorBuildNumber="939"
MinorBuildNumber="12"
Version="V2_11"
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:CreateAttachmentResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:CreateAttachmentResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Attachments>
<t:FileAttachment>
<t:AttachmentId Id="yRLhCh8="
RootItemId="uqE2AAA="
RootItemChangeKey="CQAAABYAAAAFI5DJmZv+TLtyLOLIF1S5AAAXulcf" />
</t:FileAttachment>
</m:Attachments>
</m:CreateAttachmentResponseMessage>
</m:ResponseMessages>
</m:CreateAttachmentResponse>
</s:Body>
</s:Envelope>
See also
Attachments and EWS in Exchange
Learn how to get attachments from EWS items by using the EWS Managed API or EWS
in Exchange.
You can get attachments from an item by using the EWS Managed API or EWS. Because
the initial call to get an item only includes metadata about the attachment collection on
the item, retrieving attachments is always a two-step process. First, retrieve the item.
Next, retrieve the attachment.
Table 1. EWS Managed API methods and EWS operations for adding attachments
This example assumes that service is a valid ExchangeService object, that itemId is the
ItemId of the message from which attachments will be retrieved, and that the user has
been authenticated to an Exchange server.
C#
if (attachment is FileAttachment)
fileAttachment.Load("C:\\temp\\" + fileAttachment.Name);
// This does not save the file like it does with a file
attachment.
itemAttachment.Load();
The following code example shows how to use the GetItem operation to get an email
message and the collection of attachments on the message. This is also the first XML
request that the EWS Managed API sends when you use the EWS Managed API to get all
attachments from an email. The values of some attributes are shortened for readability.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:GetItem>
<m:ItemShape>
<t:BaseShape>IdOnly</t:BaseShape>
<t:AdditionalProperties>
</t:AdditionalProperties>
</m:ItemShape>
<m:ItemIds>
</m:ItemIds>
</m:GetItem>
</soap:Body>
</soap:Envelope>
The server responds to the GetItem request with a GetItemResponse message that
includes a ResponseCode value of NoError, which indicates that the email was
retrieved successfully, and the AttachmentId values of the existing attachments.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="15"
MinorVersion="0"
MajorBuildNumber="939"
MinorBuildNumber="12"
Version="V2_11"
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:GetItemResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:GetItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:Message>
<t:ItemId Id="ERu/AAA="
ChangeKey="CQAAABYAAAAFI5DJmZv+TLtyLOLIF1S5AAAYEMnd"
/>
<t:Attachments>
<t:FileAttachment>
<t:Name>FileAttachment.txt</t:Name>
<t:Size>212</t:Size>
<t:LastModifiedTime>2014-05-
14T17:59:30</t:LastModifiedTime>
<t:IsInline>false</t:IsInline>
<t:IsContactPhoto>false</t:IsContactPhoto>
</t:FileAttachment>
<t:ItemAttachment>
<t:Size>3063</t:Size>
<t:LastModifiedTime>2014-05-
14T17:59:30</t:LastModifiedTime>
<t:IsInline>false</t:IsInline>
</t:ItemAttachment>
</t:Attachments>
</t:Message>
</m:Items>
</m:GetItemResponseMessage>
</m:ResponseMessages>
</m:GetItemResponse>
</s:Body>
</s:Envelope>
Now that you have the AttachmentId values, call GetAttachment on each
attachment you want to retrieve.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:GetAttachment>
<m:AttachmentIds>
<t:AttachmentId Id="5zTzlqU=" />
</m:AttachmentIds>
</m:GetAttachment>
</soap:Body>
</soap:Envelope>
When retrieving an item attachment, the server responds to the GetAttachment request
with a GetAttachmentResponse message that includes a ResponseCode value of
NoError, which indicates that the attachment was retrieved successfully, and all the
elements for the attached item, which in this case is an email message.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="15"
MinorVersion="0"
MajorBuildNumber="939"
MinorBuildNumber="12"
Version="V2_11"
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:GetAttachmentResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:GetAttachmentResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Attachments>
<t:ItemAttachment>
<t:Message>
<t:ItemClass>IPM.Note</t:ItemClass>
<t:Size>2859</t:Size>
<t:IsSubmitted>false</t:IsSubmitted>
<t:IsDraft>true</t:IsDraft>
<t:IsFromMe>false</t:IsFromMe>
<t:IsResend>false</t:IsResend>
<t:IsUnmodified>false</t:IsUnmodified>
<t:DateTimeCreated>2014-05-14T17:59:37Z</t:DateTimeCreated>
<t:ResponseObjects>
<t:ForwardItem />
</t:ResponseObjects>
<t:DisplayCc />
<t:DisplayTo>primary; emaildelegate</t:DisplayTo>
<t:HasAttachments>false</t:HasAttachments>
<t:Culture>en</t:Culture>
<t:EffectiveRights>
<t:CreateAssociated>false</t:CreateAssociated>
<t:CreateContents>false</t:CreateContents>
<t:CreateHierarchy>false</t:CreateHierarchy>
<t:Delete>true</t:Delete>
<t:Modify>true</t:Modify>
<t:Read>true</t:Read>
</t:EffectiveRights>
<t:LastModifiedName>primary</t:LastModifiedName>
<t:LastModifiedTime>2014-05-
14T17:59:30Z</t:LastModifiedTime>
<t:IsAssociated>false</t:IsAssociated>
<t:WebClientReadFormQueryString>?
ItemID=AAMk3D&amp;exvsurl=1&amp;viewmodel=
ReadMessageItem</t:WebClientReadFormQueryString>
<t:ConversationId Id="AAQkADIwM2ZlM2ZlLWMwYjctNDg2N/Rc+d0="
/>
<t:ToRecipients>
<t:Mailbox>
<t:Name>primary</t:Name>
<t:EmailAddress>[email protected]</t:EmailAddress>
<t:RoutingType>SMTP</t:RoutingType>
<t:MailboxType>Mailbox</t:MailboxType>
</t:Mailbox>
<t:Mailbox>
<t:Name>emaildelegate</t:Name>
<t:EmailAddress>[email protected]</t:EmailAddress>
<t:RoutingType>SMTP</t:RoutingType>
<t:MailboxType>Mailbox</t:MailboxType>
</t:Mailbox>
</t:ToRecipients>
<t:IsReadReceiptRequested>false</t:IsReadReceiptRequested>
<t:ConversationIndex>AQHPb55BxR5Fm0Arx0yY4xbL9Fz53Q==
</t:ConversationIndex>
<t:ConversationTopic>Message Item
Subject</t:ConversationTopic>
<t:IsRead>true</t:IsRead>
</t:Message>
</t:ItemAttachment>
</m:Attachments>
</m:GetAttachmentResponseMessage>
</m:ResponseMessages>
</m:GetAttachmentResponse>
</s:Body>
</s:Envelope>
When retrieving a file attachment, the server responds to the GetAttachment request
with a GetAttachmentResponse message that includes a ResponseCode value of
NoError, which indicates that the attachment was retrieved successfully, and all the
elements of the file attachment.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="15"
MinorVersion="0"
MajorBuildNumber="939"
MinorBuildNumber="12"
Version="V2_11"
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:GetAttachmentResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:GetAttachmentResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Attachments>
<t:FileAttachment>
<t:Content>VGhpcyBpcyBhIGZpbGUgYXR0YWNobWVudC4=</t:Content>
</t:FileAttachment>
</m:Attachments>
</m:GetAttachmentResponseMessage>
</m:ResponseMessages>
</m:GetAttachmentResponse>
</s:Body>
</s:Envelope>
Note that you cannot move or copy the item attachment to another folder because the
item attachment is not a strongly-typed item, so if you're trying to move an attachment
to a different folder, use the following code example and then import the file into a
different folder.
C#
if (attachment is ItemAttachment)
itemAttachment.Load(ItemSchema.MimeContent);
File.WriteAllBytes(fileName,
itemAttachment.Item.MimeContent.Content);
See also
Attachments and EWS in Exchange
Learn how to delete attachments from items by using the EWS Managed API or EWS in
Exchange.
You have a number of options when it comes to deleting file and item attachments from
items by using the EWS Managed API. You can delete all the attachments from the
message, delete by a file name, or delete by position in the collection. For each of these
options, there is an AttachmentCollection method.
Conversely, with EWS, no matter whether you're deleting all attachments from an item
or just one, the sequence of operations is same. Unlike the EWS Managed API, EWS
does not include separate operations to delete based on name or position in the
attachments array.
Table 1. EWS Managed API methods and EWS operations for deleting attachments
This example assumes that service is a valid ExchangeService object, itemId is the
ItemId of the message from which attachments will be deleted, and that the user has
been authenticated to an Exchange server.
C#
message.Attachments.Clear();
message.Update(ConflictResolutionMode.AlwaysOverwrite);
This example assumes that service is a valid ExchangeService object, itemId is the
ItemId of the message from which the attachment will be deleted, and that the user
has been authenticated to an Exchange server.
C#
public static void DeleteNamedAttachments(ExchangeService service, ItemId
itemId)
if (attachment.Name == "FileAttachment.txt")
message.Attachments.Remove(attachment);
break;
message.Update(ConflictResolutionMode.AlwaysOverwrite);
This example assumes that service is a valid ExchangeService object, itemId is the
ItemId of the message from which the attachment will be deleted, and that the user
has been authenticated to an Exchange server.
C#
if (message.HasAttachments)
message.Attachments.RemoveAt(0);
message.Update(ConflictResolutionMode.AlwaysOverwrite);
The following code example shows how to use the GetItem operation to get an email
message and the collection of attachments on the message. This is also the first XML
request that the EWS Managed API sends when you use the EWS Managed API to delete
all attachments from an email. The values of some attributes are shortened for
readability.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:TimeZoneContext>
<t:TimeZoneDefinition Id="Central Standard Time" />
</t:TimeZoneContext>
</soap:Header>
<soap:Body>
<m:GetItem>
<m:ItemShape>
<t:BaseShape>IdOnly</t:BaseShape>
<t:AdditionalProperties>
</t:AdditionalProperties>
</m:ItemShape>
<m:ItemIds>
</m:ItemIds>
</m:GetItem>
</soap:Body>
</soap:Envelope>
The server responds to the GetItem request with a GetItemResponse message that
includes a ResponseCode value of NoError, which indicates that the email was
retrieved successfully, and the AttachmentId values of the existing attachments.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="15"
MinorVersion="0"
MajorBuildNumber="939"
MinorBuildNumber="12"
Version="V2_11"
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:GetItemResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:GetItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:Message>
<t:ItemId Id="uqE1AAA="
ChangeKey="CQAAABYAAAAFI5DJmZv+TLtyLOLIF1S5AAAXulcd"
/>
<t:Attachments>
<t:FileAttachment>
<t:Name>FileAttachment.txt</t:Name>
</t:FileAttachment>
<t:FileAttachment>
<t:Name>SecondAttachment.txt</t:Name>
</t:FileAttachment>
<t:FileAttachment>
<t:Name>ThirdAttachment.jpg</t:Name>
</t:FileAttachment>
<t:FileAttachment>
<t:Name>FourthAttachment.txt</t:Name>
</t:FileAttachment>
<t:ItemAttachment>
</t:ItemAttachment>
</t:Attachments>
</t:Message>
</m:Items>
</m:GetItemResponseMessage>
</m:ResponseMessages>
</m:GetItemResponse>
</s:Body>
</s:Envelope>
After you determine which attachment to delete, call the DeleteAttachment operation
and include the AttachmentId values of the attachments to delete.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:TimeZoneContext>
<t:TimeZoneDefinition Id="Central Standard Time" />
</t:TimeZoneContext>
</soap:Header>
<soap:Body>
<m:DeleteAttachment>
<m:AttachmentIds>
<t:AttachmentId Id="IpHLObE=" />
</m:AttachmentIds>
</m:DeleteAttachment>
</soap:Body>
</soap:Envelope>
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="15"
MinorVersion="0"
MajorBuildNumber="939"
MinorBuildNumber="12"
Version="V2_11"
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:DeleteAttachmentResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:DeleteAttachmentResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
</m:DeleteAttachmentResponseMessage>
<m:DeleteAttachmentResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
</m:DeleteAttachmentResponseMessage>
<m:DeleteAttachmentResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
</m:DeleteAttachmentResponseMessage>
<m:DeleteAttachmentResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
</m:DeleteAttachmentResponseMessage>
<m:DeleteAttachmentResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
</m:DeleteAttachmentResponseMessage>
</m:ResponseMessages>
</m:DeleteAttachmentResponse>
</s:Body>
</s:Envelope>
See also
Attachments and EWS in Exchange
Learn about calendars, calendar folders and items, appointments, and meetings in
Exchange.
You're probably familiar with many of the calendar features in email clients like Outlook,
which enable you to track appointments, schedule meetings, check people's availability,
invite attendees, and change or cancel meetings.
Calendar-related features in Exchange are a little different than what you see in a client
like Outlook. Instead of displaying information, EWS in Exchange enables you to do
things like create, store, send, or change information. To use EWS to work with
calendars, you'll need to be familiar with concepts such as information storage, time,
recurrence, and message flow. More specifically, you'll need to be familiar with the
following:
Time durations, time zones, and start and end times of meetings and
appointments
Fortunately, EWS and the EWS Managed API provide a rich set of operations and
methods that enable you to perform a wide range of calendar-related tasks. For
example, using the EWS Managed API, you can create a meeting and send invitations to
attendees with just a few lines of code, as shown in the following example.
C#
meeting.Start = DateTime.Now.AddDays(2);
meeting.End = meeting.Start.AddHours(2);
meeting.RequiredAttendees.Add("[email protected]");
meeting.RequiredAttendees.Add("[email protected]");
meeting.OptionalAttendees.Add("[email protected]");
meeting.ReminderMinutesBeforeStart = 60;
meeting.Save(SendInvitationsMode.SendToAllAndSaveCopy);
Items in a Calendar folder are a little different from items in other folders in a mailbox
because occurrences in a recurring series and exceptions to a recurring series are not
actual items in the mailbox, but rather are stored internally as attachments to a recurring
master. Therefore, in order to retrieve all appointments in a given date range, you need
to use a calendar view. To learn more about retrieving appointments and calendar views,
see Get appointments and meetings by using EWS in Exchange.
Both appointments and meetings can be single instances or part of a recurring series,
but because appointments don't include attendees, rooms, or resources, they do not
require a message to be sent.
Because meetings include sending and responding to requests and updates, they
involve more than just accessing items in a Calendar folder. They also have an
associated workflow. Meetings must be scheduled when attendees are available, and
can also involve reserving a meeting room, or resources such as a projector or other
equipment.
1. A meeting is created and populated with information such as start and end time,
location, and a message body.
2. A list of prospective attendees, resources, and rooms is created.
3. The availability status of attendees is checked.
4. A meeting request is sent to attendees.
5. Attendees reply to the meeting with their intention to attend or not. Attendees
may also propose a new time for the meeting.
6. Meetings can be canceled or updated, which typically trigger new messages to be
sent to attendees.
Times are stored internally on an Exchange server in Coordinated Universal Time (UTC).
Exchange converts them to local time zone based on client settings. DateTime
properties are scoped to the computer's local time zone.
Recurring series
A recurring series of appointments or meetings is comprised of a recurring master, a set
of occurrence items, and optionally, a set of exception items. Recurrence information is
stored on the recurring master item. The RecurringMasterItemId EWS element is
associated with occurrences and exceptions in a series, or you can use the
Appointment.BindToRecurringMaster EWS Managed API method to get the recurring
master. Using an instance of a series, you can find all the elements and information
associated with the series.
Note that recurrence properties exist on all calendar items, but they are populated only
on recurring master items. In addition to an index of all occurrences in a series, the
recurring master has a reference to modified and deleted occurrences and the
recurrence pattern of a series (for example, daily, weekly, monthly, or yearly).
In this section
Create appointments and meetings by using EWS in Exchange 2013
See also
Develop web service clients for Exchange
Start using web services in Exchange
EWS client design overview for Exchange
Create appointments and meetings by
using EWS in Exchange 2013
Article • 01/15/2020 • 6 minutes to read
Learn how to create appointments and meetings by using the EWS Managed API or
EWS in Exchange.
The essential difference between meetings and appointments is that meetings have
attendees, and appointments don't. Both appointments and meetings can be single
instances or part of a recurring series, but because appointments don't include
attendees, rooms, or resources, they do not require a message to be sent. Internally,
Exchange uses the same object for both meetings and appointments. You use the EWS
Managed API Appointment class or the EWS [CalendarItem]
(https://msdn.microsoft.com/library/Title Topic ID Project Name Writer Editor Publish
Preview.aspx) element to work with meetings and appointments.
Table 1. EWS Managed API methods and EWS operations for working with
appointments and meetings
Appointment.Save
CreateItem operation (calendar item)
Item.Bind
GetItem operation (calendar item)
This example assumes that you have authenticated to an Exchange server and have
acquired an ExchangeService object named service.
C#
appointment.Start = DateTime.Now.AddDays(2);
appointment.End = appointment.Start.AddHours(1);
appointment.ReminderDueBy = DateTime.Now;
appointment.Save(SendInvitationsMode.SendToNone);
// Verify that the appointment was created by using the appointment's item
ID.
After setting the properties on the appointment object, you save the appointment to the
calendar folder by using the appointment object's Save method.
Note that in the verification step, you use the item Id associated with the appointment
to verify that the appointment is in the calendar folder. As a best practice, limit the
properties returned by the server to only what you need — in this case, the
appointment's subject.
The following example shows the request XML when you use the CreateItem
operation to create an appointment.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:TimeZoneContext>
<t:TimeZoneDefinition Id="Pacific Standard Time" />
</t:TimeZoneContext>
</soap:Header>
<soap:Body>
<m:CreateItem SendMeetingInvitations="SendToNone">
<m:Items>
<t:CalendarItem>
<t:Subject>Tennis lesson</t:Subject>
<t:ReminderDueBy>2013-09-19T14:37:10.732-07:00</t:ReminderDueBy>
<t:Start>2013-09-21T19:00:00.000Z</t:Start>
<t:End>2013-09-21T20:00:00.000Z</t:End>
<t:Location>Tennis club</t:Location>
</t:CalendarItem>
</m:Items>
</m:CreateItem>
</soap:Body>
</soap:Envelope>
The following example shows the response XML that is returned by the CreateItem
operation.
7 Note
The ItemId and ChangeKey attributes have been shortened for readability.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:CreateItemResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:CreateItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:CalendarItem>
</t:CalendarItem>
</m:Items>
</m:CreateItemResponseMessage>
</m:ResponseMessages>
</m:CreateItemResponse>
</s:Body>
</s:Envelope>
The following example shows the request XML that is generated when you use the
GetItem operation to verify that the appointment was created.
7 Note
The ItemId and ChangeKey attributes have been shortened for readability.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:TimeZoneContext>
<t:TimeZoneDefinition Id="Pacific Standard Time" />
</t:TimeZoneContext>
</soap:Header>
<soap:Body>
<m:GetItem>
<m:ItemShape>
<t:BaseShape>IdOnly</t:BaseShape>
<t:AdditionalProperties>
</t:AdditionalProperties>
</m:ItemShape>
<m:ItemIds>
</m:ItemIds>
</m:GetItem>
</soap:Body>
</soap:Envelope>
The following example shows the response XML that is returned by the GetItem
operation.
7 Note
The ItemId and ChangeKey attributes have been shortened for readability.
XML
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:GetItemResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:GetItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:CalendarItem>
<t:Subject>Tennis lesson</t:Subject>
</t:CalendarItem>
</m:Items>
</m:GetItemResponseMessage>
</m:ResponseMessages>
</m:GetItemResponse>
</s:Body>
</s:Envelope>
This example assumes that you have authenticated to an Exchange server and have
acquired an ExchangeService object named service.
C#
meeting.Body = "Let's learn to really work as a team and then have lunch!";
meeting.Start = DateTime.Now.AddDays(2);
meeting.End = meeting.Start.AddHours(4);
meeting.RequiredAttendees.Add("[email protected]");
meeting.RequiredAttendees.Add("[email protected]");
meeting.OptionalAttendees.Add("[email protected]");
meeting.ReminderMinutesBeforeStart = 60;
// Save the meeting to the Calendar folder and send the meeting request.
meeting.Save(SendInvitationsMode.SendToAllAndSaveCopy);
After setting the properties on the Appointment object, save the meeting to your
calendar folder by using the Save method. When you set the SendInvitationsMode
enumeration value to SendOnlyToAll or SendToAllAndSaveCopy, invitations are sent to
attendees.
Use the item Id associated with the meeting to verify that it was saved in the calendar
folder. As a best practice, limit the properties returned by the server to only what you
need - in this case, the meeting's subject.
The following example shows the request XML when you use the CreateItem
operation to create a meeting.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:TimeZoneContext>
<t:TimeZoneDefinition Id="Pacific Standard Time" />
</t:TimeZoneContext>
</soap:Header>
<soap:Body>
<m:CreateItem SendMeetingInvitations="SendToAllAndSaveCopy">
<m:Items>
<t:CalendarItem>
<t:ReminderMinutesBeforeStart>60</t:ReminderMinutesBeforeStart>
<t:Start>2013-09-21T16:00:00.000Z</t:Start>
<t:End>2013-09-21T20:00:00.000Z</t:End>
<t:RequiredAttendees>
<t:Attendee>
<t:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:Mailbox>
</t:Attendee>
<t:Attendee>
<t:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:Mailbox>
</t:Attendee>
</t:RequiredAttendees>
<t:OptionalAttendees>
<t:Attendee>
<t:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:Mailbox>
</t:Attendee>
</t:OptionalAttendees>
</t:CalendarItem>
</m:Items>
</m:CreateItem>
</soap:Body>
</soap:Envelope>
The following example shows the response XML that is returned by the CreateItem
operation.
7 Note
The ItemId and ChangeKey attributes have been shortened for readability.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:CreateItemResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:CreateItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:CalendarItem>
</t:CalendarItem>
</m:Items>
</m:CreateItemResponseMessage>
</m:ResponseMessages>
</m:CreateItemResponse>
</s:Body>
</s:Envelope>
The following example shows the request XML that is generated by the GetItem
operation when you verify that the meeting was created.
7 Note
The ItemId and ChangeKey attributes have been shortened for readability.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:TimeZoneContext>
<t:TimeZoneDefinition Id="Pacific Standard Time" />
</t:TimeZoneContext>
</soap:Header>
<soap:Body>
<m:GetItem>
<m:ItemShape>
<t:BaseShape>IdOnly</t:BaseShape>
<t:AdditionalProperties>
</t:AdditionalProperties>
</m:ItemShape>
<m:ItemIds>
</m:ItemIds>
</m:GetItem>
</soap:Body>
</soap:Envelope>
The following example shows the response XML that is returned by the GetItem
operation.
7 Note
The ItemId and ChangeKey attributes have been shortened for readability.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:GetItemResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:GetItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:CalendarItem>
</t:CalendarItem>
</m:Items>
</m:GetItemResponseMessage>
</m:ResponseMessages>
</m:GetItemResponse>
</s:Body>
</s:Envelope>
See also
Calendars and EWS in Exchange
Get appointments and meetings by using EWS in Exchange
Update appointments and meetings by using EWS in Exchange
Delete appointments and cancel meetings by using EWS in Exchange
Propose a new meeting time by using EWS in Exchange
Create all-day events by using EWS in
Exchange
Article • 02/11/2022 • 3 minutes to read
Learn how to create all-day events by using the EWS Managed API or EWS in Exchange.
All-day events provide a way to represent something that happens for an entire day or
multiple days—for example, a holiday, or vacation days. Creating all-day events with the
EWS Managed API or EWS is a snap. It's just like creating appointments, but with a few
small changes.
When a request is received to create a new all-day event with non-midnight (in the time
zone of the request or appointment) start and/or end times, those times get adjusted to
midnight in the appropriate time zone according to the following rules:
Non-midnight start times are adjusted to the midnight prior to the time specified.
For example, 1:00 PM on June 6 gets adjusted to 12:00 AM on June 6.
Non-midnight end times are adjusted to the midnight after the time specified. For
example, 1:00 PM on June 6 gets adjusted to 12:00 AM on June 7.
So the all-day event that you create is always inclusive of the start and end time that you
specify, but might claim additional time on the user's calendar due to the shift to
midnight. Because the server will adjust the start and end time to midnight, we
recommend that you specify your start and end time at midnight to avoid any
unintended changes to the times.
It's also important to consider time zones when creating all-day events. Because the
Exchange server enforces a midnight start and end time in the time zone of the request
or appointment, viewing that all-day event in a client configured for a different time
zone can yield unexpected results. Depending on the client, it might appear as an all-
day event with extra days that you did not intend to include, or it might not appear as
an all-day event altogether. Because of this, we recommend that you use the user's
preferred time zone whenever possible when you create all-day events.
Create an all-day event by using the EWS
Managed API
The following example shows how to use the EWS Managed API to create an all-day
event, starting on the date specified by the startDate parameter and lasting for the
number of days specified by the numDays parameter. Note that the appointment will be
created in the time zone specified by the ExchangeService.TimeZone property. This
example assumes that the ExchangeService object passed in the service parameter has
been initialized with valid values for the Credentials and Url properties.
C#
allDayEvent.Subject = "Vacation";
allDayEvent.LegacyFreeBusyStatus = LegacyFreeBusyStatus.OOF;
allDayEvent.Start = startDateMidnight;
allDayEvent.End = endDateMidnight;
try
allDayEvent.Save(WellKnownFolderName.Calendar,
SendInvitationsMode.SendToNone);
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:TimeZoneContext>
<t:TimeZoneDefinition Id="Eastern Standard Time" />
</t:TimeZoneContext>
</soap:Header>
<soap:Body>
<m:CreateItem SendMeetingInvitations="SendToNone">
<m:SavedItemFolderId>
</m:SavedItemFolderId>
<m:Items>
<t:CalendarItem>
<t:Subject>Vacation</t:Subject>
<t:Start>2014-06-09T04:00:00.000Z</t:Start>
<t:End>2014-06-10T04:00:00.000Z</t:End>
<t:IsAllDayEvent>true</t:IsAllDayEvent>
<t:LegacyFreeBusyStatus>OOF</t:LegacyFreeBusyStatus>
</t:CalendarItem>
</m:Items>
</m:CreateItem>
</soap:Body>
</soap:Envelope>
Learn how to get appointments and meetings by using the EWS Managed API or EWS in
Exchange.
You can retrieve appointments and meetings from a calendar folder by using the
CalendarFolder.FindAppointments EWS Managed API method or the FindItem EWS
operation.
C#
// Initialize values for the start and end times, and the number of
appointments to retrieve.
FindItemsResults<Appointment> appointments =
calendar.FindAppointments(cView);
Console.WriteLine("\nThe first " + NUM_APPTS + " appointments on
your calendar from " + startDate.Date.ToShortDateString() +
Console.WriteLine();
text
Subject: Lunch with sales team Start: 8/21/2013 2:30:00 PM End: 8/21/2013
3:30:00 PM
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:GetFolder>
<m:FolderShape>
<t:BaseShape>IdOnly</t:BaseShape>
</m:FolderShape>
<m:FolderIds>
</m:FolderIds>
</m:GetFolder>
</soap:Body>
</soap:Envelope>
The following XML shows the GetFolder response. Note that the FolderID and
ChangeKey attributes are shortened for readability.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:GetFolderResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:GetFolderResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Folders>
<t:CalendarFolder>
</t:CalendarFolder>
</m:Folders>
</m:GetFolderResponseMessage>
</m:ResponseMessages>
</m:GetFolderResponse>
</s:Body>
</s:Envelope>
The following XML shows the FindItem request used to return the requested
appointments. Note that the FolderID and ChangeKey attributes are shortened for
readability.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:FindItem Traversal="Shallow">
<m:ItemShape>
<t:BaseShape>IdOnly</t:BaseShape>
<t:AdditionalProperties>
</t:AdditionalProperties>
</m:ItemShape>
<m:ParentFolderIds>
</m:ParentFolderIds>
</m:FindItem>
</soap:Body>
</soap:Envelope>
The following XML shows the FindItem response. Note that the ItemID and ChangeKey
attributes are shortened for readability.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:FindItemResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:FindItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:RootFolder TotalItemsInView="33"
IncludesLastItemInRange="false">
<t:Items>
<t:CalendarItem>
<t:Start>2013-08-21T19:30:00Z</t:Start>
<t:End>2013-08-21T20:00:00Z</t:End>
</t:CalendarItem>
<t:CalendarItem>
<t:Start>2013-08-21T20:00:00Z</t:Start>
<t:End>2013-08-21T21:00:00Z</t:End>
</t:CalendarItem>
<t:CalendarItem>
<t:Start>2013-08-21T21:30:00Z</t:Start>
<t:End>2013-08-21T22:30:00Z</t:End>
</t:CalendarItem>
<t:CalendarItem>
<t:Start>2013-08-22T18:00:00Z</t:Start>
<t:End>2013-08-22T19:00:00Z</t:End>
</t:CalendarItem>
<t:CalendarItem>
<t:Start>2013-08-22T21:00:00Z</t:Start>
<t:End>2013-08-22T22:00:00Z</t:End>
</t:CalendarItem>
</t:Items>
</m:RootFolder>
</m:FindItemResponseMessage>
</m:ResponseMessages>
</m:FindItemResponse>
</s:Body>
</s:Envelope>
Instead, what you really want to do is something akin to applying a Dataview onto a
union of two SQL tables, using a CalendarView object. Note that for performance
reasons, we recommend that you use the PropertySet property to limit the size of the
response by indicating the number of appointments or meetings you want returned, as
well as the specific properties you want.
See also
Calendars and EWS in Exchange
Create appointments and meetings by using EWS in Exchange 2013
Update appointments and meetings by using EWS in Exchange
Delete appointments and cancel meetings by using EWS in Exchange
Develop web service clients for Exchange
Update appointments and meetings by
using EWS in Exchange
Article • 03/04/2022 • 5 minutes to read
Learn how to update appointments and meetings by using the EWS Managed API or
EWS in Exchange.
The essential difference between meetings and appointments is that meetings have
attendees, and appointments don't. Both appointments and meetings can be single
instances or part of a recurring series, but because appointments don't include
attendees, rooms, or resources, they do not require a message to be sent. Internally,
Exchange uses the same object for both meetings and appointments. You use the EWS
Managed API Appointment class or the EWS CalendarItem element to work with
meetings and appointments.
Table 1. EWS Managed API method and EWS operations for updating appointments
and meetings
Appointment.Update
UpdateItem
UpdateItemResponse
This example assumes that you have authenticated to an Exchange server and have
acquired an ExchangeService object named service. The local variable appointmentId
is an identifier associated with an existing appointment.
C#
// As a best practice, limit the properties returned to only the ones you
need.
// Update properties on the appointment with a new subject, start time, and
end time.
appointment.Start.AddHours(25);
appointment.End.AddHours(25);
SendInvitationsOrCancellationsMode.SendToAllAndSaveCopy :
SendInvitationsOrCancellationsMode.SendToNone;
appointment.Update(ConflictResolutionMode.AlwaysOverwrite, mode);
The following example shows the request XML when you use the UpdateItem
operation to update an appointment.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:TimeZoneContext>
<t:TimeZoneDefinition Id="Pacific Standard Time" />
</t:TimeZoneContext>
</soap:Header>
<soap:Body>
<m:UpdateItem MessageDisposition="SaveOnly"
ConflictResolution="AlwaysOverwrite"
SendMeetingInvitationsOrCancellations="SendToNone">
<m:ItemChanges>
<t:ItemChange>
<t:Updates>
<t:SetItemField>
<t:CalendarItem>
</t:CalendarItem>
</t:SetItemField>
</t:Updates>
</t:ItemChange>
</m:ItemChanges>
</m:UpdateItem>
</soap:Body>
</soap:Envelope>
The following example shows the XML that is returned in response to an UpdateItem
request. The ItemId and ChangeKey attributes have been shortened for readability.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:UpdateItemResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exc
hange/services/2006/types">
<m:ResponseMessages>
<m:UpdateItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:CalendarItem>
</t:CalendarItem>
</m:Items>
<m:ConflictResults>
<t:Count>0</t:Count>
</m:ConflictResults>
</m:UpdateItemResponseMessage>
</m:ResponseMessages>
</m:UpdateItemResponse>
</s:Body>
</s:Envelope>
This example assumes that you have authenticated to an Exchange server and have
acquired an ExchangeService object named service. The local variable meetingId is an
identifier that is associated with an existing appointment.
C#
AppointmentSchema.Location,
AppointmentSchema.RequiredAttendees,
AppointmentSchema.Resources));
meeting.RequiredAttendees.Add("[email protected]");
meeting.Resources.Add("[email protected]");
meeting.Update(ConflictResolutionMode.AlwaysOverwrite,
SendInvitationsOrCancellationsMode.SendToAllAndSaveCopy);
After setting the properties on the Appointment object, save the meeting to your
calendar folder and send updated meeting requests by using the Update method.
You can pass in one of two enumeration values as parameters when you call the
Update method:
The following example shows the request XML when you use the UpdateItem
operation to update a meeting.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:TimeZoneContext>
<t:TimeZoneDefinition Id="Pacific Standard Time" />
</t:TimeZoneContext>
</soap:Header>
<soap:Body>
<m:UpdateItem MessageDisposition="SaveOnly"
ConflictResolution="AlwaysOverwrite"
SendMeetingInvitationsOrCancellations="SendToAllAndSaveCopy">
<m:ItemChanges>
<t:ItemChange>
<t:Updates>
<t:SetItemField>
<t:CalendarItem>
</t:CalendarItem>
</t:SetItemField>
<t:SetItemField>
<t:CalendarItem>
</t:CalendarItem>
</t:SetItemField>
<t:SetItemField>
<t:CalendarItem>
<t:RequiredAttendees>
<t:Attendee>
<t:Mailbox>
<t:Name>[email protected]</t:Name>
<t:EmailAddress>[email protected]</t:EmailAddress>
<t:RoutingType>SMTP</t:RoutingType>
</t:Mailbox>
</t:Attendee>
<t:Attendee>
<t:Mailbox>
<t:Name>[email protected]</t:Name>
<t:EmailAddress>[email protected]</t:EmailAddress>
<t:RoutingType>SMTP</t:RoutingType>
</t:Mailbox>
</t:Attendee>
<t:Attendee>
<t:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:Mailbox>
</t:Attendee>
</t:RequiredAttendees>
</t:CalendarItem>
</t:SetItemField>
<t:SetItemField>
<t:CalendarItem>
<t:Resources>
<t:Attendee>
<t:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:Mailbox>
</t:Attendee>
</t:Resources>
</t:CalendarItem>
</t:SetItemField>
</t:Updates>
</t:ItemChange>
</m:ItemChanges>
</m:UpdateItem>
</soap:Body>
</soap:Envelope>
The following example shows the XML that is returned in response to an UpdateItem
request. The ChangeKey and ItemId attributes have been shortened for readability.
XML
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:UpdateItemResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:UpdateItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:CalendarItem>
</t:CalendarItem>
</m:Items>
<m:ConflictResults>
<t:Count>0</t:Count>
</m:ConflictResults>
</m:UpdateItemResponseMessage>
</m:ResponseMessages>
</m:UpdateItemResponse>
</s:Body>
</s:Envelope>
See also
Calendars and EWS in Exchange
Create appointments and meetings by using EWS in Exchange 2013
Get appointments and meetings by using EWS in Exchange
Delete appointments and cancel meetings by using EWS in Exchange
Propose a new meeting time by using EWS in Exchange
Delete appointments and cancel
meetings by using EWS in Exchange
Article • 03/04/2022 • 8 minutes to read
Learn how to delete appointments and meetings by using the EWS Managed API or
EWS in Exchange.
The essential difference between meetings and appointments is that meetings have
attendees, and appointments don't. Both appointments and meetings can be single
instances or part of a recurring series, but because appointments don't include
attendees, rooms, or resources, they do not require a message to be sent. Internally,
Exchange uses the same object for both meetings and appointments. You use the EWS
Managed API Appointment class or the EWS [CalendarItem]
(https://msdn.microsoft.com/library/Title Topic ID Project Name Writer Editor Publish
Preview.aspx) element to work with meetings and appointments.
Table 1. EWS Managed API methods and EWS operations for deleting appointments
and meetings
Appointment.Delete
DeleteItem
Deletes an appointment.
Appointment.Delete
CreateItem (calendar item)
Deletes a meeting.
Note that when you delete an appointment by using EWS, you use the DeleteItem
operation, but when you delete a meeting, you use the CreateItem operation. This might
seem counterintuitive, but it is because you have to create a meeting response object to
send meeting cancellation messages to attendees.
This example assumes that you have authenticated to an Exchange server and have
acquired an ExchangeService object named service. The local variable appointmentId
is an identifier associated with an existing appointment.
C#
// As a best practice, limit the properties returned to only the ones you
need.
// Delete the appointment. Note that the item ID will change when the item
is moved to the Deleted Items folder.
appointment.Delete(DeleteMode.MoveToDeletedItems);
// Verify that the appointment has been deleted by looking for a matching
subject in the Deleted Items folder's first entry.
itemView.Traversal = ItemTraversal.Shallow;
FindItemsResults<Item> deletedItems =
service.FindItems(WellKnownFolderName.DeletedItems, itemView);
This example shows a simple way to verify that the appointment was deleted, by
verifying that the subject of the first item in the Deleted Items folder matches that of the
deleted appointment. How you choose to verify that your appointment was deleted will
vary based the needs of your application.
As you can see, deleting an appointment is straightforward and pretty much what you
might expect. Note when you create your verification step that the appointment item in
the Deleted Items folder has a different ItemId than the appointment item in the
calendar folder. The item is copied and deleted rather than simply moved to the Deleted
Items folder.
The following example shows the request XML for the DeleteItem operation to delete an
appointment.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:TimeZoneContext>
<t:TimeZoneDefinition Id="Pacific Standard Time" />
</t:TimeZoneContext>
</soap:Header>
<soap:Body>
<m:DeleteItem DeleteType="MoveToDeletedItems"
SendMeetingCancellations="SendToAllAndSaveCopy">
<m:ItemIds>
</m:ItemIds>
</m:DeleteItem>
</soap:Body>
</soap:Envelope>
The following example shows the response XML that is returned by the DeleteItem
operation. The ItemId and ChangeKey attributes are shortened for readability.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:DeleteItemResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:DeleteItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
</m:DeleteItemResponseMessage>
</m:ResponseMessages>
</m:DeleteItemResponse>
</s:Body>
</s:Envelope>
The following example shows the request XML for the FindItem operation that
retrieves the first item in the Deleted Items folder in order to compare the item's subject
with that of the deleted appointment object.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages
" xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:TimeZoneContext>
<t:TimeZoneDefinition Id="Pacific Standard Time" />
</t:TimeZoneContext>
</soap:Header>
<soap:Body>
<m:FindItem Traversal="Shallow">
<m:ItemShape>
<t:BaseShape>IdOnly</t:BaseShape>
<t:AdditionalProperties>
</t:AdditionalProperties>
</m:ItemShape>
<m:ParentFolderIds>
</m:ParentFolderIds>
</m:FindItem>
</soap:Body>
</soap:Envelope>
The following example shows the response XML that is returned by the FindItem
operation during the verification step.
7 Note
XML
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:FindItemResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:FindItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<t:Items>
<t:CalendarItem>
<t:Subject>Tennis lesson</t:Subject>
</t:CalendarItem>
</t:Items>
</m:RootFolder>
</m:FindItemResponseMessage>
</m:ResponseMessages>
</m:FindItemResponse>
</s:Body>
</s:Envelope>
Appointment.Delete
Appointment.CancelMeeting
CancelMeetingMessage
The method that you choose depends on the level of detail you need to provide in your
cancellation message. Appointment.CancelMeeting makes it easy to update the
cancellation message by passing an updated message as a parameter.
CancelMeetingMessage allows you to modify properties on your message before
sending a cancellation, so you can do things like request a receipt.
The code examples in this section show the different ways to delete a meeting and send
meeting cancellations. The examples assume that you have authenticated to an
Exchange server and have acquired an ExchangeService object named service. The
local variable meetingId is an identifier associated with an existing meeting where the
target user is the meeting organizer.
The following code example shows how to delete a meeting by using the
Appointment.Delete method.
C#
meeting.Delete(DeleteMode.MoveToDeletedItems,
SendCancellationsMode.SendToAllAndSaveCopy);
// Verify that the meeting has been deleted by looking for a matching
subject in the Deleted Items folder's first entry.
itemView.Traversal = ItemTraversal.Shallow;
FindItemsResults<Item> deletedItems =
service.FindItems(WellKnownFolderName.DeletedItems, itemView);
The following code example shows how to delete a meeting by using the
CancelMeeting method.
C#
The following code example shows how to delete a meeting by using the
Appointment.CreateCancelMeetingMessage method.
C#
cancelMessage.IsReadReceiptRequested = true;
cancelMessage.SendAndSaveCopy();
The following example shows the request XML when you use the CreateItem
operation to send cancellation messages to attendees and delete a meeting.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:TimeZoneContext>
<t:TimeZoneDefinition Id="Pacific Standard Time" />
</t:TimeZoneContext>
</soap:Header>
<soap:Body>
<m:CreateItem MessageDisposition="SendAndSaveCopy">
<m:Items>
<t:CancelCalendarItem>
</t:CancelCalendarItem>
</m:Items>
</m:CreateItem>
</soap:Body>
</soap:Envelope>
The following example shows the XML that is returned in response to a CreateItem
operation request used to delete a meeting.
7 Note
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:CreateItemResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:CreateItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:CalendarItem>
</t:CalendarItem>
</m:Items>
</m:CreateItemResponseMessage>
</m:ResponseMessages>
</m:CreateItemResponse>
</s:Body>
</s:Envelope>
The following example shows the request XML for the FindItem operation that
retrieves the first item in the Deleted Items folder in order to compare the item's subject
with that of the deleted appointment object.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:TimeZoneContext>
<t:TimeZoneDefinition Id="Pacific Standard Time" />
</t:TimeZoneContext>
</soap:Header>
<soap:Body>
<m:FindItem Traversal="Shallow">
<m:ItemShape>
<t:BaseShape>IdOnly</t:BaseShape>
<t:AdditionalProperties>
</t:AdditionalProperties>
</m:ItemShape>
<m:ParentFolderIds>
</m:ParentFolderIds>
</m:FindItem>
</soap:Body>
</soap:Envelope>
The following example shows the XML that is returned by the FindItem operation
during the verification step.
7 Note
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:FindItemResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:FindItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<t:Items>
<t:CalendarItem>
</t:CalendarItem>
</t:Items>
</m:RootFolder>
</m:FindItemResponseMessage>
</m:ResponseMessages>
</m:FindItemResponse>
</s:Body>
</s:Envelope>
See also
Calendars and EWS in Exchange
Create appointments and meetings by using EWS in Exchange 2013
Get appointments and meetings by using EWS in Exchange
Update appointments and meetings by using EWS in Exchange
Propose a new meeting time by using EWS in Exchange
Propose a new meeting time by using EWS in Exchange
Get room lists by using EWS in
Exchange
Article • 01/15/2020 • 3 minutes to read
Learn how to get a list of all the room lists in your organization or a single room list
from an Exchange server by using the EWS Managed API or EWS.
You can use the EWS Managed API or EWS to get information about rooms and how the
rooms are grouped in your organization. Room lists don't exist by default; your
administrator needs to create and organize them. Typically, they're organized by
location or department, as shown in the following example.
Each room in a room list has a name and email address associated with it.
You can get a list that contains all room lists by using either the
ExchangeService.GetRoomLists EWS Managed API method or the GetRoomLists
EWS operation.
You can retrieve a single room list that contains all the rooms for a location or
department by supplying its email address by using the GetRooms EWS Managed API
method or the GetRooms EWS operation. When you have a collection of rooms
associated with a room list, you can then search through the collection to identify the
room or rooms you want, either by email address, or by looking for key words in the
name, such as "AV", or "Lab".
Get all room lists by using the EWS Managed
API
The following example shows how to get a list that contains all the room lists in your
organization by using the GetRoomLists method.
This example assumes that you have authenticated to an Exchange server and have
acquired an ExchangeService object named service.
C#
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:GetRoomLists />
</soap:Body>
</soap:Envelope>
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:GetRoomListsResponse ResponseClass="Success"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseCode>NoError</m:ResponseCode>
<m:RoomLists>
<t:Address>
<t:EmailAddress>[email protected]</t:EmailAddress>
<t:RoutingType>SMTP</t:RoutingType>
<t:MailboxType>PublicDL</t:MailboxType>
</t:Address>
<t:Address>
<t:EmailAddress>[email protected]</t:EmailAddress>
<t:RoutingType>SMTP</t:RoutingType>
<t:MailboxType>PublicDL</t:MailboxType>
</t:Address>
<t:Address>
<t:EmailAddress>[email protected]</t:EmailAddress>
<t:RoutingType>SMTP</t:RoutingType>
<t:MailboxType>PublicDL</t:MailboxType>
</t:Address>
</m:RoomLists>
</m:GetRoomListsResponse>
</s:Body>
</s:Envelope>
C#
System.Collections.ObjectModel.Collection<EmailAddress> myRoomAddresses =
service.GetRooms(myRoomList);
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:GetRooms>
<m:RoomList>
<t:EmailAddress>[email protected]</t:EmailAddress>
</m:RoomList>
</m:GetRooms>
</soap:Body>
</soap:Envelope>
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
Version="V2_9"
xmlns:h="http://scemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:GetRoomsResponse ResponseClass="Success"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://scemas.microsoft.com/exchange/services/2006/types">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Rooms>
<t:Room>
<t:Id>
<t:EmailAddress>[email protected]</t:EmailAddress>
<t:RoutingType>SMTP</t:RoutingType>
<t:MailboxType>Mailbox</t:MailboxType>
</t:Id>
</t:Room>
<t:Room>
<t:Id>
<t:EmailAddress>[email protected]</t:EmailAddress>
<t:RoutingType>SMTP</t:RoutingType>
<t:MailboxType>Mailbox</t:MailboxType>
</t:Id>
</t:Room>
<t:Room>
<t:Id>
<t:EmailAddress>[email protected]</t:EmailAddress>
<t:RoutingType>SMTP</t:RoutingType>
<t:MailboxType>Mailbox</t:MailboxType>
</t:Id>
</t:Room>
</m:Rooms>
</m:GetRoomsResponse>
</s:Body>
</s:Envelope>
See also
Calendars and EWS in Exchange
Learn how to get free/busy information and suggested meeting times by using the EWS
Managed API or EWS in Exchange.
Using the EWS Managed API or EWS to programmatically create a meeting and send
out meeting requests is great, but finding a time that works for all your attendees is
often a challenge. If you have to manually check to see when everyone is available, it
defeats the purpose of automating the task. Fortunately, the
ExchangeService.GetUserAvailability EWS Managed API method and the
GetUserAvailability EWS operation come to your rescue. You can use this method or
operation to query an Exchange server to find the best time to schedule a meeting or
just get free/busy information for attendees. You can get the free/busy information for a
list of attendees, or have your Exchange server find a meeting time for you, or both
This example assumes that you have authenticated to an Exchange server and have
acquired an ExchangeService object named service.
C#
attendees.Add(new AttendeeInfo()
SmtpAddress = "[email protected]",
AttendeeType = MeetingAttendeeType.Organizer
});
attendees.Add(new AttendeeInfo()
SmtpAddress = "[email protected]",
AttendeeType = MeetingAttendeeType.Required
});
availabilityOptions.GoodSuggestionThreshold = 49;
availabilityOptions.MaximumNonWorkHoursSuggestionsPerDay = 0;
availabilityOptions.MaximumSuggestionsPerDay = 2;
availabilityOptions.MeetingDuration = 60;
availabilityOptions.MinimumSuggestionQuality = SuggestionQuality.Good;
availabilityOptions.DetailedSuggestionsWindow = new
TimeWindow(DateTime.Now.AddDays(1), DateTime.Now.AddDays(2));
availabilityOptions.RequestedFreeBusyView = FreeBusyViewType.FreeBusy;
GetUserAvailabilityResults results =
service.GetUserAvailability(attendees,
availabilityOptions.DetailedSuggestionsWindow,
AvailabilityData.FreeBusyAndSuggestions,
availabilityOptions);
Console.WriteLine();
Console.WriteLine("\t{0} - {1}\n",
timeSuggestion.MeetingTime.ToShortTimeString(),
timeSuggestion.MeetingTime.Add(TimeSpan.FromMinutes(availabilityOptions.Meet
ingDuration)).ToShortTimeString());
int i = 0;
i++;
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:TimeZoneContext>
<t:TimeZoneDefinition Name="(UTC-08:00) Pacific Time (US &amp;
Canada)" Id="Pacific Standard Time">
<t:Periods>
</t:Periods>
<t:TransitionsGroups>
<t:TransitionsGroup Id="0">
<t:RecurringDayTransition>
<t:To Kind="Period">Dlt/1</t:To>
<t:TimeOffset>P0DT2H0M0.0S</t:TimeOffset>
<t:Month>4</t:Month>
<t:DayOfWeek>Sunday</t:DayOfWeek>
<t:Occurrence>1</t:Occurrence>
</t:RecurringDayTransition>
<t:RecurringDayTransition>
<t:To Kind="Period">Std</t:To>
<t:TimeOffset>P0DT2H0M0.0S</t:TimeOffset>
<t:Month>10</t:Month>
<t:DayOfWeek>Sunday</t:DayOfWeek>
<t:Occurrence>-1</t:Occurrence>
</t:RecurringDayTransition>
</t:TransitionsGroup>
<t:TransitionsGroup Id="1">
<t:RecurringDayTransition>
<t:To Kind="Period">Dlt/2007</t:To>
<t:TimeOffset>P0DT2H0M0.0S</t:TimeOffset>
<t:Month>3</t:Month>
<t:DayOfWeek>Sunday</t:DayOfWeek>
<t:Occurrence>2</t:Occurrence>
</t:RecurringDayTransition>
<t:RecurringDayTransition>
<t:To Kind="Period">Std</t:To>
<t:TimeOffset>P0DT2H0M0.0S</t:TimeOffset>
<t:Month>11</t:Month>
<t:DayOfWeek>Sunday</t:DayOfWeek>
<t:Occurrence>1</t:Occurrence>
</t:RecurringDayTransition>
</t:TransitionsGroup>
</t:TransitionsGroups>
<t:Transitions>
<t:Transition>
<t:To Kind="Group">0</t:To>
</t:Transition>
<t:AbsoluteDateTransition>
<t:To Kind="Group">1</t:To>
<t:DateTime>2007-01-01T08:00:00.000Z</t:DateTime>
</t:AbsoluteDateTransition>
</t:Transitions>
</t:TimeZoneDefinition>
</t:TimeZoneContext>
</soap:Header>
<soap:Body>
<m:GetUserAvailabilityRequest>
<m:MailboxDataArray>
<t:MailboxData>
<t:Email>
<t:Address>[email protected]</t:Address>
</t:Email>
<t:AttendeeType>Organizer</t:AttendeeType>
<t:ExcludeConflicts>false</t:ExcludeConflicts>
</t:MailboxData>
<t:MailboxData>
<t:Email>
<t:Address>[email protected]</t:Address>
</t:Email>
<t:AttendeeType>Required</t:AttendeeType>
<t:ExcludeConflicts>false</t:ExcludeConflicts>
</t:MailboxData>
</m:MailboxDataArray>
<t:FreeBusyViewOptions>
<t:TimeWindow>
<t:StartTime>2014-02-13T00:00:00</t:StartTime>
<t:EndTime>2014-02-14T00:00:00</t:EndTime>
</t:TimeWindow>
<t:MergedFreeBusyIntervalInMinutes>30</t:MergedFreeBusyIntervalInMinutes>
<t:RequestedView>FreeBusy</t:RequestedView>
</t:FreeBusyViewOptions>
<t:SuggestionsViewOptions>
<t:GoodThreshold>49</t:GoodThreshold>
<t:MaximumResultsByDay>2</t:MaximumResultsByDay>
<t:MaximumNonWorkHourResultsByDay>0</t:MaximumNonWorkHourResultsByDay>
<t:MeetingDurationInMinutes>60</t:MeetingDurationInMinutes>
<t:MinimumSuggestionQuality>Good</t:MinimumSuggestionQuality>
<t:DetailedSuggestionsWindow>
<t:StartTime>2014-02-13T00:00:00</t:StartTime>
<t:EndTime>2014-02-14T00:00:00</t:EndTime>
</t:DetailedSuggestionsWindow>
</t:SuggestionsViewOptions>
</m:GetUserAvailabilityRequest>
</soap:Body>
</soap:Envelope>
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<GetUserAvailabilityResponse
xmlns="https://schemas.microsoft.com/exchange/services/2006/messages">
<FreeBusyResponseArray>
<FreeBusyResponse>
<ResponseMessage ResponseClass="Success">
<ResponseCode>NoError</ResponseCode>
</ResponseMessage>
<FreeBusyView>
<FreeBusyViewType
xmlns="https://schemas.microsoft.com/exchange/services/2006/types">FreeBusy<
/FreeBusyViewType>
<CalendarEventArray
xmlns="https://schemas.microsoft.com/exchange/services/2006/types">
<CalendarEvent>
<StartTime>2014-02-13T08:00:00</StartTime>
<EndTime>2014-02-13T10:00:00</EndTime>
<BusyType>Free</BusyType>
</CalendarEvent>
<CalendarEvent>
<StartTime>2014-02-13T11:00:00</StartTime>
<EndTime>2014-02-13T12:00:00</EndTime>
<BusyType>Busy</BusyType>
</CalendarEvent>
</CalendarEventArray>
<WorkingHours
xmlns="https://schemas.microsoft.com/exchange/services/2006/types">
<TimeZone>
<Bias>480</Bias>
<StandardTime>
<Bias>0</Bias>
<Time>02:00:00</Time>
<DayOrder>1</DayOrder>
<Month>11</Month>
<DayOfWeek>Sunday</DayOfWeek>
</StandardTime>
<DaylightTime>
<Bias>-60</Bias>
<Time>02:00:00</Time>
<DayOrder>2</DayOrder>
<Month>3</Month>
<DayOfWeek>Sunday</DayOfWeek>
</DaylightTime>
</TimeZone>
<WorkingPeriodArray>
<WorkingPeriod>
<StartTimeInMinutes>480</StartTimeInMinutes>
<EndTimeInMinutes>1020</EndTimeInMinutes>
</WorkingPeriod>
</WorkingPeriodArray>
</WorkingHours>
</FreeBusyView>
</FreeBusyResponse>
<FreeBusyResponse>
<ResponseMessage ResponseClass="Success">
<ResponseCode>NoError</ResponseCode>
</ResponseMessage>
<FreeBusyView>
<FreeBusyViewType
xmlns="https://schemas.microsoft.com/exchange/services/2006/types">FreeBusy<
/FreeBusyViewType>
<CalendarEventArray
xmlns="https://schemas.microsoft.com/exchange/services/2006/types">
<CalendarEvent>
<StartTime>2014-02-12T00:00:00</StartTime>
<EndTime>2014-02-13T00:00:00</EndTime>
<BusyType>Free</BusyType>
</CalendarEvent>
<CalendarEvent>
<StartTime>2014-02-13T08:00:00</StartTime>
<EndTime>2014-02-13T10:00:00</EndTime>
<BusyType>Free</BusyType>
</CalendarEvent>
<CalendarEvent>
<StartTime>2014-02-13T11:00:00</StartTime>
<EndTime>2014-02-13T12:00:00</EndTime>
<BusyType>Busy</BusyType>
</CalendarEvent>
<CalendarEvent>
<StartTime>2014-02-13T15:00:00</StartTime>
<EndTime>2014-02-13T16:00:00</EndTime>
<BusyType>Tentative</BusyType>
</CalendarEvent>
</CalendarEventArray>
<WorkingHours
xmlns="https://schemas.microsoft.com/exchange/services/2006/types">
<TimeZone>
<Bias>480</Bias>
<StandardTime>
<Bias>0</Bias>
<Time>02:00:00</Time>
<DayOrder>1</DayOrder>
<Month>11</Month>
<DayOfWeek>Sunday</DayOfWeek>
</StandardTime>
<DaylightTime>
<Bias>-60</Bias>
<Time>02:00:00</Time>
<DayOrder>2</DayOrder>
<Month>3</Month>
<DayOfWeek>Sunday</DayOfWeek>
</DaylightTime>
</TimeZone>
<WorkingPeriodArray>
<WorkingPeriod>
<StartTimeInMinutes>540</StartTimeInMinutes>
<EndTimeInMinutes>1020</EndTimeInMinutes>
</WorkingPeriod>
</WorkingPeriodArray>
</WorkingHours>
</FreeBusyView>
</FreeBusyResponse>
</FreeBusyResponseArray>
<SuggestionsResponse>
<ResponseMessage ResponseClass="Success">
<ResponseCode>NoError</ResponseCode>
</ResponseMessage>
<SuggestionDayResultArray>
<SuggestionDayResult
xmlns="https://schemas.microsoft.com/exchange/services/2006/types">
<Date>2014-02-13T00:00:00</Date>
<DayQuality>Excellent</DayQuality>
<SuggestionArray>
<Suggestion>
<MeetingTime>2014-02-13T09:00:00</MeetingTime>
<IsWorkTime>true</IsWorkTime>
<SuggestionQuality>Excellent</SuggestionQuality>
<AttendeeConflictDataArray>
<IndividualAttendeeConflictData>
<BusyType>Free</BusyType>
</IndividualAttendeeConflictData>
<IndividualAttendeeConflictData>
<BusyType>Free</BusyType>
</IndividualAttendeeConflictData>
</AttendeeConflictDataArray>
</Suggestion>
<Suggestion>
<MeetingTime>2014-02-13T09:30:00</MeetingTime>
<IsWorkTime>true</IsWorkTime>
<SuggestionQuality>Excellent</SuggestionQuality>
<AttendeeConflictDataArray>
<IndividualAttendeeConflictData>
<BusyType>Free</BusyType>
</IndividualAttendeeConflictData>
<IndividualAttendeeConflictData>
<BusyType>Free</BusyType>
</IndividualAttendeeConflictData>
</AttendeeConflictDataArray>
</Suggestion>
</SuggestionArray>
</SuggestionDayResult>
</SuggestionDayResultArray>
</SuggestionsResponse>
</GetUserAvailabilityResponse>
</s:Body>
</s:Envelope>
See also
Calendars and EWS in Exchange
Find out how to propose new meeting times from your Exchange client application by
using EWS in Exchange.
The propose new time feature enables attendees to propose new meeting times to the
meeting organizer as part of the Exchange calendar workflow. When an attendee
proposes a new meeting, the organizer can use the proposed new meeting time to
update the meeting and send updates to all attendees. Before you can enable attendees
to propose new meeting times, you need to determine whether the organizer allows for
new time proposals. This article describes how to determine whether you can propose a
new time and how to use EWS to propose a new time.
7 Note
1. Use the FindItem EWS operation (or the Folder.FindItems EWS Managed API
method) to find the target meeting request or calendar item. Alternatively, you can
use the SyncFolderItems EWS operation to get the identifier of the target
meeting request or calendar item.
2. Parse the results of the FindItem operation (or Folder.FindItems method) to get
the item identifier of the meeting item.
3. Use the GetItem EWS operation to get the response objects for the meeting.
The following XML shows what is sent to request the response objects on an item.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages">
<soap:Header>
<t:MailboxCulture>en-US</t:MailboxCulture>
</soap:Header>
<soap:Body>
<m:GetItem>
<m:ItemShape>
<t:BaseShape>IdOnly</t:BaseShape>
<t:AdditionalProperties>
<t:FieldURI FieldURI="item:ResponseObjects"/>
<t:FieldURI FieldURI="item:Subject"/>
<t:FieldURI FieldURI="calendar:Start"/>
<t:FieldURI FieldURI="calendar:End"/>
</t:AdditionalProperties>
</m:ItemShape>
<m:ItemIds>
</m:ItemIds>
</m:GetItem>
</soap:Body>
</soap:Envelope>
The GetItem operation response will look similar to the following XML if you request the
item identifier, the meeting start and end time, the response object collection, and if the
organizer allows for proposed changes to the meeting time. The response object
collection, which is represented by the ResponseObjects element, contains the set of
responses that are valid for the calendar item. The ProposeNewTime element is a
response object that indicates that the user can propose a new time for the meeting.
The AcceptItem , TentativelyAcceptItem , and DeclineItem elements represent the
response objects that you can use to propose a new meeting time to the meeting
organizer.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="15"
MinorVersion="0"
MajorBuildNumber="815"
MinorBuildNumber="6"
Version="V2_7"
xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance"/>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:GetItemResponse
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:GetItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:MeetingRequest>
<t:ResponseObjects>
<t:AcceptItem/>
<t:TentativelyAcceptItem/>
<t:DeclineItem/>
<t:ProposeNewTime/>
<t:ReplyToItem/>
<t:ReplyAllToItem/>
<t:ForwardItem/>
</t:ResponseObjects>
<t:Start>2013-11-09T17:00:00Z</t:Start>
<t:End>2013-11-09T17:30:00Z</t:End>
</t:MeetingRequest>
</m:Items>
</m:GetItemResponseMessage>
</m:ResponseMessages>
</m:GetItemResponse>
</s:Body>
</s:Envelope>
XML
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages">
<soap:Header>
<t:RequestServerVersion Version="Exchange2013"/>
</soap:Header>
<soap:Body>
<m:CreateItem>
<m:Items>
<t:AcceptItem>
<t:ReferenceItemId Id="AAMkADEzOTExYjJkL1AAA="
ChangeKey="CwAAAB/G6X"/>
<t:ProposedStart>2013-11-28T04:00:00Z</t:ProposedStart>
<t:ProposedEnd>2013-11-28T04:30:00Z</t:ProposedEnd>
</t:AcceptItem>
</m:Items>
</m:CreateItem>
</soap:Body>
</soap:Envelope>
The response to this request contains the identifier of the calendar item that was added
to the attendee's calendar and a copy of the meeting request that was placed in the
attendee's Deleted Items folder. The response message with the new time proposal was
also saved in the attendee's Sent Items folder (you will need to find the meeting
response message to get a handle on it).
XML
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="15"
MinorVersion="0"
MajorBuildNumber="815"
MinorBuildNumber="6"
Version="V2_7"
xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance"/>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:CreateItemResponse
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:CreateItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:CalendarItem>
</t:CalendarItem>
<t:MeetingRequest>
</t:MeetingRequest>
</m:Items>
</m:CreateItemResponseMessage>
</m:ResponseMessages>
</m:CreateItemResponse>
</s:Body>
</s:Envelope>
The organizer will receive a MeetingResponse message when the attendee responds
with a proposed new meeting time. The MeetingResponse message contains the
proposed new meeting start time and end time, and the identifier of the associated
calendar item in the organizer's calendar. The organizer can use that information to
update their existing calendar item for the meeting. The following is the workflow for
the organizer to respond to a MeetingResponse message that proposes a new meeting
time:
2. Get the organizer's existing calendar item for the meeting by using the EWS
identifier returned in the AssociatedCalendarItemId element.
3. Compare the original start and end time with the proposed new meeting time. If
the proposed new meeting time is acceptable to the organizer, go to step 4.
Otherwise, the meeting organizer can either ignore the proposed meeting time, or
send an email response to the attendee that proposed the new meeting time.
5. The organizer can then update their meeting with the new proposed meeting
times and send the updates to all attendees by using the UpdateItem EWS
operation (or the Appointment.Update EWS Managed API method).
The following figure shows the process that occurs between the meeting organizer, the
attendee, and the Exchange server that handled the EWS calls.
See also
Calendars and EWS in Exchange
Learn how to create, get, update, or delete batches of calendar items in a single call by
using the EWS Managed API or EWS in Exchange.
You can use the EWS Managed API or EWS to work with batches of appointments and
meetings to reduce the number of calls a client makes to an Exchange server. When you
use the EWS Managed API to create, get, update, and delete a batch of calendar items,
you use ExchangeService object methods, whereas when you work with single
calendar items, you use Appointment object methods. If you are using EWS, you use
the same operation for batch calls that you use for single calls.
Table 1. EWS Managed API methods and EWS operations for working with batches of
calendar items
In order to… Use this EWS Managed API Use this EWS
method operation
In this article, you'll learn how to complete basic tasks for batches of calendar items by
using the EWS Managed API or EWS.
Note that in the EWS Managed API examples in this article, if the methods are called
sequentially, you can create, get, update, and then delete a batch of calendar items.
C#
BatchDeleteCalendarItemsTwice(service, itemIds);
This example assumes that you have authenticated to an Exchange server and have
acquired an ExchangeService object named service.
C#
appt1.Start = DateTime.Now.AddDays(2);
appt1.End = appt1.Start.AddHours(3);
appt1.ReminderMinutesBeforeStart = 30;
recurrAppt2.Start = DateTime.Now.AddDays(1);
recurrAppt2.End = recurrAppt2.Start.AddHours(1);
arecurrAppt2.ReminderMinutesBeforeStart = 30;
recurrAppt2.Recurrence = new
Recurrence.WeeklyPattern(recurrAppt2.Start.Date, 1, dow);
recurrAppt2.Recurrence.StartDate = recurrAppt2.Start.Date;
recurrAppt2.Recurrence.NumberOfOccurrences = 10;
meeting3.Body = "Let's get together to finish all the methods and unit
tests for the ContosoLive project.";
meeting3.Start = DateTime.Now.AddDays(3);
meeting3.End = meeting3.Start.AddHours(6);
meeting3.RequiredAttendees.Add("[email protected]");
meeting3.RequiredAttendees.Add("[email protected]");
meeting3.RequiredAttendees.Add("[email protected]");
meeting3.ReminderMinutesBeforeStart = 30;
// Note that multiple calls to the Exchange server might be made when
Appointment objects have attachments.
// Note also that the the ID of the item collection passed as the first
parameter to CreateItems is set on return.
ServiceResponseCollection<ServiceResponse> response =
service.CreateItems(calendarItems,
WellKnownFolderName.Calendar,
MessageDisposition.SendAndSaveCopy,
SendInvitationsMode.SendToAllAndSaveCopy);
if (response.OverallResult == ServiceResult.Success)
itemIds.Add(appt.Id);
int counter = 1;
counter++;
return itemIds;
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:TimeZoneContext>
<t:TimeZoneDefinition Id="Pacific Standard Time" />
</t:TimeZoneContext>
</soap:Header>
<soap:Body>
<m:CreateItem MessageDisposition="SendAndSaveCopy"
SendMeetingInvitations="SendToAllAndSaveCopy">
<m:SavedItemFolderId>
</m:SavedItemFolderId>
<m:Items>
<t:CalendarItem>
<t:ReminderDueBy>2014-01-07T12:13:40.333-08:00</t:ReminderDueBy>
<t:Start>2014-01-08T13:13:37.717-08:00</t:Start>
<t:End>2014-01-08T16:13:37.717-08:00</t:End>
</t:CalendarItem>
<t:CalendarItem>
<t:Start>2014-01-07T13:13:40.333-08:00</t:Start>
<t:End>2014-01-07T14:13:40.333-08:00</t:End>
<t:Recurrence>
<t:WeeklyRecurrence>
<t:Interval>1</t:Interval>
<t:DaysOfWeek>Tuesday</t:DaysOfWeek>
</t:WeeklyRecurrence>
<t:NumberedRecurrence>
<t:StartDate>2014-01-07-08:00</t:StartDate>
<t:NumberOfOccurrences>10</t:NumberOfOccurrences>
</t:NumberedRecurrence>
</t:Recurrence>
</t:CalendarItem>
<t:CalendarItem>
<t:Subject>Code Blast</t:Subject>
<t:ReminderMinutesBeforeStart>30</t:ReminderMinutesBeforeStart>
<t:Start>2014-01-09T13:13:44.998-08:00</t:Start>
<t:End>2014-01-09T19:13:44.998-08:00</t:End>
<t:Location>The lounge</t:Location>
<t:RequiredAttendees>
<t:Attendee>
<t:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:Mailbox>
</t:Attendee>
<t:Attendee>
<t:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:Mailbox>
</t:Attendee>
<t:Attendee>
<t:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:Mailbox>
</t:Attendee>
</t:RequiredAttendees>
</t:CalendarItem>
</m:Items>
</m:CreateItem>
</soap:Body>
</soap:Envelope>
Note that the calendar items are either meetings or appointments, or single instances or
a recurring series, according to the element values of each calendar item passed to the
Exchange server.
The following is the response from the server. The ItemId and ChangeKey attributes are
shortened for readability.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:CreateItemResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:CreateItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:CalendarItem>
</t:CalendarItem>
</m:Items>
</m:CreateItemResponseMessage>
<m:CreateItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:CalendarItem>
</t:CalendarItem>
</m:Items>
</m:CreateItemResponseMessage>
<m:CreateItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:CalendarItem>
</t:CalendarItem>
</m:Items>
</m:CreateItemResponseMessage>
</m:ResponseMessages>
</m:CreateItemResponse>
</s:Body>
</s:Envelope>
This example assumes that you have authenticated to an Exchange server and have
acquired an ExchangeService object named service.
C#
AppointmentSchema.Subject,
AppointmentSchema.Body,
AppointmentSchema.ReminderMinutesBeforeStart,
AppointmentSchema.Start,
AppointmentSchema.End,
AppointmentSchema.AppointmentType,
AppointmentSchema.Location,
AppointmentSchema.RequiredAttendees);
ServiceResponseCollection<GetItemResponse> response =
service.BindToItems(itemIds, appointmentProps);
calendarItems.Add(appointmentItem);
if (response.OverallResult == ServiceResult.Success)
Console.WriteLine("\r\n");
else
int counter = 1;
Console.WriteLine("\r\n");
counter++;
return calendarItems;
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:TimeZoneContext>
<t:TimeZoneDefinition Id="Pacific Standard Time" />
</t:TimeZoneContext>
</soap:Header>
<soap:Body>
<m:GetItem>
<m:ItemShape>
<t:BaseShape>IdOnly</t:BaseShape>
<t:AdditionalProperties>
</t:AdditionalProperties>
</m:ItemShape>
<m:ItemIds>
</m:ItemIds>
</m:GetItem>
</soap:Body>
</soap:Envelope>
The server responds to the GetItem request with a GetItemResponse message with
the requested properties for each item, as shown in the following example.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:GetItemResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:GetItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:CalendarItem>
<t:Body BodyType="HTML">
&lt;html&gt;
&lt;head&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;/body&gt;
&lt;/html&gt;
</t:Body>
<t:ReminderMinutesBeforeStart>30</t:ReminderMinutesBeforeStart>
<t:Start>2014-01-19T18:59:07Z</t:Start>
<t:End>2014-01-19T21:59:07Z</t:End>
<t:CalendarItemType>Single</t:CalendarItemType>
</t:CalendarItem>
</m:Items>
</m:GetItemResponseMessage>
<m:GetItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:CalendarItem>
<t:Body BodyType="HTML">
&lt;html&gt;
&lt;head&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;/body&gt;
&lt;/html&gt;
</t:Body>
<t:ReminderMinutesBeforeStart>15</t:ReminderMinutesBeforeStart>
<t:Start>2014-01-18T18:59:07Z</t:Start>
<t:End>2014-01-18T19:59:07Z</t:End>
<t:CalendarItemType>RecurringMaster</t:CalendarItemType>
</t:CalendarItem>
</m:Items>
</m:GetItemResponseMessage>
<m:GetItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:CalendarItem>
<t:Subject>Code Blast</t:Subject>
<t:Body BodyType="HTML">
&lt;html&gt;
&lt;head&gt;
&lt;/head&gt;
&lt;body&gt;
Let's get together to finish all the methods and unit tests
for the ContosoLive project.
&lt;/body&gt;
&lt;/html&gt;
</t:Body>
<t:ReminderMinutesBeforeStart>30</t:ReminderMinutesBeforeStart>
<t:Start>2014-01-20T18:59:08Z</t:Start>
<t:End>2014-01-21T00:59:08Z</t:End>
<t:Location>The lounge</t:Location>
<t:CalendarItemType>Single</t:CalendarItemType>
<t:RequiredAttendees>
<t:Attendee>
<t:Mailbox>
<t:Name>[email protected]</t:Name>
<t:EmailAddress>[email protected]</t:EmailAddress>
<t:RoutingType>SMTP</t:RoutingType>
</t:Mailbox>
<t:ResponseType>Unknown</t:ResponseType>
</t:Attendee>
<t:Attendee>
<t:Mailbox>
<t:Name>[email protected]</t:Name>
<t:EmailAddress>[email protected]</t:EmailAddress>
<t:RoutingType>SMTP</t:RoutingType>
</t:Mailbox>
<t:ResponseType>Unknown</t:ResponseType>
</t:Attendee>
<t:Attendee>
<t:Mailbox>
<t:Name>[email protected]</t:Name>
<t:EmailAddress>[email protected]</t:EmailAddress>
<t:RoutingType>SMTP</t:RoutingType>
</t:Mailbox>
<t:ResponseType>Unknown</t:ResponseType>
</t:Attendee>
</t:RequiredAttendees>
</t:CalendarItem>
</m:Items>
</m:GetItemResponseMessage>
</m:ResponseMessages>
</m:GetItemResponse>
</s:Body>
</s:Envelope>
This example assumes that you have authenticated to an Exchange server and have
acquired an ExchangeService object named service.
C#
public static Collection<ItemId> BatchUpdateCalendarItems(ExchangeService
service, Collection<Appointment> calendarItems)
int i = 1;
i++;
itemIds.Add(appointment.Id);
ServiceResponseCollection<UpdateItemResponse> response =
service.UpdateItems(calendarItems,
WellKnownFolderName.Calendar,
ConflictResolutionMode.AutoResolve,
MessageDisposition.SendAndSaveCopy,
SendInvitationsOrCancellationsMode.SendToChangedAndSaveCopy);
if (response.OverallResult == ServiceResult.Success)
else
i = 1;
Console.WriteLine("ErrorMessage: {0}\r\n",
srvResponse.ErrorMessage);
i++;
return itemIds;
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:TimeZoneContext>
<t:TimeZoneDefinition Id="Pacific Standard Time" />
</t:TimeZoneContext>
</soap:Header>
<soap:Body>
<m:UpdateItem MessageDisposition="SendAndSaveCopy"
ConflictResolution="AutoResolve"
SendMeetingInvitationsOrCancellations="SendToChangedAndSaveCopy">
<m:SavedItemFolderId>
</m:SavedItemFolderId>
<m:ItemChanges>
<t:ItemChange>
<t:Updates>
<t:SetItemField>
<t:CalendarItem>
</t:Subject>
</t:CalendarItem>
</t:SetItemField>
</t:Updates>
</t:ItemChange>
<t:ItemChange>
<t:Updates>
<t:SetItemField>
<t:CalendarItem>
</t:CalendarItem>
</t:SetItemField>
</t:Updates>
</t:ItemChange>
<t:ItemChange>
<t:Updates>
<t:SetItemField>
<t:CalendarItem>
</t:CalendarItem>
</t:SetItemField>
</t:Updates>
</t:ItemChange>
</m:ItemChanges>
</m:UpdateItem>
</soap:Body>
</soap:Envelope>
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
Version="V2_8"
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:UpdateItemResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:UpdateItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:CalendarItem>
</t:CalendarItem>
</m:Items>
<m:ConflictResults>
<t:Count>1</t:Count>
</m:ConflictResults>
</m:UpdateItemResponseMessage>
<m:UpdateItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:CalendarItem>
</t:CalendarItem>
</m:Items>
<m:ConflictResults>
<t:Count>1</t:Count>
</m:ConflictResults>
</m:UpdateItemResponseMessage>
<m:UpdateItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:CalendarItem>
</t:CalendarItem>
</m:Items>
<m:ConflictResults>
<t:Count>1</t:Count>
</m:ConflictResults>
</m:UpdateItemResponseMessage>
</m:ResponseMessages>
</m:UpdateItemResponse>
</s:Body>
</s:Envelope>
C#
ServiceResponseCollection<ServiceResponse> response =
service.DeleteItems(itemIds,
DeleteMode.MoveToDeletedItems,
SendCancellationsMode.SendToAllAndSaveCopy,
AffectedTaskOccurrence.AllOccurrences);
int counter = 1;
counter++;
response = service.DeleteItems(itemIds,
DeleteMode.MoveToDeletedItems,
SendCancellationsMode.SendToAllAndSaveCopy,
AffectedTaskOccurrence.AllOccurrences);
counter = 1;
counter++;
When the DeleteItems method is called the second time, no exception is thrown, but
the server returns an ErrorItemNotFound error in the result.
Delete calendar items in batches by using EWS
You can delete calendar items in batches by using the DeleteItem EWS operation, as
shown in the following code example. This is also the XML request that the EWS
Managed API sends when you use the EWS Managed API to delete calendar items in
batches.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:TimeZoneContext>
<t:TimeZoneDefinition Id="Pacific Standard Time" />
</t:TimeZoneContext>
</soap:Header>
<soap:Body>
<m:DeleteItem DeleteType="MoveToDeletedItems"
AffectedTaskOccurrences="AllOccurrences"
SendMeetingCancellations="SendToAllAndSaveCopy">
<m:ItemIds>
</m:ItemIds>
</m:DeleteItem>
</soap:Body>
</soap:Envelope>
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:DeleteItemResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:DeleteItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
</m:DeleteItemResponseMessage>
<m:DeleteItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
</m:DeleteItemResponseMessage>
<m:DeleteItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
</m:DeleteItemResponseMessage>
</m:ResponseMessages>
</m:DeleteItemResponse>
</s:Body>
</s:Envelope>
Note that if the DeleteItem request is made when the associated items have already
been deleted, no exception will be thrown, but the server will return an
ErrorItemNotFound error in the result. The following example shows the server
response to a DeleteItem request when the associated items have already been deleted.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:DeleteItemResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:DeleteItemResponseMessage ResponseClass="Error">
<m:ResponseCode>ErrorItemNotFound</m:ResponseCode>
<m:DescriptiveLinkKey>0</m:DescriptiveLinkKey>
</m:DeleteItemResponseMessage>
<m:DeleteItemResponseMessage ResponseClass="Error">
<m:ResponseCode>ErrorItemNotFound</m:ResponseCode>
<m:DescriptiveLinkKey>0</m:DescriptiveLinkKey>
</m:DeleteItemResponseMessage>
<m:DeleteItemResponseMessage ResponseClass="Error">
<m:ResponseCode>ErrorItemNotFound</m:ResponseCode>
<m:DescriptiveLinkKey>0</m:DescriptiveLinkKey>
</m:DeleteItemResponseMessage>
</m:ResponseMessages>
</m:DeleteItemResponse>
</s:Body>
</s:Envelope>
To verify the success of a batch process by using the EWS Managed API, you can check
that the OverallResult property of the ServiceResponseCollection is equal to
ServiceResult.Success . If so, all the calendar items were processed successfully. If the
OverallResult is not equal to ServiceResult.Success, one or more of the calendar items
were not processed successfully. Each of the objects returned in the
ServiceResponseCollection contains the following properties:
ErrorCode
ErrorDetails
ErrorMessage
ErrorProperties
Result
These properties contain information about why the calendar items could not be
processed as requested. The examples in this article print out the Result, ErrorCode, and
ErrorMessage for each failed item. You can use these results to investigate the issue.
For EWS, to verify the success of a batched process, check the ResponseClass attribute
for each item being processed. The following is the basic structure of the
ResponseMessageType, the base type from which all response messages are derived.
XML
<MessageText/>
<ResponseCode/>
<DescriptiveLinkKey/>
<MessageXml/>
</ResponseMessage>
The ResponseClass attribute is set to Success if the calendar item was processed
successfully, or Error if it was not processed successfully. For calendar items, you will not
encounter a Warning during batch processing. If the ResponseClass is Success, the
ResponseCode element that follows is also always set to NoError. If the
ResponseClass is Error, you need to check the values of the MessageText ,
ResponseCode, and MessageXml elements to determine what caused the problem.
DescriptiveLinkKey is currently unused.
See also
Calendars and EWS in Exchange
Recurring masters
Occurrences in a series
In this article, we'll look at the three types of calendar items that are part of a recurring
series.
It's helpful to understand how recurring series are implemented on the Exchange server.
Instead of creating a separate distinct item for each occurrence in a recurring series, the
server creates only one actual item in the calendar, known as the recurring master. The
format of a recurring master is very similar to a non-recurring appointment, with the
addition of recurrence pattern information. The server then generates occurrences
based on the recurrence pattern in response to client requests for appointment
information, using a process called expansion. These generated occurrences are not
permanently stored on the server. This is important to understand because the way that
you search for calendar items determines what information you receive and whether
expansion occurs.
Recurrence patterns
The key piece to a recurring series that makes expansion possible is the recurrence
pattern. The recurrence pattern is found on the recurring master, and describes a set of
criteria for calculating occurrences based on the date and time of the recurring master.
Recurrence.DailyPattern
DailyRecurrence
Repeat every day.
Repeat every other day.
Recurrence.MonthlyPattern
AbsoluteMonthlyRecurrence Repeat every month on
the tenth day of the
month.
Repeat every other
month on the twenty-
first day of the month.
Recurrence.RelativeMonthlyPattern RelativeMonthlyRecurrence
Repeat on the second
Tuesday of every month.
Repeat on the third
Thursday of the month
every three months.
Recurrence.RelativeYearlyPattern
RelativeYearlyRecurrence
Repeat on the first
Monday of August every
year.
Recurrence.WeeklyPattern
WeeklyRecurrence
Repeat every Monday.
Repeat every Tuesday
and Thursday every
other week.
Recurrence.YearlyPattern
AbsoluteYearlyRecurrence
Repeat on September
1st every year.
The other important piece of information for a recurrence pattern is when the
recurrence ends. This can be expressed as either a set number of occurrences, as an end
date, or as having no end.
Recurrence.EndDate
EndDateRecurrence
The last occurrence in the
series falls on or before the
date specified by this property
or element.
Recurrence.HasEnd
NoEndRecurrence
The series has no end.
Recurrence.NeverEnds
ExchangeService.FindItems
FindItem operation No Non-recurring
with an appointments
IndexedPageItemView and recurring
element or master
FractionalPageItemView appointments
element
Sadie has just signed her son up for swim team. The team has practice every Wednesday
morning at 8:30 AM, starting July 2, with the last practice being on August 6. Not
wanting to forget about practice, Sadie adds a recurring appointment to her calendar to
remind her.
A quick look at a calendar shows that the team will have a total of six practices.
However, there aren't six distinct appointment items in the calendar. Instead, there is
just one recurring master appointment representing the series.
Now let's look at finding appointments on Sadie's calendar that occur within the month
of July. The following code example uses the FindItems method in the Exchange
Managed API to produce a non-expanded view of Sadie's calendar.
C#
AppointmentSchema.Location,
AppointmentSchema.Start,
AppointmentSchema.End,
AppointmentSchema.AppointmentType);
itemView.PropertySet = propSet;
filterList.Add(startFilter);
filterList.Add(endFilter);
Console.WriteLine(appt.Subject);
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:TimeZoneContext>
<t:TimeZoneDefinition Id="Pacific Standard Time" />
</t:TimeZoneContext>
</soap:Header>
<soap:Body>
<m:FindItem Traversal="Shallow">
<m:ItemShape>
<t:BaseShape>IdOnly</t:BaseShape>
<t:AdditionalProperties>
</t:AdditionalProperties>
</m:ItemShape>
<m:Restriction>
<t:And>
<t:IsGreaterThan>
<t:FieldURIOrConstant>
</t:FieldURIOrConstant>
</t:IsGreaterThan>
<t:IsLessThan>
<t:FieldURIOrConstant>
</t:FieldURIOrConstant>
</t:IsLessThan>
</t:And>
</m:Restriction>
<m:ParentFolderIds>
</m:ParentFolderIds>
</m:FindItem>
</soap:Body>
</soap:Envelope>
The server's response includes only a single item, the recurring master, indicated by the
CalendarItemType element value of RecurringMaster. The value of the ItemId
element has been shortened for readability.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:FindItemResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:FindItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<t:Items>
<t:CalendarItem>
<t:Start>2014-07-02T15:30:00Z</t:Start>
<t:End>2014-07-02T17:00:00Z</t:End>
<t:CalendarItemType>RecurringMaster</t:CalendarItemType>
</t:CalendarItem>
</t:Items>
</m:RootFolder>
</m:FindItemResponseMessage>
</m:ResponseMessages>
</m:FindItemResponse>
</s:Body>
</s:Envelope>
Now let's compare with an expanded view. The following code example uses the
FindAppointments method in the EWS Managed API to create an expanded view of
Sadie's calendar.
C#
AppointmentSchema.Location,
AppointmentSchema.Start,
AppointmentSchema.End,
AppointmentSchema.AppointmentType);
calView.PropertySet = propSet;
FindItemsResults<Appointment> results =
service.FindAppointments(WellKnownFolderName.Calendar, calView);
Console.WriteLine(appt.Subject);
This code results in the following FindItem operation request with a CalendarView
element.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:TimeZoneContext>
<t:TimeZoneDefinition Id="Pacific Standard Time" />
</t:TimeZoneContext>
</soap:Header>
<soap:Body>
<m:FindItem Traversal="Shallow">
<m:ItemShape>
<t:BaseShape>IdOnly</t:BaseShape>
<t:AdditionalProperties>
</t:AdditionalProperties>
</m:ItemShape>
<m:ParentFolderIds>
</m:ParentFolderIds>
</m:FindItem>
</soap:Body>
</soap:Envelope>
This time, the server response includes five occurrences, one for each Wednesday in July.
The CalendarItemType elements on these items all have a value of Occurrence. Note
that the recurring master is not present in the response. The values of the ItemId
elements have been shortened for readability.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:FindItemResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:FindItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<t:Items>
<t:CalendarItem>
<t:Start>2014-07-02T15:30:00Z</t:Start>
<t:End>2014-07-02T17:00:00Z</t:End>
<t:CalendarItemType>Occurrence</t:CalendarItemType>
</t:CalendarItem>
<t:CalendarItem>
<t:Start>2014-07-09T15:30:00Z</t:Start>
<t:End>2014-07-09T17:00:00Z</t:End>
<t:CalendarItemType>Occurrence</t:CalendarItemType>
</t:CalendarItem>
<t:CalendarItem>
<t:Start>2014-07-16T15:30:00Z</t:Start>
<t:End>2014-07-16T17:00:00Z</t:End>
<t:CalendarItemType>Occurrence</t:CalendarItemType>
</t:CalendarItem>
<t:CalendarItem>
<t:Start>2014-07-23T15:30:00Z</t:Start>
<t:End>2014-07-23T17:00:00Z</t:End>
<t:CalendarItemType>Occurrence</t:CalendarItemType>
</t:CalendarItem>
<t:CalendarItem>
<t:Start>2014-07-30T15:30:00Z</t:Start>
<t:End>2014-07-30T17:00:00Z</t:End>
<t:CalendarItemType>Occurrence</t:CalendarItemType>
</t:CalendarItem>
</t:Items>
</m:RootFolder>
</m:FindItemResponseMessage>
</m:ResponseMessages>
</m:FindItemResponse>
</s:Body>
</s:Envelope>
After you have a recurring master, an occurrence, or an exception, you can always
retrieve the other related items. Given an occurrence or exception, you can retrieve the
recurring master, and vice versa.
In this section
Access a recurring series by using EWS in Exchange
Create a recurring series by using EWS in Exchange
See also
Calendars and EWS in Exchange
Learn how to access calendar items in a recurring series by using the EWS Managed API
or EWS in Exchange.
This example assumes that you have authenticated to an Exchange server and have
acquired an ExchangeService object named service.
C#
DateTime
startSearchDate,
DateTime
endSearchDate)
// Create a calendar view to search the calendar folder and specify the
properties to return.
AppointmentSchema.Start,
AppointmentSchema.IsRecurring,
AppointmentSchema.AppointmentType);
FindItemsResults<Appointment> findResults =
service.FindAppointments(WellKnownFolderName.Calendar, calView);
if (appt.AppointmentType == AppointmentType.Occurrence ||
appt.AppointmentType == AppointmentType.Exception)
foundAppointments.Add(appt);
else
return foundAppointments;
This example assumes that you have authenticated to an Exchange server and have
acquired an ExchangeService object named service.
C#
AppointmentType myAppointmentType,
DateTime startSearchDate)
searchFilter.Add(new
SearchFilter.IsGreaterThanOrEqualTo(AppointmentSchema.Start,
startSearchDate));
AppointmentSchema.Subject,
AppointmentSchema.Start,
AppointmentSchema.AppointmentType,
AppointmentSchema.IsRecurring);
// Get the appointment items from the server with the properties we
specified.
FindItemsResults<Item> findResults =
service.FindItems(WellKnownFolderName.Calendar, searchFilter, view);
// Add each of the appointments of the type you want to the collection.
if (appt.AppointmentType == myAppointmentType)
foundAppointments.Add(appt);
return foundAppointments;
Table 1. EWS Managed API property or method to use to get related recurrence
calendar items
The following code example shows how to get a recurring master, the first or last
occurrence in a series, or an occurrence given its index.
This example assumes that you have authenticated to an Exchange server and have
acquired an ExchangeService object named service.
C#
AppointmentSchema.Subject,
AppointmentSchema.FirstOccurrence,
AppointmentSchema.LastOccurrence,
AppointmentSchema.ModifiedOccurrences,
AppointmentSchema.DeletedOccurrences);
switch (calendarItem.AppointmentType)
case AppointmentType.RecurringMaster:
break;
case AppointmentType.Single:
case AppointmentType.Occurrence:
recurrMaster = Appointment.BindToRecurringMaster(service,
itemId, props);
break;
case AppointmentType.Exception:
recurrMaster = Appointment.BindToRecurringMaster(service,
itemId, props);
break;
recurrMaster.FirstOccurrence.ItemId.ToString().Substring(144),
recurrMaster.FirstOccurrence.Start.ToString());
recurrMaster.LastOccurrence.ItemId.ToString().Substring(144),
recurrMaster.LastOccurrence.Start.ToString());
recurrMaster.Id,
1, // Index
of first item is 1, not 0.
new
PropertySet(AppointmentSchema.AppointmentType,
AppointmentSchema.Start));
firstOccurrence.Start.ToString(),
recurrMaster.FirstOccurrence.Start.ToString());
The following XML shows the GetItem request used to return an occurrence in a series
specified by its index. Note that the ItemID of the recurring master has been shortened
for readability.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:GetItem>
<m:ItemShape>
<t:BaseShape>IdOnly</t:BaseShape>
<t:AdditionalProperties>
</t:AdditionalProperties>
</m:ItemShape>
<m:ItemIds>
</m:ItemIds>
</m:GetItem>
</soap:Body>
</soap:Envelope>
The server responds to the GetItem request with a GetItemResponse message that
includes a ResponseCode value of NoError, which indicates that the email was created
successfully, and the ItemId of the newly created message.
See also
Calendars and EWS in Exchange
Get appointments and meetings by using EWS in Exchange
Create a recurring series by using EWS
in Exchange
Article • 09/15/2021 • 6 minutes to read
Learn how to create recurring meetings by using the EWS Managed API or EWS in
Exchange.
Creating a recurring appointment or meeting isn't all that much different than creating a
single instance appointment or meeting. You just need to assign values to a few
additional recurrence-related properties. These are set on an
ExchangeService.Appointment object's Recurrence object (if you're using the EWS
Managed API), or the Recurrence child element of a CalendarItem element (if you're
using EWS). One thing to consider when you create a recurring, rather than a single-
instance meeting, is that the calendar item you create is the recurring master for a
series. A number of properties are set only on a recurring master; these properties can
help you find, modify, or delete individual instances in a series. For this reason, it might
be useful to keep track of the ID of the recurring master when you create a recurring
series.
Recurrence class
Recurrence Contains recurrence-related
The Recurrence class is the base class (RecurrenceType)
information, including the
for a derived pattern class, either recurrence pattern (daily,
IntervalPattern , weekly, monthly, and so on),
RelativeYearlyPattern , or start and end date, number of
YearlyPattern . occurrences, and so on.
FirstOccurrence property
FirstOccurrence
Contains the start and end
times and the item ID for the
first meeting in a series.
LastOccurrence property
LastOccurrence
Contains the start and end
times and the item ID for the
last meeting in a series.
ModifiedOccurrences property
ModifiedOccurrences Contains the set of all
meetings in the series that
have been modified from the
original recurrence pattern.
EWS Managed API class or property EWS XML element Description
DeletedOccurrences property
DeletedOccurrences
Contains the set of all
meetings in the series that
have been deleted from the
original recurrence pattern.
Because meetings are essentially appointments that include attendees, the code
examples in this article show how to create recurring meetings. If you want to create a
recurring appointment, you can modify the examples by removing code related to
attendees.
This example assumes that you have authenticated to an Exchange server and have
acquired an ExchangeService object named service. The method in this example
returns the item ID of the recurring series' recurring master.
C#
recurrMeeting.Start = DateTime.Now.AddDays(1);
recurrMeeting.End = recurrMeeting.Start.AddHours(1);
recurrMeeting.RequiredAttendees.Add("[email protected]");
recurrMeeting.RequiredAttendees.Add("[email protected]");
recurrMeeting.RequiredAttendees.Add("[email protected]");
recurrMeeting.ReminderMinutesBeforeStart = 30;
recurrMeeting.Recurrence = new
Recurrence.WeeklyPattern(recurrMeeting.Start.Date, 1, dow);
recurrMeeting.Recurrence.StartDate = recurrMeeting.Start.Date;
recurrMeeting.Recurrence.NumberOfOccurrences = 10;
recurrMeeting.Save(SendInvitationsMode.SendToAllAndSaveCopy);
// Retrieve the meeting subject and the properties that are set on a
recurring master when a recurring series is created.
AppointmentSchema.AppointmentType,
AppointmentSchema.Recurrence,
AppointmentSchema.FirstOccurrence,
AppointmentSchema.LastOccurrence,
AppointmentSchema.ModifiedOccurrences,
AppointmentSchema.DeletedOccurrences));
recurrMeeting.FirstOccurrence.ItemId.ToString().Substring(144));
recurrMeeting.LastOccurrence.ItemId.ToString().Substring(144));
return recurrMeeting.Id;
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:TimeZoneContext>
<t:TimeZoneDefinition Name="(UTC-08:00) Pacific Time (US &amp;
Canada)" Id="Pacific Standard Time">
<t:Periods>
</t:Periods>
<t:TransitionsGroups>
<t:TransitionsGroup Id="0">
<t:RecurringDayTransition>
<t:To Kind="Period">Dlt/1</t:To>
<t:TimeOffset>P0DT2H0M0.0S</t:TimeOffset>
<t:Month>4</t:Month>
<t:DayOfWeek>Sunday</t:DayOfWeek>
<t:Occurrence>1</t:Occurrence>
</t:RecurringDayTransition>
<t:RecurringDayTransition>
<t:To Kind="Period">Std</t:To>
<t:TimeOffset>P0DT2H0M0.0S</t:TimeOffset>
<t:Month>10</t:Month>
<t:DayOfWeek>Sunday</t:DayOfWeek>
<t:Occurrence>-1</t:Occurrence>
</t:RecurringDayTransition>
</t:TransitionsGroup>
<t:TransitionsGroup Id="1">
<t:RecurringDayTransition>
<t:To Kind="Period">Dlt/2007</t:To>
<t:TimeOffset>P0DT2H0M0.0S</t:TimeOffset>
<t:Month>3</t:Month>
<t:DayOfWeek>Sunday</t:DayOfWeek>
<t:Occurrence>2</t:Occurrence>
</t:RecurringDayTransition>
<t:RecurringDayTransition>
<t:To Kind="Period">Std</t:To>
<t:TimeOffset>P0DT2H0M0.0S</t:TimeOffset>
<t:Month>11</t:Month>
<t:DayOfWeek>Sunday</t:DayOfWeek>
<t:Occurrence>1</t:Occurrence>
</t:RecurringDayTransition>
</t:TransitionsGroup>
</t:TransitionsGroups>
<t:Transitions>
<t:Transition>
<t:To Kind="Group">0</t:To>
</t:Transition>
<t:AbsoluteDateTransition>
<t:To Kind="Group">1</t:To>
<t:DateTime>2007-01-01T08:00:00.000Z</t:DateTime>
</t:AbsoluteDateTransition>
</t:Transitions>
</t:TimeZoneDefinition>
</t:TimeZoneContext>
</soap:Header>
<soap:Body>
<m:CreateItem SendMeetingInvitations="SendToAllAndSaveCopy">
<m:Items>
<t:CalendarItem>
<t:ReminderMinutesBeforeStart>30</t:ReminderMinutesBeforeStart>
<t:Start>2014-03-08T13:21:32.868-08:00</t:Start>
<t:End>2014-03-08T14:21:32.868-08:00</t:End>
<t:RequiredAttendees>
<t:Attendee>
<t:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:Mailbox>
</t:Attendee>
<t:Attendee>
<t:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:Mailbox>
</t:Attendee>
<t:Attendee>
<t:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:Mailbox>
</t:Attendee>
</t:RequiredAttendees>
<t:Recurrence>
<t:WeeklyRecurrence>
<t:Interval>1</t:Interval>
<t:DaysOfWeek>Saturday</t:DaysOfWeek>
</t:WeeklyRecurrence>
<t:NumberedRecurrence>
<t:StartDate>2014-03-08-08:00</t:StartDate>
<t:NumberOfOccurrences>10</t:NumberOfOccurrences>
</t:NumberedRecurrence>
</t:Recurrence>
</t:CalendarItem>
</m:Items>
</m:CreateItem>
</soap:Body>
</soap:Envelope>
The following example shows the response XML that is returned by the CreateItem
operation.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
Version="V2_10"
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:CreateItemResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:CreateItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:CalendarItem>
</t:CalendarItem>
</m:Items>
</m:CreateItemResponseMessage>
</m:ResponseMessages>
</m:CreateItemResponse>
</s:Body>
</s:Envelope>
The following example shows the request XML that is generated when you use the
GetItem operation and the ItemId for the series you created, and request properties
only set on a recurring master to confirm that the ItemId returned by the server when
creating a recurring series is for a recurring master.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:GetItem>
<m:ItemShape>
<t:BaseShape>IdOnly</t:BaseShape>
<t:AdditionalProperties>
</t:AdditionalProperties>
</m:ItemShape>
<m:ItemIds>
</m:ItemIds>
</m:GetItem>
</soap:Body>
</soap:Envelope>
The following example shows the response XML that is returned by the GetItem
operation.
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
Version="V2_10"
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:GetItemResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:GetItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:CalendarItem>
<t:CalendarItemType>RecurringMaster</t:CalendarItemType>
<t:Recurrence>
<t:WeeklyRecurrence>
<t:Interval>1</t:Interval>
<t:DaysOfWeek>Saturday</t:DaysOfWeek>
</t:WeeklyRecurrence>
<t:NumberedRecurrence>
<t:StartDate>2014-03-08-08:00</t:StartDate>
<t:NumberOfOccurrences>10</t:NumberOfOccurrences>
</t:NumberedRecurrence>
</t:Recurrence>
<t:FirstOccurrence>
<t:Start>2014-03-08T21:21:00Z</t:Start>
<t:End>2014-03-08T22:21:00Z</t:End>
<t:OriginalStart>2014-03-08T21:21:00Z</t:OriginalStart>
</t:FirstOccurrence>
<t:LastOccurrence>
<t:Start>2014-05-10T20:21:00Z</t:Start>
<t:End>2014-05-10T21:21:00Z</t:End>
<t:OriginalStart>2014-05-10T20:21:00Z</t:OriginalStart>
</t:LastOccurrence>
</t:CalendarItem>
</m:Items>
</m:GetItemResponseMessage>
</m:ResponseMessages>
</m:GetItemResponse>
</s:Body>
</s:Envelope>
See also
Calendars and EWS in Exchange
Learn how to delete appointments in a recurring series by using the EWS Managed API
or EWS in Exchange.
You can use the EWS Managed API or EWS to delete a series of appointments or
meetings, or just one instance in the series. The process you use to delete an entire
series is essentially the same as the process you use to delete just a single occurrence.
You use the same EWS Managed API methods or EWS operations that you use to delete
a single instance appointment or meeting. The difference is in the item ID that is
included in the method or operation. Let's start by looking at how both scenarios are
the same.
In order to delete a recurring series or a single occurrence in a recurring series, you need
to find the occurrence or series that you want to delete, and then call the appropriate
method or operation to remove it. While you can simply delete any type of
appointment, we recommend that you keep any attendees or the organizer up to date
and cancel meetings that the user has organized and decline meetings that the user did
not organize.
So how are the scenarios different? It's all about the Appointment object used to
invoke the method (for the EWS Managed API) or the item ID included in the operation
request (for EWS). To delete an entire series, you need the Appointment object or item
ID for the recurring master. To delete a single occurrence, you need the Appointment
object or item ID for the occurrence.
C#
public static bool DeleteRecurringItem(ExchangeService service, Appointment
recurringItem, bool deleteEntireSeries)
if (recurringItem.AppointmentType == AppointmentType.Single)
return false;
if (recurringItem.AppointmentType == AppointmentType.RecurringMaster)
if (!deleteEntireSeries)
return false;
else
appointmentToDelete = recurringItem;
else
if (deleteEntireSeries)
// The item passed is not the recurring master, but the caller
try
appointmentToDelete =
Appointment.BindToRecurringMaster(service, recurringItem.Id);
return false;
else
// The item passed is not the recurring master, but the caller
appointmentToDelete = recurringItem;
if (appointmentToDelete != null)
if (appointmentToDelete.IsMeeting)
CalendarActionResults results;
// the presence of the second bit. This bit indicates that the
appointment
int isReceived = 2;
return true;
else
results = appointmentToDelete.Decline(true);
return true;
else
appointmentToDelete.Delete(DeleteMode.MoveToDeletedItems);
return true;
return false;
In order to use this example, you need to bind to either an occurrence or the recurring
master, and pass the resulting Appointment object to the method. Keep in mind that if
you access appointments by using a CalendarView class, the resulting items are all
single occurrences. Conversely, if you use the ItemView class, the resulting items are
all recurring masters.
7 Note
In the code examples that follow, the ItemId, ChangeKey, and RecurringMasterId
attributes are shortened for readability.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:TimeZoneContext>
<t:TimeZoneDefinition Id="Eastern Standard Time" />
</t:TimeZoneContext>
</soap:Header>
<soap:Body>
<m:CreateItem MessageDisposition="SendAndSaveCopy">
<m:Items>
<t:CancelCalendarItem>
</t:CancelCalendarItem>
</m:Items>
</m:CreateItem>
</soap:Body>
</soap:Envelope>
This example uses the CreateItem operation with a DeclineItem element to decline a
meeting for which the user is not the organizer. As in the previous example, the value of
the ReferenceItemId element indicates the item to decline, and can be the item ID of a
recurring master or a single occurrence.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:TimeZoneContext>
<t:TimeZoneDefinition Id="Eastern Standard Time" />
</t:TimeZoneContext>
</soap:Header>
<soap:Body>
<m:CreateItem MessageDisposition="SendAndSaveCopy">
<m:Items>
<t:DeclineItem>
</t:DeclineItem>
</m:Items>
</m:CreateItem>
</soap:Body>
</soap:Envelope>
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:TimeZoneContext>
<t:TimeZoneDefinition Id="Eastern Standard Time" />
</t:TimeZoneContext>
</soap:Header>
<soap:Body>
<m:DeleteItem DeleteType="MoveToDeletedItems"
SendMeetingCancellations="SendToAllAndSaveCopy">
<m:ItemIds>
<t:OccurrenceItemId RecurringMasterId="AAMkADA8..."
InstanceIndex="3" />
</m:ItemIds>
</m:DeleteItem>
</soap:Body>
</soap:Envelope>
Note that you can get the same result by replacing the OccurrenceItemId element with
an ItemId element that contains the item ID of the occurrence, as shown.
XML
<m:ItemIds>
</m:ItemIds>
See also
Recurrence patterns and EWS
Access a recurring series by using EWS in Exchange
Create a recurring series by using EWS in Exchange
Update a recurring series by using EWS
Update a recurring series by using EWS in Exchange
Calendars and EWS in Exchange
Create appointments and meetings by using EWS in Exchange 2013
Delete appointments and cancel meetings by using EWS in Exchange
Update a recurring series by using EWS
Article • 03/04/2022 • 4 minutes to read
Learn how to modify appointments in a recurring series by using the EWS Managed API
or EWS in Exchange.
You can use the EWS Managed API or EWS to update a recurring series by either
updating the entire series, or by updating a single occurrence. In this article we'll discuss
how to update a single occurrence.
When you change a single occurrence in a series, that occurrence is added to an array of
modified appointments associated with the recurring master for the series. You can use
the Appointment.ModifiedOccurrences EWS Managed API property or the
ModifiedOccurrences EWS element to access all the appointments in a series that
have been modified.
The following example updates an appointment in a recurring series and verifies that
the modified appointment is updated on the recurring master. This example assumes
that you have authenticated to an Exchange server and have acquired an
ExchangeService object named service. The recurrenceMasterId parameter is an
identifier associated with the recurring master for the occurrence to modify.
C#
if (calendarItem.AppointmentType == AppointmentType.RecurringMaster)
recurrMaster = Appointment.Bind(service,
recurrenceMasterId,
new
PropertySet(AppointmentSchema.AppointmentType,
AppointmentSchema.Subject,
AppointmentSchema.FirstOccurrence,
AppointmentSchema.LastOccurrence,
AppointmentSchema.ModifiedOccurrences,
AppointmentSchema.DeletedOccurrences));
else
return recurrenceMasterId;
recurrMaster.Id,
2,
new
PropertySet(AppointmentSchema.Location,
AppointmentSchema.Start,
AppointmentSchema.End,
AppointmentSchema.RequiredAttendees,
AppointmentSchema.Subject));
occurrenceToModify.Start = occurrenceToModify.Start.AddDays(1);
occurrenceToModify.End = occurrenceToModify.End.AddDays(1);
occurrenceToModify.RequiredAttendees.Add("Contoso CEO",
"sadie@contoso");
occurrenceToModify.Subject = occurrenceToModify.Subject.ToString() +
":Mandatory";
// Update the occurrence in your calendar folder and send meeting update
requests to attendees.
occurrenceToModify.Update(ConflictResolutionMode.AlwaysOverwrite,
SendInvitationsOrCancellationsMode.SendToAllAndSaveCopy);
AppointmentSchema.DeletedOccurrences));
return recurrMaster.Id;
The following example shows the request XML when you use the UpdateItem
operation to update an occurrence in a recurring series of appointments. The ItemId
and ChangeKey are shortened for readability.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:UpdateItem ConflictResolution="AlwaysOverwrite"
SendMeetingInvitationsOrCancellations="SendToAllAndSaveCopy">
<m:ItemChanges>
<t:ItemChange>
<t:Updates>
<t:SetItemField>
<t:CalendarItem>
</t:CalendarItem>
</t:SetItemField>
<t:SetItemField>
<t:CalendarItem>
<t:Start>2014-03-27T19:33:00.000-07:00</t:Start>
</t:CalendarItem>
</t:SetItemField>
<t:SetItemField>
<t:CalendarItem>
<t:End>2014-03-27T20:33:00.000-07:00</t:End>
</t:CalendarItem>
</t:SetItemField>
<t:SetItemField>
<t:CalendarItem>
<t:RequiredAttendees>
<t:Attendee>
<t:Mailbox>
<t:Name>[email protected]</t:Name>
<t:EmailAddress>[email protected]</t:EmailAddress>
<t:RoutingType>SMTP</t:RoutingType>
</t:Mailbox>
</t:Attendee>
<t:Attendee>
<t:Mailbox>
<t:Name>[email protected]</t:Name>
<t:EmailAddress>[email protected]</t:EmailAddress>
<t:RoutingType>SMTP</t:RoutingType>
</t:Mailbox>
</t:Attendee>
<t:Attendee>
<t:Mailbox>
<t:Name>[email protected]</t:Name>
<t:EmailAddress>[email protected]</t:EmailAddress>
<t:RoutingType>SMTP</t:RoutingType>
</t:Mailbox>
</t:Attendee>
<t:Attendee>
<t:Mailbox>
<t:Name>Contoso CEO</t:Name>
<t:EmailAddress>sadie@contoso</t:EmailAddress>
</t:Mailbox>
</t:Attendee>
<t:Attendee>
<t:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:Mailbox>
</t:Attendee>
<t:Attendee>
<t:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:Mailbox>
</t:Attendee>
</t:RequiredAttendees>
</t:CalendarItem>
</t:SetItemField>
<t:SetItemField>
<t:CalendarItem>
</t:CalendarItem>
</t:SetItemField>
</t:Updates>
</t:ItemChange>
</m:ItemChanges>
</m:UpdateItem>
</soap:Body>
</soap:Envelope>
See also
Calendars and EWS in Exchange
Learn how to update an entire recurring series at once by using the EWS Managed API
or EWS in Exchange.
You can use the EWS Managed API or EWS to update a recurring series by either
updating the entire series, or by updating a single occurrence. In this article we'll discuss
how to update the entire series at once.
However, there is one key difference to consider when updating a recurring series:
updating the recurrence pattern. Updating the recurrence pattern is only possible with
the recurring master, and changes to the pattern can add or remove occurrences. For
example, if you modify the Recurrence.EndDate property to a date later than its
current value, the recurrence pattern is reevaluated, and additional occurrences might
be added.
The following example updates a recurring series to change the location, add an
attendee, and modify the recurrence pattern. This example assumes that the
ExchangeService object passed in the service parameter has been initialized with valid
values in the Credentials and Url properties. The recurringAppointment parameter is
an Appointment object bound to either an occurrence or the recurring master for the
series to be updated.
C#
using Microsoft.Exchange.WebServices.Data;
if (recurringAppointment.AppointmentType == AppointmentType.Single)
return false;
if (recurringAppointment.AppointmentType !=
AppointmentType.RecurringMaster)
try
recurringMaster = Appointment.BindToRecurringMaster(service,
recurringAppointment.Id);
return false;
else
recurringMaster = Appointment.Bind(service,
recurringAppointment.Id);
// Add an attendee.
recurringMaster.RequiredAttendees.Add(newAttendee);
// master.
// If the series has an end date, extend the series to add two more
occurrences.
if (recurringMaster.Recurrence.HasEnd)
if (recurringMaster.Recurrence.NumberOfOccurrences != null)
recurringMaster.Recurrence.NumberOfOccurrences += 2;
else
switch (recurrenceType.Name)
case "DailyPattern":
recurringMaster.Recurrence.EndDate =
recurringMaster.Recurrence.EndDate.Value.AddDays(2);
break;
case "WeeklyPattern":
recurringMaster.Recurrence.EndDate =
recurringMaster.Recurrence.EndDate.Value.AddDays(14);
break;
case "YearlyPattern":
recurringMaster.Recurrence.EndDate =
recurringMaster.Recurrence.EndDate.Value.AddYears(2);
break;
default:
break;
else
recurringMaster.Recurrence.EndDate = DateTime.Now.AddDays(14);
try
recurringMaster.Update(ConflictResolutionMode.AutoResolve);
return false;
return true;
The following example updates the recurring series in the following ways:
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:TimeZoneContext>
<t:TimeZoneDefinition Id="Eastern Standard Time" />
</t:TimeZoneContext>
</soap:Header>
<soap:Body>
<m:UpdateItem MessageDisposition="SaveOnly"
ConflictResolution="AutoResolve"
SendMeetingInvitationsOrCancellations="SendToAllAndSaveCopy">
<m:ItemChanges>
<t:ItemChange>
<t:Updates>
<t:SetItemField>
<t:CalendarItem>
</t:CalendarItem>
</t:SetItemField>
<t:SetItemField>
<t:CalendarItem>
<t:RequiredAttendees>
<t:Attendee>
<t:Mailbox>
<t:Name>Mack Chaves</t:Name>
<t:EmailAddress>[email protected]</t:EmailAddress>
<t:RoutingType>SMTP</t:RoutingType>
</t:Mailbox>
</t:Attendee>
<t:Attendee>
<t:Mailbox>
<t:Name>Sadie Daniels</t:Name>
<t:EmailAddress>[email protected]</t:EmailAddress>
<t:RoutingType>SMTP</t:RoutingType>
</t:Mailbox>
</t:Attendee>
</t:RequiredAttendees>
</t:CalendarItem>
</t:SetItemField>
<t:SetItemField>
<t:CalendarItem>
<t:Recurrence>
<t:WeeklyRecurrence>
<t:Interval>1</t:Interval>
<t:DaysOfWeek>Tuesday</t:DaysOfWeek>
</t:WeeklyRecurrence>
<t:EndDateRecurrence>
<t:StartDate>2014-05-06</t:StartDate>
<t:EndDate>2014-06-22-04:00</t:EndDate>
</t:EndDateRecurrence>
</t:Recurrence>
</t:CalendarItem>
</t:SetItemField>
<t:SetItemField>
<t:CalendarItem>
</t:CalendarItem>
</t:SetItemField>
</t:Updates>
</t:ItemChange>
</m:ItemChanges>
</m:UpdateItem>
</soap:Body>
</soap:Envelope>
See also
Calendars and EWS in Exchange
Recurrence patterns and EWS
Update appointments and meetings by using EWS in Exchange
Update a recurring series by using EWS
Access a recurring series by using EWS in Exchange
Delegate access and EWS in Exchange
Article • 06/14/2022 • 9 minutes to read
Find out how to use the EWS Managed API and EWS in Exchange to provide delegate
access to users' mailboxes.
You can enable users to access other users' mailboxes in one of three ways:
By using impersonation.
Delegation and folder permissions are best when you're only granting access to a few
users, because you have to add permissions individually to each mailbox. Impersonation
is the best choice when you're dealing with quantities of mailboxes, because you can
easily enable one service account to access every mailbox in a database. Figure 1 shows
some of the differences between each type of access.
When is it appropriate to modify folder permissions directly? Generally, when you want
to provide a user access to a folder, but do not want to grant the user "send on behalf
of" permissions, when your permissions requirements do not map to the
DelegateFolderPermissionLevel EWS Managed API enumeration values or the
PermissionLevel EWS element values, or when you want to provide a user access to a
single custom folder.
If you only need to modify folder permissions to achieve your goal, and do not need to
add a delegate (that is, you don't need "send on behalf of" permissions), see Set folder
permissions for another user by using EWS in Exchange.
Note that you can also use Outlook or the Exchange Server PowerShell (Exchange
Management Shell) to set up delegate access.
Calendar
Tasks
Inbox
Contacts
Notes
Journal
When a user has delegate access to one or more of these folders, they can create, get,
update, delete, copy, and search for items in that folder and any child folders,
depending on the permissions set on the folder. The way in which the application
performs these actions depends on whether explicit or implicit access is required.
Delegate permissions
When an administrator or mailbox owner adds a delegate to a mailbox, they can also set
the permission level for one or more folders. If a permission level is not set for a folder,
the permission value defaults to None. Multiple users can have the same permission
level on a folder, and users can have different permission levels for different folders. If
you're using the EWS Managed API, you use the DelegateUser.Permissions property,
which contains one of the DelegateFolderPermissionLevel enumeration values for
each folder, to set delegate permissions on folders. If you're using EWS, you use the
DelegatePermissions element to set delegate permissions, and the PermissionLevel
element to define the permission level.
Permission Description
level
Author A delegate can read and create items, and modify and delete items they create. For
example, a delegate can create task requests and meeting requests directly in the
mailbox owner's Task or Calendar folder, and then send either item on the mailbox
owner's behalf.
Editor A delegate can do everything an Author can do, and also modify and delete the
items the mailbox owner created.
Reviewer A delegate can read items; for example a delegate with Reviewer permission can
read messages in another person's Inbox.
Custom The mailbox owner has granted a custom set of permissions to the delegate.
Explicit access
Simply put, explicit access is the entry way for delegates to perform actions on a
mailbox owner's folders or items. Explicit access is granted to a delegate when they
include the well-known folder name for a mailbox owner's folder along with the mailbox
owner's SMTP address in a request to the server. The access is explicit because the
delegate's request explicitly states that the context for the method or operation is the
mailbox owner's mailbox, and not the delegate's mailbox.
Explicit access defines the context for all methods or operations performed on the
folders or items moving forward. All item and folder IDs returned when the explicit
access is set uniquely identify themselves as belonging to the mailbox owner (although
not in any human readable format). This way, the application doesn't need to specify the
mailbox owner's SMTP address again and again; the context is hidden in the identifiers.
After an item or folder is identified, a delegate actually uses implicit access to modify the
item. The following figure shows the process of getting explicit and implicit access.
You can set explicit access in many different scenarios. Essentially, any time you're
sending a folder ID in a method or operation, you can set explicit access. This can
include finding folders, finding appointments, getting items, finding conversations, and
so on.
ExchangeService.FindItems
ExchangeService.FindAppointments
ExchangeService.FindFolders
And more!
You can use the FolderId parameter in each of these methods to identify the mailbox
owner's target folder, as follows.
C#
For example, to bind to the Calendar folder, the FolderId in this Bind method specifies
the well-known folder name, and the mailbox owner's SMTP address.
C#
By specifying the well-known folder name and the SMTP address, the delegate can bind
to the mailbox owner's Calendar folder — thereby gaining explicit access to the folder.
All subsequent requests for implicit access to items in the folder then rely on the context
returned in the item IDs and folder IDs. Essentially, the identifiers contain the context for
the implied delegate access calls. Or, to retrieve the item ID of an item that meets
specific criteria, use the following.
C#
In this case the item ID is returned, and then the delegate can then use implicit access to
make changes to the item by using the item ID.
You don't have to initiate explicit access again until you require an item ID or a folder ID
that you didn't access via the existing explicit access.
Explicit access and EWS
You can initiate explicit access by using the GetFolder , FindItem , or FindFolder
operations. These operations provide the option to use the DistinguishedFolderId
element to identify the target folder. The DistinguishedFolderId element has a single
optional child element, the Mailbox element. The Mailbox element, when used as a
child of the DistinguishedFolderId element, specifies the mailbox for the delegate to
access. If the calling user has permission to access the mailbox owner's folder, the
response will contain a collection of identifiers to items or folders in that mailbox. The
item and folder identifiers that are returned in the response can be used for implicit
delegate access.
Implicit access
Implicit access is used after a delegate has retrieved the ID for an item or folder in the
mailbox owner's mailbox and the delegate wants to update, delete, or copy the item.
When the delegate uses that item or folder ID in a request, the changes are made to the
item in the mailbox owner's mailbox. The delegate does not have to include the mailbox
owner's SMTP address.
For example, when a delegate has the ID of one of the mailbox owner's folders, the
delegate can perform a FindItem operation on that folder by using the folder ID,
without explicitly identifying the mailbox owner's mailbox. At that point, the delegate
can perform actions on the mailbox owner's folder by using the IDs that are returned in
the responses.
In this section
Add and remove delegates by using EWS in Exchange
See also
Develop web service clients for Exchange
Add- MailboxPermission
Add and remove delegates by using
EWS in Exchange
Article • 09/15/2021 • 6 minutes to read
Learn how to add delegates to or remove delegates from users' mailboxes by using the
EWS Managed API or EWS in Exchange.
You can use the EWS Managed API or EWS to enable delegates to act on behalf of a
mailbox owner or remove a delegate's access to a mailbox. Users who are added as a
delegate, and are given permissions, can perform tasks on behalf of the mailbox owner.
For example, they can create and send meeting invitations, send emails, and respond to
meeting requests on the mailbox owner's behalf.
Table 1. EWS Managed API methods and EWS operations for adding and removing
delegates
After a delegate is granted permissions to a folder, they can act on items in the folder
and any subfolders, according to their delegate permissions. Permissions for delegates
only apply to subfolders that are created after the delegate access was granted. To
update folder permissions for pre-existing folders, or other folders, see Set folder
permissions for another user by using EWS in Exchange.
Note that delegates can only be added to mailbox-enabled accounts, including mail-
enabled security groups. By default, a single EWS delegate access call can access a
maximum of 255 different mailboxes.
C#
// Create a new delegate that has editor access to the mailbox owner's
Calendar folder.
calendarDelegate.Permissions.CalendarFolderPermissionLevel =
DelegateFolderPermissionLevel.Editor;
newDelegates.Add(calendarDelegate);
// Create a new delegate that has editor access to the mailbox owner's
Contacts folder.
contactDelegate.Permissions.ContactsFolderPermissionLevel =
DelegateFolderPermissionLevel.Editor;
newDelegates.Add(contactDelegate);
// Create a new delegate that has editor access to the mailbox owner's
Inbox folder.
emailDelegate.Permissions.InboxFolderPermissionLevel =
DelegateFolderPermissionLevel.Editor;
newDelegates.Add(emailDelegate);
Collection<DelegateUserResponse> response =
service.AddDelegates(mailbox,
MeetingRequestsDeliveryScope.DelegatesAndSendInformationToMe, newDelegates);
// Print out the result and the last eight characters of the item
ID.
Console.WriteLine("\r\n");
return response;
This is also the XML request that the EWS Managed API sends when you use the
AddDelegates method to add delegates.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:AddDelegate>
<m:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</m:Mailbox>
<m:DelegateUsers>
<t:DelegateUser>
<t:UserId>
<t:PrimarySmtpAddress>[email protected]</t:PrimarySmtpAddress>
</t:UserId>
<t:DelegatePermissions>
<t:CalendarFolderPermissionLevel>Editor</t:CalendarFolderPermissionLevel>
<t:TasksFolderPermissionLevel>None</t:TasksFolderPermissionLevel>
<t:InboxFolderPermissionLevel>None</t:InboxFolderPermissionLevel>
<t:ContactsFolderPermissionLevel>None</t:ContactsFolderPermissionLevel>
<t:NotesFolderPermissionLevel>None</t:NotesFolderPermissionLevel>
<t:JournalFolderPermissionLevel>None</t:JournalFolderPermissionLevel>
</t:DelegatePermissions>
<t:ReceiveCopiesOfMeetingMessages>false</t:ReceiveCopiesOfMeetingMessages>
<t:ViewPrivateItems>false</t:ViewPrivateItems>
</t:DelegateUser>
<t:DelegateUser>
<t:UserId>
<t:PrimarySmtpAddress>[email protected]</t:PrimarySmtpAddress>
</t:UserId>
<t:DelegatePermissions>
<t:CalendarFolderPermissionLevel>None</t:CalendarFolderPermissionLevel>
<t:TasksFolderPermissionLevel>None</t:TasksFolderPermissionLevel>
<t:InboxFolderPermissionLevel>None</t:InboxFolderPermissionLevel>
<t:ContactsFolderPermissionLevel>Editor</t:ContactsFolderPermissionLevel>
<t:NotesFolderPermissionLevel>None</t:NotesFolderPermissionLevel>
<t:JournalFolderPermissionLevel>None</t:JournalFolderPermissionLevel>
</t:DelegatePermissions>
<t:ReceiveCopiesOfMeetingMessages>false</t:ReceiveCopiesOfMeetingMessages>
<t:ViewPrivateItems>false</t:ViewPrivateItems>
</t:DelegateUser>
<t:DelegateUser>
<t:UserId>
<t:PrimarySmtpAddress>[email protected]</t:PrimarySmtpAddress>
</t:UserId>
<t:DelegatePermissions>
<t:CalendarFolderPermissionLevel>None</t:CalendarFolderPermissionLevel>
<t:TasksFolderPermissionLevel>None</t:TasksFolderPermissionLevel>
<t:InboxFolderPermissionLevel>Editor</t:InboxFolderPermissionLevel>
<t:ContactsFolderPermissionLevel>None</t:ContactsFolderPermissionLevel>
<t:NotesFolderPermissionLevel>None</t:NotesFolderPermissionLevel>
<t:JournalFolderPermissionLevel>None</t:JournalFolderPermissionLevel>
</t:DelegatePermissions>
<t:ReceiveCopiesOfMeetingMessages>false</t:ReceiveCopiesOfMeetingMessages>
<t:ViewPrivateItems>false</t:ViewPrivateItems>
</t:DelegateUser>
</m:DelegateUsers>
<m:DeliverMeetingRequests>DelegatesAndSendInformationToMe</m:DeliverMeetingR
equests>
</m:AddDelegate>
</soap:Body>
</soap:Envelope>
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="15"
MinorVersion="0"
MajorBuildNumber="888"
MinorBuildNumber="9"
Version="V2_10"
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:AddDelegateResponse ResponseClass="Success"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseCode>NoError</m:ResponseCode>
<m:ResponseMessages>
<m:DelegateUserResponseMessageType ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:DelegateUser>
<t:UserId>
<t:SID>S-1-5-21-1337771579-694202782-848329751-1535221</t:SID>
<t:PrimarySmtpAddress>[email protected]</t:PrimarySmtpAddress>
<t:DisplayName>calendardelegate</t:DisplayName>
</t:UserId>
<t:ReceiveCopiesOfMeetingMessages>false</t:ReceiveCopiesOfMeetingMessages>
<t:ViewPrivateItems>false</t:ViewPrivateItems>
</m:DelegateUser>
</m:DelegateUserResponseMessageType>
<m:DelegateUserResponseMessageType ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:DelegateUser>
<t:UserId>
<t:SID>S-1-5-21-1337771579-694202782-848329751-1535264</t:SID>
<t:PrimarySmtpAddress>[email protected]</t:PrimarySmtpAddress>
<t:DisplayName>contactdelegate</t:DisplayName>
</t:UserId>
<t:ReceiveCopiesOfMeetingMessages>false</t:ReceiveCopiesOfMeetingMessages>
<t:ViewPrivateItems>false</t:ViewPrivateItems>
</m:DelegateUser>
</m:DelegateUserResponseMessageType>
<m:DelegateUserResponseMessageType ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:DelegateUser>
<t:UserId>
<t:SID>S-1-5-21-1337771579-694202782-848329751-1535223</t:SID>
<t:PrimarySmtpAddress>[email protected]</t:PrimarySmtpAddress>
<t:DisplayName>emaildelegate</t:DisplayName>
</t:UserId>
<t:ReceiveCopiesOfMeetingMessages>false</t:ReceiveCopiesOfMeetingMessages>
<t:ViewPrivateItems>false</t:ViewPrivateItems>
</m:DelegateUser>
</m:DelegateUserResponseMessageType>
</m:ResponseMessages>
</m:AddDelegateResponse>
</s:Body>
</s:Envelope>
This example assumes that service is a valid ExchangeService object for the mailbox
owner, and that the user has been authenticated to an Exchange server.
C#
deletedDelegates.Add("[email protected]");
deletedDelegates.Add("[email protected]");
deletedDelegates.Add("[email protected]");
Collection<DelegateUserResponse> response =
service.RemoveDelegates(mailbox, deletedDelegates);
// Print out the result and the last eight characters of the item
ID.
return response;
This is also the XML request that the EWS Managed API sends when you use the
RemoveDelegates method to remove delegates.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:RemoveDelegate>
<m:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</m:Mailbox>
<m:UserIds>
<t:UserId>
<t:PrimarySmtpAddress>[email protected]</t:PrimarySmtpAddress>
</t:UserId>
<t:UserId>
<t:PrimarySmtpAddress>[email protected]</t:PrimarySmtpAddress>
</t:UserId>
<t:UserId>
<t:PrimarySmtpAddress>[email protected]</t:PrimarySmtpAddress>
</t:UserId>
</m:UserIds>
</m:RemoveDelegate>
</soap:Body>
</soap:Envelope>
Next steps
After you add delegates to calendar, email, and task folders, the delegate can access the
items in the folders. To learn more, see the following articles:
If the folders for which you added delegates include child folders that were created
before you granted the delegate access, the delegate will not be able to access those
folders without additional permissions. To add these permissions, or modify permissions
for any other folders, see Set folder permissions for another user by using EWS in
Exchange.
See also
Delegate access and EWS in Exchange
Exchange 2013: Add delegate users to an email account programmatically
Exchange 2013: Update delegates associated with email accounts
programmatically
Exchange 2013: Remove delegates associated with email accounts
programmatically
Access a calendar as a delegate by using
EWS in Exchange
Article • 03/15/2022 • 9 minutes to read
Learn how to access a calendar as a delegate by using the EWS Managed API or EWS in
Exchange.
You can use the EWS Managed API or EWS to give a user delegate access to a mailbox
owner's Calendar folder. The delegate can then create meeting requests on behalf of the
mailbox owner, create appointments, respond to meeting requests, and retrieve, update,
and delete meetings from the mailbox owner's Calendar folder, depending on their
permissions.
As a delegate, you use the same methods and operations to access a mailbox owner's
Calendar folder that you use to access your own Calendar folder. The main difference is
that you have to use explicit access to find or create a calendar item or calendar
subfolder, and then after you identify the item ID or folder ID, you can use implicit
access to get, update, or delete the item.
Table 1. EWS Managed API methods and EWS operations for accessing a calendar as a
delegate
If you want to… Use this EWS Managed API method… Use this EWS operation…
Get an Appointment.Bind
GetItem
appointment or
meeting as a
delegate
If you want to… Use this EWS Managed API method… Use this EWS operation…
meeting as a
delegate
meeting as a
delegate
7 Note
Prerequisite tasks
Before a user can access a mailbox owner's Calendar folder as a delegate, the user must
be added as a delegate with permissions to the mailbox owner's Calendar folder.
A delegate must have a mailbox attached to their account to update the calendar of a
mailbox owner.
If a delegate needs to work with meeting requests and responses only, you can add the
delegate to the Calendar folder, and use the default
MeetingRequestsDeliveryScope.DelegatesAndSendInformationToMe EWS Managed
API enumeration value or the DeliverMeetingRequests EWS element value of
DelegatesAndSendInformationToMe to send the requests to the delegate and
informational messages to the mailbox owner. The delegate then does not need to be
given access to the mailbox owner's Inbox folder.
This example assumes that service is a valid ExchangeService object for the delegate
and that the delegate has been granted the appropriate permissions for the mailbox
owner's Calendar folder.
C#
meeting.Start = DateTime.Now.AddDays(2);
meeting.End = meeting.Start.AddHours(4);
meeting.RequiredAttendees.Add("[email protected]");
meeting.ReminderMinutesBeforeStart = 60;
meeting.Save(new FolderId(WellKnownFolderName.Calendar,
SendInvitationsMode.SendToAllAndSaveCopy);
Note that when you save the item, the Save method call must identify the mailbox
owner's Calendar folder. If the mailbox owner's Calendar folder is not specified, the
meeting request gets saved to the delegate's calendar and not the mailbox owner's
Calendar folder. You can include the mailbox owner's Calendar folder in the Save
method call in two ways. We recommend that you instantiate a new instance of the
FolderId object by using the WellKnownFolderName and the SMTP address of the
mailbox owner.
C#
meeting.Save(new FolderId(WellKnownFolderName.Calendar,
"[email protected]"), SendInvitationsMode.SendToAllAndSaveCopy);
However, you can also Bind to the Calendar folder first, and then use the ID of the
folder in the Save method call. Be aware, however, that this creates an extra EWS call.
C#
// Save the meeting to the Calendar folder for the mailbox owner and
send the meeting request.
meeting.Save(primaryCalendar.Id,
SendInvitationsMode.SendToAllAndSaveCopy);
This is also the XML request that the EWS Managed API sends when you use the Save
method to create a meeting or appointment as a delegate.
The SOAP header has been removed from the following example for brevity.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<m:CreateItem SendMeetingInvitations="SendToAllAndSaveCopy">
<m:SavedItemFolderId>
<t:DistinguishedFolderId Id="calendar">
<t:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:Mailbox>
</t:DistinguishedFolderId>
</m:SavedItemFolderId>
<m:Items>
<t:CalendarItem>
<t:ReminderMinutesBeforeStart>60</t:ReminderMinutesBeforeStart>
<t:Start>2014-03-09T23:26:33.756-05:00</t:Start>
<t:End>2014-03-10T03:26:33.756-05:00</t:End>
<t:RequiredAttendees>
<t:Attendee>
<t:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:Mailbox>
</t:Attendee>
</t:RequiredAttendees>
</t:CalendarItem>
</m:Items>
</m:CreateItem>
</soap:Body>
</soap:Envelope>
C#
ItemSchema.DateTimeReceived,
EmailMessageSchema.IsRead);
view.Traversal = ItemTraversal.Shallow;
view.OrderBy.Add(ItemSchema.DateTimeReceived, SortDirection.Descending);
try
new FolderId(WellKnownFolderName.Calendar,
filter,
view);
Console.WriteLine("Exception while
After the FindItems call returns a response with an ID, you can get, update or delete that
meeting by using the ID and implicit access — and you do not need to specify the
mailbox owner's SMTP address.
This is also the XML request that the EWS Managed API sends when you use the
FindItem method to search for a meeting or appointment as a delegate.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:FindItem Traversal="Shallow">
<m:ItemShape>
<t:BaseShape>IdOnly</t:BaseShape>
<t:AdditionalProperties>
</t:AdditionalProperties>
</m:ItemShape>
<m:IndexedPageItemView MaxEntriesReturned="10"
Offset="0"
BasePoint="Beginning" />
<m:Restriction>
<t:Contains ContainmentMode="Substring"
ContainmentComparison="IgnoreCase">
</t:Contains>
</m:Restriction>
<m:SortOrder>
<t:FieldOrder Order="Descending">
</t:FieldOrder>
</m:SortOrder>
<m:ParentFolderIds>
<t:DistinguishedFolderId Id="calendar">
<t:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:Mailbox>
</t:DistinguishedFolderId>
</m:ParentFolderIds>
</m:FindItem>
</soap:Body>
</soap:Envelope>
The server responds to the FindItem request with a FindItemResponse message that
includes a ResponseCode element value of NoError, which indicates that the search
completed successfully. The response contains a CalendarItem for any appointments
or meetings that met the search criteria. In this case, only one meeting is found.
The value of the ItemId element has been shortened for readability.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="15"
MinorVersion="0"
MajorBuildNumber="893"
MinorBuildNumber="10"
Version="V2_10"
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance" />
</s:Header>
<s:Body>
<m:FindItemResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:FindItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:RootFolder IndexedPagingOffset="1"
TotalItemsInView="1"
IncludesLastItemInRange="true">
<t:Items>
<t:CalendarItem>
<t:ItemId Id="IJpUAAA="
ChangeKey="DwAAABYAAADOilbYa8KaT7ZgMoTz2P+hAAAAIKhS" />
<t:DateTimeReceived>2014-03-
04T21:27:22Z</t:DateTimeReceived>
</t:CalendarItem>
</t:Items>
</m:RootFolder>
</m:FindItemResponseMessage>
</m:ResponseMessages>
</m:FindItemResponse>
</s:Body>
</s:Envelope>
Now that you have the ItemId for the meeting that meets your criteria, you can get,
update, or delete that meeting by using the ItemId and implicit access — and you do
not need to specify the mailbox owner's SMTP address.
Table 2. EWS Managed API methods for working with appointments and meetings as
a delegate
Task EWS Managed API Code example
method
Table 3. EWS operations for working with appointments and meetings as a delegate
meeting
See also
Delegate access and EWS in Exchange
Add and remove delegates by using EWS in Exchange
Set folder permissions for another user by using EWS in Exchange
Calendars and EWS in Exchange
Access contacts as a delegate by using
EWS in Exchange
Article • 09/15/2021 • 8 minutes to read
Learn how to access contacts as a delegate by using the EWS Managed API or EWS in
Exchange.
You can use the EWS Managed API or EWS to give a user access to a mailbox owner's
Contacts folder. The delegate can then create contacts on behalf of the mailbox owner,
and retrieve, update, and delete contacts from the mailbox owner's Contacts folder,
depending on their permissions.
As a delegate, you use the same methods and operations to access a mailbox owner's
Contacts folder that you use to access your own Contacts folder. The main difference is
that you have to use explicit access to find or create a contact item, and then after you
identify the item ID, you can use implicit access to get, update, or delete the item.
Table 1. EWS Managed API methods and EWS operations for accessing a contact as a
delegate
If you want Use this EWS Managed API method… Use this EWS operation…
to…
Get a Contact.Bind
GetItem
contact as a
delegate
delegate
7 Note
Prerequisite tasks
Before a user can access the mailbox owner's Contacts folder as a delegate, the user
must be added as a delegate with permissions to the mailbox owner's Contacts folder.
This example assumes that service is a valid ExchangeService object for the delegate
and that the delegate has been granted the appropriate permissions for the mailbox
owner's Contacts folder.
C#
contact.GivenName = "Brian";
contact.MiddleName = "David";
contact.Surname = "Johnson";
contact.FileAsMapping = FileAsMapping.SurnameCommaGivenName;
contact.CompanyName = "Contoso";
contact.PhoneNumbers[PhoneNumberKey.BusinessPhone] = "425-555-0110";
contact.PhoneNumbers[PhoneNumberKey.HomePhone] = "425-555-0120";
contact.PhoneNumbers[PhoneNumberKey.CarPhone] = "425-555-0130";
contact.EmailAddresses[EmailAddressKey.EmailAddress1] =
new EmailAddress("[email protected]");
contact.EmailAddresses[EmailAddressKey.EmailAddress2] =
new EmailAddress("[email protected]");
// The contact identifier contains the context for the mailbox owner's
contact.Save(new FolderId(WellKnownFolderName.Contacts,
"[email protected]"));
Note that when you save the item, the Save method call must identify the mailbox
owner's Contacts folder. If the mailbox owner's Contacts folder is not specified, the
meeting request gets saved to the delegate's Contacts folder and not the mailbox
owner's Contacts folder. You can include the mailbox owner's Contacts folder in the
Save method call in two way. We recommend that you instantiate a new instance of the
FolderId object by using the WellKnownFolderName and the SMTP address of the
mailbox owner.
C#
contact.Save(new FolderId(WellKnownFolderName.Contacts,
"[email protected]"));
However, you can also Bind to the Contacts folder first, and then use the ID of the
folder in the Save method call. Be aware, however, that this creates an extra EWS call.
C#
meeting.Save(primaryContacts.Id);
This is also the XML request that the EWS Managed API sends when you use the Save
method to create a contact.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:CreateItem MessageDisposition="SaveOnly">
<m:SavedItemFolderId>
<t:DistinguishedFolderId Id="contacts">
<t:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:Mailbox>
</t:DistinguishedFolderId>
</m:SavedItemFolderId>
<m:Items>
<t:Contact>
<t:FileAsMapping>LastCommaFirst</t:FileAsMapping>
<t:GivenName>Brian</t:GivenName>
<t:MiddleName>David</t:MiddleName>
<t:CompanyName>Contoso</t:CompanyName>
<t:EmailAddresses>
<t:Entry Key="EmailAddress1">[email protected]</t:Entry>
<t:Entry Key="EmailAddress2">[email protected]</t:Entry>
</t:EmailAddresses>
<t:PhoneNumbers>
<t:Entry Key="BusinessPhone">425-555-0110</t:Entry>
<t:Entry Key="HomePhone">425-555-0120</t:Entry>
<t:Entry Key="CarPhone">425-555-0130</t:Entry>
</t:PhoneNumbers>
<t:Surname>Johnson</t:Surname>
</t:Contact>
</m:Items>
</m:CreateItem>
</soap:Body>
</soap:Envelope>
C#
folders.Add(new FolderId(WellKnownFolderName.Contacts,
"[email protected]"));
After the ResolveNames method call returns a response with an ID, you can get, update
or delete the contact using the ID and implicit access—and you do not need to specify
the mailbox owner's SMTP address.
Resolve a contact as a delegate by using EWS
EWS enables you to use the service object for the delegate user to resolve partial names
in the mailbox owner's Contacts folder. This example shows how to use the
ResolveNames operation to find meetings in the mailbox owner's Contacts folder that
contain the word "johnson".
This is also the XML request that the EWS Managed API sends when you use the
ResolveName method to resolve a contact.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:ResolveNames ReturnFullContactData="true"
SearchScope="Contacts">
<m:ParentFolderIds>
<t:DistinguishedFolderId Id="contacts">
<t:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:Mailbox>
</t:DistinguishedFolderId>
</m:ParentFolderIds>
<m:UnresolvedEntry>johnson</m:UnresolvedEntry>
</m:ResolveNames>
</soap:Body>
</soap:Envelope>
The value of the ItemId element has been shortened for readability.
XML
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="15"
MinorVersion="0"
MajorBuildNumber="893"
MinorBuildNumber="17"
Version="V2_10"
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance" />
</s:Header>
<s:Body>
<m:ResolveNamesResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:ResolveNamesResponseMessage ResponseClass="Warning">
<m:ResponseCode>ErrorNameResolutionMultipleResults</m:ResponseCode>
<m:DescriptiveLinkKey>0</m:DescriptiveLinkKey>
<m:ResolutionSet TotalItemsInView="2"
IncludesLastItemInRange="true">
<t:Resolution>
<t:Mailbox>
<t:Name>[email protected]</t:Name>
<t:EmailAddress>[email protected]</t:EmailAddress>
<t:RoutingType>SMTP</t:RoutingType>
<t:MailboxType>Contact</t:MailboxType>
<t:ItemId Id="iMihAAA="
ChangeKey="EQAAABYAAADOilbYa8KaT7ZgMoTz2P+hAAABiPQo" />
</t:Mailbox>
</t:Resolution>
<t:Resolution>
<t:Mailbox>
<t:Name>[email protected]</t:Name>
<t:EmailAddress>[email protected]</t:EmailAddress>
<t:RoutingType>SMTP</t:RoutingType>
<t:MailboxType>Contact</t:MailboxType>
<t:ItemId Id="iMihAAA="
ChangeKey="EQAAABYAAADOilbYa8KaT7ZgMoTz2P+hAAABiPQo" />
</t:Mailbox>
</t:Resolution>
</m:ResolutionSet>
</m:ResolveNamesResponseMessage>
</m:ResponseMessages>
</m:ResolveNamesResponse>
</s:Body>
</s:Envelope>
Now that you have the ItemId for the contacts that match the ambiguous name, you
can Get, update, or delete contact items as a delegate by using EWS by using the ItemId
and implicit access—and you do not need to specify the mailbox owner's SMTP address.
Update a contact Bind followed by Update an item by using the EWS Managed
Update
API
Delete a contact Bind followed by Delete Delete an item by using the EWS Managed API
See also
Delegate access and EWS in Exchange
Add and remove delegates by using EWS in Exchange
Set folder permissions for another user by using EWS in Exchange
People and contacts in EWS in Exchange
Resolve ambiguous names by using EWS in Exchange 2013
Access email as a delegate by using
EWS in Exchange
Article • 09/15/2021 • 9 minutes to read
Learn how to access email as a delegate by using the EWS Managed API or EWS in
Exchange.
You can use the EWS Managed API or EWS to give a user delegate access to a mailbox
owner's Inbox folder. The delegate can then create meeting requests on behalf of the
mailbox owner, search for email, and retrieve, update, and delete email from the
mailbox owner's Inbox folder, depending on their permissions.
As a delegate, you use the same methods and operations to access a mailbox owner's
Inbox folder that you use to access an Inbox folder without delegate access. The main
difference is that you have to use explicit access to find or create an email item, and
then after you identify the item ID, you can use implicit access to get, update, or delete
the item.
Table 1. EWS Managed API methods and EWS operations for accessing email as a
delegate
If you want Use this EWS Managed API method… Use this EWS operation…
to…
as a delegate
If you want Use this EWS Managed API method… Use this EWS operation…
to…
delegate
delegate
Keep the following things in mind when working with emails as a delegate:
If a delegate only needs to work with meeting requests and responses, the
delegate does not need access to the Inbox folder. For more information, see
prerequisite tasks for accessing calendars as a delegate.
When a recipient receives a message that was sent on behalf of a mailbox owner,
the sender appears as " Delegate on behalf of mailbox owner ."
7 Note
Prerequisite tasks
Before a user can access the mailbox owner's Inbox folder as a delegate, the user must
be added as a delegate with permissions to the mailbox owner's Inbox folder.
This example assumes that service is a valid ExchangeService object for the delegate
and that the delegate has been granted the appropriate permissions for the mailbox
owner's Inbox, Drafts, and Sent Items folder.
C#
message.ToRecipients.Add("[email protected]");
// owner's mailbox.
This is also the first XML request that the EWS Managed API sends when you use the
Save method to create and send an email.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:CreateItem MessageDisposition="SaveOnly">
<m:SavedItemFolderId>
<t:DistinguishedFolderId Id="drafts">
<t:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:Mailbox>
</t:DistinguishedFolderId>
</m:SavedItemFolderId>
<m:Items>
<t:Message>
<t:ToRecipients>
<t:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:Mailbox>
</t:ToRecipients>
</t:Message>
</m:Items>
</m:CreateItem>
</soap:Body>
</soap:Envelope>
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="15"
MinorVersion="0"
MajorBuildNumber="893"
MinorBuildNumber="17"
Version="V2_10"
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance" />
</s:Header>
<s:Body>
<m:CreateItemResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:CreateItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:Message>
<t:ItemId Id="iNRaAAA="
ChangeKey="CQAAABYAAADOilbYa8KaT7ZgMoTz2P+hAAABiQPU"
/>
</t:Message>
</m:Items>
</m:CreateItemResponseMessage>
</m:ResponseMessages>
</m:CreateItemResponse>
</s:Body>
</s:Envelope>
Next, use the SendItem operation to send the message on behalf of the mailbox owner
and save it in the mailbox owner's Sent Items folder.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:SendItem SaveItemToFolder="true">
<m:ItemIds>
<t:ItemId Id="iNRaAAA="
ChangeKey="CQAAABYAAADOilbYa8KaT7ZgMoTz2P+hAAABiQPU" />
</m:ItemIds>
<m:SavedItemFolderId>
<t:DistinguishedFolderId Id="sentitems">
<t:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:Mailbox>
</t:DistinguishedFolderId>
</m:SavedItemFolderId>
</m:SendItem>
</soap:Body>
</soap:Envelope>
The server responds to the SendItem request with a SendItemResponse message that
includes a ResponseCode element value of NoError, which indicates that the email
was sent and saved to the mailbox owner's Sent Items folder successfully.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="15"
MinorVersion="0"
MajorBuildNumber="893"
MinorBuildNumber="17"
Version="V2_10"
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance" />
</s:Header>
<s:Body>
<m:SendItemResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:SendItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
</m:SendItemResponseMessage>
</m:ResponseMessages>
</m:SendItemResponse>
</s:Body>
</s:Envelope>
C#
static void DelegateAccessSearchEmailWithFilter(ExchangeService service)
ItemSchema.DateTimeReceived,
EmailMessageSchema.IsRead);
view.Traversal = ItemTraversal.Shallow;
// Sorting.
view.OrderBy.Add(ItemSchema.DateTimeReceived, SortDirection.Descending);
try
FolderId(WellKnownFolderName.Inbox, "[email protected]"),
filter, view);
if (item is EmailMessage)
After the FindItems call returns a response with an ID, you can get, update or delete that
email by using the ID and implicit access - and you do not need to specify the mailbox
owner's SMTP address.
This is also the XML request that the EWS Managed API sends when you search for an
email.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:FindItem Traversal="Shallow">
<m:ItemShape>
<t:BaseShape>IdOnly</t:BaseShape>
<t:AdditionalProperties>
</t:AdditionalProperties>
</m:ItemShape>
<m:IndexedPageItemView MaxEntriesReturned="10"
Offset="0"
BasePoint="Beginning" />
<m:Restriction>
<t:Contains ContainmentMode="Substring"
ContainmentComparison="IgnoreCase">
</t:Contains>
</m:Restriction>
<m:SortOrder>
<t:FieldOrder Order="Descending">
</t:FieldOrder>
</m:SortOrder>
<m:ParentFolderIds>
<t:DistinguishedFolderId Id="inbox">
<t:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:Mailbox>
</t:DistinguishedFolderId>
</m:ParentFolderIds>
</m:FindItem>
</soap:Body>
</soap:Envelope>
The server responds to the FindItem request with a FindItemResponse message that
includes a ResponseCode element value of NoError, which indicates that the search
completed successfully. The response contains a Message element for any emails that
met the search criteria. In this case, only one email is found.
The value of the ItemId element has been shortened for readability.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="15"
MinorVersion="0"
MajorBuildNumber="893"
MinorBuildNumber="17"
Version="V2_10"
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance" />
</s:Header>
<s:Body>
<m:FindItemResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:FindItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:RootFolder IndexedPagingOffset="1"
TotalItemsInView="1"
IncludesLastItemInRange="true">
<t:Items>
<t:Message>
<t:ItemId Id="iNwoAAA="
ChangeKey="CQAAABYAAADOilbYa8KaT7ZgMoTz2P+hAAABiQuu" />
<t:Subject>Soccer team</t:Subject>
<t:DateTimeReceived>2014-03-
10T06:16:55Z</t:DateTimeReceived>
<t:IsRead>false</t:IsRead>
</t:Message>
</t:Items>
</m:RootFolder>
</m:FindItemResponseMessage>
</m:ResponseMessages>
</m:FindItemResponse>
</s:Body>
</s:Envelope>
Now that you have the ItemId for the email that meets your criteria, you can get,
update, or delete that email by using the ItemId and implicit access - and you do not
need to specify the mailbox owner's SMTP address.
Update an email Bind followed by Update an item by using the EWS Managed
Update
API
See also
Delegate access and EWS in Exchange
Add and remove delegates by using EWS in Exchange
Set folder permissions for another user by using EWS in Exchange
Calendars and EWS in Exchange
Set folder permissions for another user
by using EWS in Exchange
Article • 09/15/2021 • 12 minutes to read
Learn how to set permission levels on a folder by using the EWS Managed API or EWS in
Exchange.
Folder-level permissions enable users to access one or more folders in another user's
mailbox. Folder permissions are similar to delegate access, but they differ in the
following ways:
Folder permissions do not enable a user to "send on behalf of" or "send as"
another user. They only enable access to folders. Users can create items in those
folders, but they can't send them.
You can set folder permissions on any folder in the mailbox, but you can only add
a delegate to the Calendar, Contacts, Inbox, Journal, Notes, and Tasks folders.
You can set a number of permissions on a specific folder. When you add a
delegate, you can assign one of only five permission levels.
You can set folder permissions for anonymous and default users. You can only
grant delegate access to a mail-enabled account.
If you're familiar with Access Control Entries (ACEs) and Discretionary Access Control
Lists (DACLs), you know that a user can only have one set of permissions for each folder.
If you try to add a set of permissions for a user and they already have a set of
permissions, you'll get an error. When you add, remove, or update permissions on a
folder, you get the current DACL, add or remove any ACEs, and then send the updated
DACL. You cannot add multiple ACEs for the same user. When you update permissions
by using the EWS Managed API, you need to remove the user's current ACE and then
add their new ACE to the collection. If you're using EWS, you just replace the previous
set of ACEs with the new ones.
If you're making multiple permission changes to a single folder, you can batch additions,
removals, or updates —just note that you cannot batch user updates on multiple
folders. One call is required to get the permissions on a single folder, and a second call
is required to update the permissions on that folder. When you add, remove, or update
user permissions, you use the same two method calls or operations for each task.
Table 1. EWS Managed API methods and EWS operations for setting folder
permissions
If you want to… Use this EWS Managed API Use this EWS operation…
method…
folder permissions
Folder permissions
You have quite a few options when it comes to setting folder permissions on a specific
folder. You can set a permission level on a folder for each user, which adds a set of
predefined individual permissions to the DACL, or you can set individual permissions on
a folder — but you can't mix and match.
Can create
Can create subfolders
Is folder owner
Is folder visible
Is folder contact
Edit items
Delete items
Read items
In addition, the following permission levels are available, which define a subset of
individual permissions and values, as shown in Table 2:
None
Owner
PublishingEditor
Editor
PublishingAuthor
Author
NoneditingAuthor
Reviewer
Contributor
Custom - This value cannot be set by the application. The server sets this value if
the application includes a custom collection of individual permissions.
FreeBusyTimeOnly - This can only be set on Calendar folders.
FreeBusyTimeAndSubjectAndLocation - This can only be set on Calendar folders.
The following table shows which individual permissions are applied by default based on
permission level.
If you specify a non-custom permission level in the folder-level permissions request, you
don't need to specify the individual permission settings. If you do specify an individual
permission when you set a permission level, an ErrorInvalidPermissionSettings error will
be returned in the response.
Get the current permissions for a folder by using the Bind method.
Call the Update method to save the new permissions to the server.
This example assumes that service is a valid ExchangeService object for the mailbox
owner and that the user has been authenticated to an Exchange server.
C#
// Specify the SMTP address of the new user and the folder permissions
level.
// Add the permissions for the new user to the Sent Items DACL.
sentItemsFolder.Permissions.Add(fldperm);
sentItemsFolder.Update();
C#
If you want to use the custom permission level, use this code instead.
C#
fldperm.UserId = "[email protected]";
fldperm.CanCreateItems = true;
fldperm.CanCreateSubFolders = true;
You can set any or all of the writable FolderPermission properties when you create a
FolderPermission object with a custom permission level. Note, however, that the
FolderPermissionLevel is never explicitly set to Custom by the application. The
FolderPermissionLevel is set to Custom only when you create a FolderPermission object
and set individual permissions.
Adding folder permissions by using EWS
The following EWS code examples show how to add permissions to a specific folder by
retrieving the current permissions and then submitting a list of new permissions.
The first step is to send a GetFolder request, where the DistinguishedFolderId value
specifies the folder in which to add permissions (the Sent Items folder in this example)
and the FieldURI value includes folder:PermissionSet. This request will retrieve the
permission settings for the folder specified.
This is also the XML request that the EWS Managed API sends when you call the Bind
method to add folder permissions.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:GetFolder>
<m:FolderShape>
<t:BaseShape>IdOnly</t:BaseShape>
<t:AdditionalProperties>
</t:AdditionalProperties>
</m:FolderShape>
<m:FolderIds>
</m:FolderIds>
</m:GetFolder>
</soap:Body>
</soap:Envelope>
The server responds to the GetFolder request with a GetFolderResponse message that
includes a ResponseCode element value of NoError, which indicates that the folder
was retrieved successfully. The FolderId and ParentFolderId values have been
shortened for readability.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="15"
MinorVersion="0"
MajorBuildNumber="893"
MinorBuildNumber="17"
Version="V2_10"
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:GetFolderResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:GetFolderResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Folders>
<t:Folder>
<t:FolderId Id="CgAAAA=="
ChangeKey="AQAAABYAAADOilbYa8KaT7ZgMoTz2P+hAAABiRd1" />
<t:PermissionSet>
<t:Permissions>
<t:Permission>
<t:UserId>
<t:DistinguishedUser>Default</t:DistinguishedUser>
</t:UserId>
<t:CanCreateItems>false</t:CanCreateItems>
<t:CanCreateSubFolders>false</t:CanCreateSubFolders>
<t:IsFolderOwner>false</t:IsFolderOwner>
<t:IsFolderVisible>false</t:IsFolderVisible>
<t:IsFolderContact>false</t:IsFolderContact>
<t:EditItems>None</t:EditItems>
<t:DeleteItems>None</t:DeleteItems>
<t:ReadItems>None</t:ReadItems>
<t:PermissionLevel>None</t:PermissionLevel>
</t:Permission>
<t:Permission>
<t:UserId>
<t:DistinguishedUser>Anonymous</t:DistinguishedUser>
</t:UserId>
<t:CanCreateItems>false</t:CanCreateItems>
<t:CanCreateSubFolders>false</t:CanCreateSubFolders>
<t:IsFolderOwner>false</t:IsFolderOwner>
<t:IsFolderVisible>false</t:IsFolderVisible>
<t:IsFolderContact>false</t:IsFolderContact>
<t:EditItems>None</t:EditItems>
<t:DeleteItems>None</t:DeleteItems>
<t:ReadItems>None</t:ReadItems>
<t:PermissionLevel>None</t:PermissionLevel>
</t:Permission>
</t:Permissions>
</t:PermissionSet>
</t:Folder>
</m:Folders>
</m:GetFolderResponseMessage>
</m:ResponseMessages>
</m:GetFolderResponse>
</s:Body>
</s:Envelope>
Next, use the UpdateFolder operation to send the updated PermissionSet , which
includes the Permission for the new user. Note that including the SetFolderField
element for the respective folder in the UpdateFolder operation will overwrite all the
permission settings on the folder. Likewise, including the DeleteFolderField option of
the UpdateFolder operation will also delete all the permission settings on the folder.
This is also the XML request that the EWS Managed API sends when you call the Update
method to add folder permissions.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:UpdateFolder>
<m:FolderChanges>
<t:FolderChange>
<t:FolderId Id="CgAAAA=="
ChangeKey="AQAAABYAAADOilbYa8KaT7ZgMoTz2P+hAAABiRd1"
/>
<t:Updates>
<t:SetFolderField>
<t:Folder>
<t:PermissionSet>
<t:Permissions>
<t:Permission>
<t:UserId>
<t:DistinguishedUser>Default</t:DistinguishedUser>
</t:UserId>
<t:PermissionLevel>None</t:PermissionLevel>
</t:Permission>
<t:Permission>
<t:UserId>
<t:DistinguishedUser>Anonymous</t:DistinguishedUser>
</t:UserId>
<t:PermissionLevel>None</t:PermissionLevel>
</t:Permission>
<t:Permission>
<t:UserId>
<t:PrimarySmtpAddress>[email protected]</t:PrimarySmtpAddress>
</t:UserId>
<t:PermissionLevel>Editor</t:PermissionLevel>
</t:Permission>
</t:Permissions>
</t:PermissionSet>
</t:Folder>
</t:SetFolderField>
</t:Updates>
</t:FolderChange>
</m:FolderChanges>
</m:UpdateFolder>
</soap:Body>
</soap:Envelope>
XML
<t:Permission>
<t:UserId>
<t:PrimarySmtpAddress>[email protected]</t:PrimarySmtpAddress>
</t:UserId>
<t:PermissionLevel>Editor</t:PermissionLevel>
</t:Permission>
If you want to use the custom permission level, use this code instead.
XML
<t:Permission>
<t:UserId>
</t:UserId>
<t:CanCreateItems>true</t:CanCreateItems>
<t:CanCreateSubFolders>true</t:CanCreateSubFolders>
<t:IsFolderOwner>false</t:IsFolderOwner>
<t:IsFolderVisible>false</t:IsFolderVisible>
<t:IsFolderContact>false</t:IsFolderContact>
<t:EditItems>None</t:EditItems>
<t:DeleteItems>None</t:DeleteItems>
<t:ReadItems>None</t:ReadItems>
<t:PermissionLevel>Custom</t:PermissionLevel>
</t:Permission>
1. Getting the current permissions for a folder by using the Bind method.
This example removes all user permissions on a folder. If you want to modify this
example to remove permissions only for a specific user, change the following line of
code to identify either the display name or SMTP address of the user.
C#
if (sentItemsFolder.Permissions[t].UserId.DisplayName != null ||
sentItemsFolder.Permissions[t].UserId.PrimarySmtpAddress != null)
This example assumes that service is a valid ExchangeService object for the mailbox
owner and that the user has been authenticated to an Exchange server.
C#
// user with a display name or SMTP address. This leaves the anonymous
and
if (sentItemsFolder.Permissions.Count != 0)
if (sentItemsFolder.Permissions[t].UserId.DisplayName != null ||
sentItemsFolder.Permissions[t].UserId.PrimarySmtpAddress != null)
sentItemsFolder.Permissions.Remove(sentItemsFolder.Permissions[t]);
sentItemsFolder.Update();
First, send a GetFolder request where the DistinguishedFolderId value specifies the
folder in which to remove permissions (the Sent Items folder in this example) and the
FieldURI value includes folder:PermissionSet. This request will retrieve the
PermissionSet for the folder specified.
This is also the XML request that the EWS Managed API sends when you call the Bind
method to remove folder permissions.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:GetFolder>
<m:FolderShape>
<t:BaseShape>AllProperties</t:BaseShape>
<t:AdditionalProperties>
</t:AdditionalProperties>
</m:FolderShape>
<m:FolderIds>
<t:DistinguishedFolderId Id="drafts">
<t:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:Mailbox>
</t:DistinguishedFolderId>
</m:FolderIds>
</m:GetFolder>
</soap:Body>
</soap:Envelope>
The server responds to the GetFolder request with a GetFolderResponse message that
includes a ResponseCode element value of NoError, which indicates that the folder
was retrieved successfully. The values of the FolderId and ParentFolderId elements have
been shortened for readability.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="15"
MinorVersion="0"
MajorBuildNumber="893"
MinorBuildNumber="17"
Version="V2_10"
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:GetFolderResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:GetFolderResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Folders>
<t:Folder>
<t:FolderId Id="EAAAAA=="
ChangeKey="AQAAABYAAADOilbYa8KaT7ZgMoTz2P+hAAABiRd5" />
<t:ParentFolderId Id="CQAAAA=="
ChangeKey="AQAAAA==" />
<t:FolderClass>IPF.Note</t:FolderClass>
<t:DisplayName>Drafts</t:DisplayName>
<t:TotalCount>0</t:TotalCount>
<t:ChildFolderCount>0</t:ChildFolderCount>
<t:EffectiveRights>
<t:CreateAssociated>true</t:CreateAssociated>
<t:CreateContents>true</t:CreateContents>
<t:CreateHierarchy>true</t:CreateHierarchy>
<t:Delete>true</t:Delete>
<t:Modify>true</t:Modify>
<t:Read>true</t:Read>
<t:ViewPrivateItems>true</t:ViewPrivateItems>
</t:EffectiveRights>
<t:PermissionSet>
<t:Permissions>
<t:Permission>
<t:UserId>
<t:DistinguishedUser>Default</t:DistinguishedUser>
</t:UserId>
<t:CanCreateItems>false</t:CanCreateItems>
<t:CanCreateSubFolders>false</t:CanCreateSubFolders>
<t:IsFolderOwner>false</t:IsFolderOwner>
<t:IsFolderVisible>false</t:IsFolderVisible>
<t:IsFolderContact>false</t:IsFolderContact>
<t:EditItems>None</t:EditItems>
<t:DeleteItems>None</t:DeleteItems>
<t:ReadItems>None</t:ReadItems>
<t:PermissionLevel>None</t:PermissionLevel>
</t:Permission>
<t:Permission>
<t:UserId>
<t:DistinguishedUser>Anonymous</t:DistinguishedUser>
</t:UserId>
<t:CanCreateItems>false</t:CanCreateItems>
<t:CanCreateSubFolders>false</t:CanCreateSubFolders>
<t:IsFolderOwner>false</t:IsFolderOwner>
<t:IsFolderVisible>false</t:IsFolderVisible>
<t:IsFolderContact>false</t:IsFolderContact>
<t:EditItems>None</t:EditItems>
<t:DeleteItems>None</t:DeleteItems>
<t:ReadItems>None</t:ReadItems>
<t:PermissionLevel>None</t:PermissionLevel>
</t:Permission>
<t:Permission>
<t:UserId>
<t:SID>S-1-5-21-1337771579-694202782-848329751-
1535223</t:SID>
<t:PrimarySmtpAddress>[email protected]</t:PrimarySmtpAddress>
<t:DisplayName>Sadie Daniels</t:DisplayName>
</t:UserId>
<t:CanCreateItems>true</t:CanCreateItems>
<t:CanCreateSubFolders>false</t:CanCreateSubFolders>
<t:IsFolderOwner>false</t:IsFolderOwner>
<t:IsFolderVisible>true</t:IsFolderVisible>
<t:IsFolderContact>false</t:IsFolderContact>
<t:EditItems>All</t:EditItems>
<t:DeleteItems>All</t:DeleteItems>
<t:ReadItems>FullDetails</t:ReadItems>
<t:PermissionLevel>Editor</t:PermissionLevel>
</t:Permission>
</t:Permissions>
</t:PermissionSet>
<t:UnreadCount>0</t:UnreadCount>
</t:Folder>
</m:Folders>
</m:GetFolderResponseMessage>
</m:ResponseMessages>
</m:GetFolderResponse>
</s:Body>
</s:Envelope>
Next, use the UpdateFolder operation to send the updated PermissionSet, which does
not include the Permission for the removed user.
This is also the XML request that the EWS Managed API sends when you call the Update
method to remove folder permissions.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:UpdateFolder>
<m:FolderChanges>
<t:FolderChange>
<t:FolderId Id="EAAAAA=="
ChangeKey="AQAAABYAAADOilbYa8KaT7ZgMoTz2P+hAAABiRd5"
/>
<t:Updates>
<t:SetFolderField>
<t:Folder>
<t:PermissionSet>
<t:Permissions>
<t:Permission>
<t:UserId>
<t:DistinguishedUser>Default</t:DistinguishedUser>
</t:UserId>
<t:PermissionLevel>None</t:PermissionLevel>
</t:Permission>
<t:Permission>
<t:UserId>
<t:DistinguishedUser>Anonymous</t:DistinguishedUser>
</t:UserId>
<t:PermissionLevel>None</t:PermissionLevel>
</t:Permission>
</t:Permissions>
</t:PermissionSet>
</t:Folder>
</t:SetFolderField>
</t:Updates>
</t:FolderChange>
</m:FolderChanges>
</m:UpdateFolder>
</soap:Body>
</soap:Envelope>
1. Remove the folder permissions for the outdated permissions, but do not call the
Update method (yet).
If you try to add two sets of permissions for the same user, you will receive a
ServiceResponseException error with the following description: "The specified
permission set contains duplicate UserIds". In that case, remove the current permissions
from the Permission collection, then add the new permissions to the Permission
collection.
These are the same two operations you use to enable or remove access by using EWS.
The only difference is that when you receive the GetFolder response, it will contain a
Permission set for user. Simply replace that existing Permission element with the new
Permission element, and then send the UpdateFolder operation with the new
Permission value or values.
If you try to add two sets of permissions for the same user, you will receive a
ResponseCode value of ErrorDuplicateUserIdsSpecified. In that case, remove the
outdated Permission value for the user from the request and then retry the request.
Next steps
After you give a user permission to a specific folder, the user can access the folder as a
delegate. For more information, see:
See also
Delegate access and EWS in Exchange
Add and remove delegates by using EWS in Exchange
Folders and items in EWS in Exchange
Handling delegation-related errors in
EWS in Exchange
Article • 09/15/2021 • 2 minutes to read
Find out how to handle delegation-related errors in applications that you develop by
using the EWS Managed API or EWS in Exchange.
If your application uses delegation or adds or removes delegates, you might have to
handle delegation-related errors. You can handle these errors at runtime, or while you
are developing your EWS application. These errors are defined by the EWS Managed API
ServiceError enumeration and the EWS ResponseCode element.
Delegation-related errors
Error Occurs when Handle it by…
you try to…
See also
Delegate access and EWS in Exchange
Learn about the different types of distribution groups that are available in Exchange and
how you can manage them in your EWS Managed API or EWS application.
A distribution group is a collection of email addresses that are associated with a single
alias or email address. Distribution groups (also sometimes called distribution lists)
enable a user to send email to multiple people by using a single recipient address.
Because distribution group membership, and therefore the message recipients, can be
managed outside of individual email threads, distribution groups provide an excellent
way to enable the distribution of mail to a group of users. You can programmatically
create and manage distribution groups by using the EWS Managed API, EWS, and the
Exchange Management Shell. Before you start programming, let's explore the different
types of distribution groups that are available and your options for managing them.
Security groups — Active Directory objects that are mail-enabled; also known as
universal security groups. Security groups are used to assign access permissions to
resources in Active Directory Domain Services (AD DS) as well as to distribute
messages.
Contact groups — Private distribution groups that are located in a user's mailbox.
The type of distribution group that you choose will depend on where you plan to store
the distribution group, who will use it, and what it will be used for.
You can also use universal distribution groups to contain a collection of rooms; for
example, to make it easier for users to find a conference room for a meeting. Users can
add a room list — a universal distribution group that contains room resource mailboxes
— to a meeting request to find an available room without having to add each room
individually.
You can create a static universal distribution group that stays the same until you to
update the membership, or you can create a dynamic universal distribution group. A
dynamic universal distribution group queries Active Directory mail-enabled objects and
builds the group membership based on the results. The group membership is
recalculated whenever an email message is sent to the group.
Security groups
Universal distribution groups and security groups are identical in most ways. However,
unlike universal distribution groups, you can use security groups to assign permissions
to network resources in AD DS. You cannot use the EWS Managed API or EWS to create
and manage security groups; instead, you use Exchange Management Shell cmdlets.
But, just like universal distribution groups, you can use the EWS Managed API or EWS to
expand security groups.
Contact groups
If you don't want to give every user administrative access to the server to create
distribution groups, but you want to enable them to send a single message to a large
collection of people, you can do this by using contact groups. A contact group does not
have an email address associated with it, and it exists only in one user's mailbox; other
users won't have access to it. You can use the EWS Managed API or EWS to create
contact groups.
ContactGroup CreateItem
Create a contact group in the Exchange store.
class
methods NOTE: You cannot create a universal distribution group or
security group by using EWS Managed API or EWS.
ExpandGroup ExpandDL
Expand a universal distribution group, security group, or
contact group by retrieving a list of its members.
FindItems FindItem
Search for contact groups in the mailbox.
GetRooms
GetRooms
Retrieve a collection of all rooms in a specified room list in
an organization. A room list is a distribution group that only
contains room resource mailboxes.
You can use the information returned by the ExpandGroup method or the
ExpandDL operation to determine what types of members are in the group. The
member types are defined by the MailboxType EWS Managed API enumeration and
the MailboxType EWS element.
PublicGroup PublicDL A distribution group contained within the group you just
expanded. To get a full list of members, expand this group as
well.
ContactGroup PrivateDL A group of contacts that is located in the mailbox and is only
available to users of that mailbox.
7 Note
You cannot use Exchange Management Shell cmdlets to manage contact groups.
Table 3. Exchange Management Shell cmdlets for working with distribution groups
Enable-DistributionGroup
Mail-enable an existing universal group.
Get-DistributionGroup
Query for existing distribution groups.
New-DistributionGroup
Create a distribution group.
Set-DistributionGroup
Modify the settings of an existing distribution group.
In this section
Create contact groups by using EWS in Exchange
Expand distribution groups by using EWS in Exchange 2013
See also
Develop web service clients for Exchange
Calling Exchange Management Shell Cmdlets from Managed Code
Create contact groups by using EWS in
Exchange
Article • 09/15/2021 • 2 minutes to read
Learn how to create a contact group by using the EWS Managed API or EWS in
Exchange.
You can create a contact group, which is a private distribution group, by using the EWS
Managed API or EWS. To create contact groups, use the methods in the ContactGroup
EWS Managed API class, or use the CreateItem EWS operation.
Note that you can't use the EWS Managed API or EWS to create a universal distribution
group or security group. To create a universal distribution group or security group, you
can use the New-DistributionGroup Exchange Management Shell cmdlet .
C#
myContactGroup.Members.Add(new GroupMember("[email protected]"));
myContactGroup.Save();
<CreateItem
xmlns="https://schemas.microsoft.com/exchange/services/2006/messages"
MessageDisposition="SaveOnly">
<Items
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages">
<DistributionList
xmlns="https://schemas.microsoft.com/exchange/services/2006/types">
<DisplayName
xmlns="https://schemas.microsoft.com/exchange/services/2006/types">
My Contact Group
</DisplayName>
<Members
xmlns="https://schemas.microsoft.com/exchange/services/2006/types">
<Member
xmlns="https://schemas.microsoft.com/exchange/services/2006/types">
<Mailbox
xmlns="https://schemas.microsoft.com/exchange/services/2006/types">
<EmailAddress
xmlns="https://schemas.microsoft.com/exchange/services/2006/types">
</EmailAddress>
</Mailbox>
</Member>
<Member
xmlns="https://schemas.microsoft.com/exchange/services/2006/types">
<Mailbox
xmlns="https://schemas.microsoft.com/exchange/services/2006/types">
<EmailAddress
xmlns="https://schemas.microsoft.com/exchange/services/2006/types">
</EmailAddress>
</Mailbox>
</Member>
</Members>
</DistributionList>
</Items>
</CreateItem>
The following is an example of a successful XML response to the request. Notice that the
values returned include an item ID for the new contact group and a change key that you
can use in other code to modify the contact group or expand the group to see the
members. The item ID is shortened for readability.
XML
<CreateItemResponse
xmlns="https://schemas.microsoft.com/exchange/services/2006/messages">
<ResponseMessages
xmlns="https://schemas.microsoft.com/exchange/services/2006/messages">
<CreateItemResponseMessage ResponseClass="Success"
xmlns="https://schemas.microsoft.com/exchange/services/2006/messages">
<ResponseCode
xmlns="https://schemas.microsoft.com/exchange/services/2006/messages">
NoError
</ResponseCode>
<Items
xmlns="https://schemas.microsoft.com/exchange/services/2006/messages">
<DistributionList
xmlns="https://schemas.microsoft.com/exchange/services/2006/types">
<ItemId
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
Id="AAMkADBlY…"
ChangeKey="EgAAABYAAAAD7hO1SJPWTbICFWZ4U3NMAABXzQiK" />
</DistributionList>
</Items>
</CreateItemResponseMessage>
</ResponseMessages>
</CreateItemResponse>
See also
Distribution groups and EWS in Exchange
Learn how to expand a distribution group by using the EWS Managed API or EWS in
Exchange.
You can use the ExchangeService.ExpandGroup EWS Managed API method or the
ExpandDL EWS operation to expand a distribution group to identify all recipients.
Because the ExpandGroup method is overloaded, you can call it in several ways:
C#
ExpandGroupResults myGroupMembers =
service.ExpandGroup("[email protected]");
That's not a lot of code, but it's also pretty basic and might not give you what you are
looking for. So let's take it a step further. Distribution groups can also contain other
distribution groups. Simply expanding it will output the email address of the contained
distribution groups but not expand them. By adding a few more lines of code, you can
recursively expand the groups to output every contact.
C#
if (address.MailboxType == MailboxType.PublicGroup)
// distribution group.
ExpandDistributionLists(service, address.Address);
else
And now you can call this new function in the your code and expand all the public
distribution groups contained within the first one.
C#
ExpandDistributionLists(service, "[email protected]");
if (address.MailboxType == MailboxType.PublicGroup)
ExpandDistributionLists(service, address.Address);
else
Now you can call this function by using the Exchange service object and the ItemId of
the contact group. Note that the ItemId in the example is shortened for readability.
C#
XML
<soap:Envelope xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<soap:Body>
<ExpandDL
xmlns="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</Mailbox>
</ExpandDL>
</soap:Body>
</soap:Envelope>
The following example shows the XML response message that is sent from the server to
the client. Notice that both mailboxes and universal distribution groups are returned.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ExpandDLResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ResponseMessages
xmlns="https://schemas.microsoft.com/exchange/services/2006/messages">
<ExpandDLResponseMessage ResponseClass="Success">
<ResponseCode>NoError</ResponseCode>
<Mailbox
xmlns="https://schemas.microsoft.com/exchange/services/2006/types">
<Name>Sadie Daniels</Name>
<EmailAddress>[email protected]</EmailAddress>
<RoutingType>SMTP</RoutingType>
<MailboxType>Mailbox</MailboxType>
</Mailbox>
<Mailbox
xmlns="https://schemas.microsoft.com/exchange/services/2006/types">
<Name>Alfred Welker</Name>
<EmailAddress>[email protected]</EmailAddress>
<RoutingType>SMTP</RoutingType>
<MailboxType>Mailbox</MailboxType>
</Mailbox>
<Mailbox
xmlns="https://schemas.microsoft.com/exchange/services/2006/types">
<Name>Contoso Sales</Name>
<EmailAddress>[email protected]</EmailAddress>
<RoutingType>SMTP</RoutingType>
<MailboxType>PublicDL</MailboxType>
</Mailbox>
<Mailbox
xmlns="https://schemas.microsoft.com/exchange/services/2006/types">
<Name>Contoso Support</Name>
<EmailAddress>[email protected]</EmailAddress>
<RoutingType>SMTP</RoutingType>
<MailboxType>PublicDL</MailboxType>
</Mailbox>
</DLExpansion>
</ExpandDLResponseMessage>
</ResponseMessages>
</ExpandDLResponse>
</s:Body>
</s:Envelope>
Unlike when you use the EWS Managed API, when you use EWS to expand a universal
distribution group, you can't recursively expand the distribution groups that are
returned. You will need to send an additional request to expand each of the distribution
groups included in the response.
XML
<soap:Envelope xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<soap:Body>
<ExpandDL
xmlns="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<Mailbox>
<ItemId
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
Id="AAMkADBlY…" />
</Mailbox>
</ExpandDL>
</soap:Body>
</soap:Envelope>
The structure of the XML response to a request to expand a contact group is the same
as the response to a request to expand a universal distribution group.
See also
Distribution groups and EWS in Exchange
Discovery consists of several phases, including identifying and preserving key data,
culling down and reviewing the data, and producing data in court. eDiscovery queries
facilitate the discovery process by providing a single discovery workflow across
Exchange and SharePoint.
eDiscovery operations
The eDiscovery functionality that is exposed by EWS is available via operations
introduced in Exchange Online, Exchange Online as part of Office 365, and versions of
Exchange starting with Exchange 2013.
GetHoldOnMailboxes
Gets the status of a query-based hold, which is set by using
the SetHoldOnMailboxes operation .
GetNonIndexableItemDetails
Retrieves details about items that cannot be indexed. This
includes, but is not limited to, the item identifier, an error
code, an error description, when an attempt was made to
index the item, and additional information about the file.
GetNonIndexableItemStatistics
Retrieves the count of items that cannot be indexed in a
mailbox.
GetSearchableMailboxes
Gets a list of mailboxes that the client has permission to
search or perform eDiscovery on.
SearchMailboxes
Searches for items in specific mailboxes that match query
keywords.
SetHoldOnMailboxes
Sets a query-based hold on items.
See also
Develop web service clients for Exchange
Find out how to work with email messages, including how to create an email and how to
perform other email-related tasks by using the EWS Managed API or EWS in Exchange.
At its core, Exchange is about email. But what makes an email an email? Well, email
messages are one of the strongly typed items in Exchange, which means that they
contain a particular set of properties, even before they're sent. Email messages are
represented by the EmailMessage class in the EWS Managed API and by the
Message element and its child elements in EWS.
In the EWS Managed API, the EmailMessage object derives from the Item object. The
EmailMessage class extends the Item class by providing additional properties like
EmailMessage.Sender and EmailMessage.IsRead , which are now common to nearly
all messaging scenarios. When you get, update, or delete an email message, in most
cases you can do that by using the EmailMessage object or the base Item object,
depending on whether the properties you're working with are in the
EmailMessageSchema or the ItemSchema class. Item creation is different because
the Item class does not have a constructor, so when you're creating an email, you'll use
the EmailMessage constructor to create it and the EmailMessage.Save or
EmailMessage.SendAndSaveCopy methods to save it, or send it and save it.
Similarly, in EWS, use the CreateItem operation with the Message element to create
an email message. To get, update, or delete emails by using EWS, the fact that the item
being modified is an email message is not important, aside from the fact that additional
properties are available on email messages. The same operations that are used for other
strongly typed items are also used for email messages.
Create EmailMessage.Save
CreateItem
Get EmailMessage.Bind
GetItem
Update Item.Update
UpdateItem
Delete Item.Delete
DeleteItem
Because email messages are simply strongly typed items, in some cases you work with
them in the same way that you work with generic items.
Create an email message by using the EWS
Managed API
You can create an email message by using the EWS Managed API Save method, as
shown in the code in the following example. Note that the example only saves the
message in the Drafts folder, it does not send the message. For information about how
to send the message or create and send the message in one step, see Send email
messages by using EWS in Exchange.
This example assumes that service is a valid ExchangeService object and that the user
has been authenticated to an Exchange server.
C#
message.ToRecipients.Add("[email protected]");
// Save the email message to the Drafts folder (where it can be retrieved,
updated, and sent at a later time).
message.Save(WellKnownFolderName.Drafts);
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:CreateItem MessageDisposition="SaveOnly">
<m:SavedItemFolderId>
</m:SavedItemFolderId>
<m:Items>
<t:Message>
<t:Subject>Project priorities</t:Subject>
<t:ToRecipients>
<t:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:Mailbox>
</t:ToRecipients>
</t:Message>
</m:Items>
</m:CreateItem>
</soap:Body>
</soap:Envelope>
If you're updating an email message, see Email properties and elements in EWS in
Exchange for a list of writable email message properties. To send a draft message after
you've updated it, see Send a draft email message by using the EWS Managed API.
If you're updating an email message, see Email properties and elements in EWS in
Exchange for a list of writable email message properties. To send a draft message after
you've updated it, see Send a draft email message by using EWS.
In this section
Email properties and elements in EWS in Exchange
See also
Develop web service clients for Exchange
Folders and items in EWS in Exchange
Email properties and elements in EWS in
Exchange
Article • 01/15/2020 • 4 minutes to read
Learn about the first-class and other properties and elements that you can get on email
messages by using the EWS Managed API or EWS in Exchange.
Email messages have more than 50 properties, and getting the ones you want, when
you want them, can be confusing if you don't know where to look. The most important
thing to know about working with email properties and elements is which are included
in the set of first-class properties and elements that is returned by each of the main
retrieval methods and operations. The set of first-class properties that is returned varies
based on the retrieval method that you use. It's also important not to be fooled by the
AllProperties value of the BaseShape EWS element, which corresponds to the
BasePropertySet.FirstClassMessageProperties enumeration value in the EWS Managed
API. This value doesn't actually include all properties, it only includes the first-class
properties.
Id
ItemId
Yes Read-
only
ItemClass
ItemClass
Yes Read-
write
Subject
Subject
Yes Read-
write
Sensitivity
Sensitivity
Yes Read-
only
Body
Body
No Read-
write
Attachments
Attachments
No Read-
write
DateTimeReceived
DateTimeReceived
Yes Read-
only
Size
Size
Yes Read-
only
Categories
Categories
No Read-
write
Importance
Importance
Yes Read-
write
InReplyTo
InReplyTo
Yes Read-
write
IsSubmitted
IsSubmitted
Yes Read-
only
EWS Managed API property EWS element First-class Read-
property for write
the FindItems or
method or read-
the FindItem only
operation?
IsDraft
IsDraft
Yes Read-
only
IsFromMe
IsFromMe
Yes Read-
only
IsResend
IsResend
Yes Read-
only
IsUnmodified
IsUnmodified
Yes Read-
only
InternetMessageHeaders
InternetMessageHeaders
No Read-
only
DateTimeSent
DateTimeSent
Yes Read-
only
DateTimeCreated
DateTimeCreated
Yes Read-
only
AllowedResponseActions
ResponseObjects
No Read-
only
ReminderDueBy
ReminderDueBy
Yes Read-
write
IsReminderSet
ReminderIsSet
Yes Read-
write
ReminderMinutesBeforeStart
ReminderMinutesBeforeStart
Yes Read-
write
DisplayCc
DisplayCc
Yes Read-
only
DisplayTo
DisplayTo
Yes Read-
only
HasAttachments
HasAttachments
Yes Read-
only
Culture
Culture
Yes Read-
write
EWS Managed API property EWS element First-class Read-
property for write
the FindItems or
method or read-
the FindItem only
operation?
EffectiveRights
EffectiveRights
Yes Read-
only
LastModifiedName
LastModifiedName
Yes Read-
only
LastModifiedTime
LastModifiedTime
Yes Read-
only
IsAssociated
IsAssociated
Yes Read-
write
WebClientEditFormQueryString
WebClientEditFormQueryString
Yes Read-
only
ConversationId
ConversationId
Yes Read-
only
Flag
Flag
Yes Read-
write
InstanceKey
InstanceKey
Yes Read-
only
EntityExtractionResult
EntityExtractionResult
No Read-
only
Sender
Sender
Yes Read-
write
ToRecipients
ToRecipients
No Read-
only
CcRecipients
CcRecipients
No Read-
only
BccRecipients
BccRecipients
No Read-
only
IsReadReceiptRequested
IsReadReceiptRequested
Yes Read-
write
EWS Managed API property EWS element First-class Read-
property for write
the FindItems or
method or read-
the FindItem only
operation?
IsDeliveryReceiptRequested
IsDeliveryReceiptRequested
Yes Read-
write
ConversationIndex
ConversationIndex
Yes Read-
only
ConversationTopic
ConversationTopic
Yes Read-
only
From
From
Yes Read-
write
InternetMessageId
InternetMessageId
Yes Read-
only
IsRead
IsRead
Yes Read-
write
IsResponseRequested
IsResponseRequested
Yes Read-
write
ReplyTo
ReplyTo
No Read-
only
References
References
Yes Read-
write
ReceivedBy
ReceivedBy
Yes Read-
only
ReceivedRepresenting
ReceivedRepresenting
Yes Read-
only
PropertySet(BasePropertySet.IdOnly, ItemSchema.TextBody,
ItemSchema.MimeContent);
Or if you're using EWS, add the elements to the AdditionalProperties element in your
GetItem operation request, as shown.
XML
<t:AdditionalProperties>
</t:AdditionalProperties>
EmailMessage properties inherited from the EWS Managed API ServiceObject object
cannot be included in a property set for the Bind method; however, all the
ServiceObject properties are readable on the EmailMessage object and are retrieved by
the Bind method.
ArchiveTag
ArchiveTag
Read-write
ExtendedProperties
ExtendedProperty
Read-only
IconIndex
IconIndex
Read-only
IsAttachment
Not available Read-only
IsDirty
Not available Read-only
IsNew
Not available Read-only
Item
Item
Read-only
MimeContent
MimeContent
Read-only
NormalizedBody
NormalizedBody
Read-only
PolicyTag
PolicyTag
Read-write
Preview
Preview
Read-write
RetentionDate
RetentionDate
Read-only
EWS Managed API property EWS element Read-write or read-only
Schema
Not available Read-only
Service
Not available Read-only
StoreEntryId
StoreEntryId
Read-only
TextBody
TextBody
Read-only
UniqueBody
UniqueBody
Read-only
See also
Email and EWS in Exchange
Learn how to send new or draft email messages, or to send a delayed email message by
using the EWS Managed API or EWS in Exchange.
Whether you are using the EWS Managed API or EWS, you can send email messages in
two ways. You can either send an existing message, such as a message stored in your
Drafts folder, or you can create and send an email in one step. The methods and
operations that you use to send the message are the same whether you're sending a
message immediately, or sending a delayed message.
Table 1. EWS Managed API methods and EWS operations for sending email messages
This example assumes that service is a valid ExchangeService object and that the user
has been authenticated to an Exchange server.
C#
message.ToRecipients.Add("[email protected]");
message.SendAndSaveCopy();
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:CreateItem MessageDisposition="SendAndSaveCopy">
<m:SavedItemFolderId>
</m:SavedItemFolderId>
<m:Items>
<t:Message>
<t:ToRecipients>
<t:Mailbox>
<t:EmailAddress>[email protected] </t:EmailAddress>
</t:Mailbox>
</t:ToRecipients>
</t:Message>
</m:Items>
</m:CreateItem>
</soap:Body>
</soap:Envelope>
This example assumes that service is a valid ExchangeService object and that the user
has been authenticated to an Exchange server.
C#
message.Send();
The first message, the GetItem request message, specifies the ItemId of the draft
email message to bind to, and elements in the ItemShape element limit the results to
include in the GetItem response. The ItemShape element has a BaseShape of IdOnly,
and the AdditionalProperties element includes the FieldURI values for the Subject
property from the Item schema and the ToRecipients property from the Message
schema, which means that only the ItemId, Subject , and ToRecipients elements will
be returned to the client in the response. For more information about limiting the values
returned in calls and the meaning of the BaseShape element, see Property sets and
response shapes in EWS in Exchange.
This is also the XML request that is sent by the EWS Managed API when calling the
Bind method. The values of some attributes and elements have been shortened for
readability.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:GetItem>
<m:ItemShape>
<t:BaseShape>IdOnly</t:BaseShape>
<t:AdditionalProperties>
</t:AdditionalProperties>
</m:ItemShape>
<m:ItemIds>
</m:ItemIds>
</m:GetItem>
</soap:Body>
</soap:Envelope>
The following example shows the XML response that the server returns after it processes
the GetItem operation. The response indicates that the email message was retrieved
successfully, and includes the Subject and ToRecipient elements as requested. The
values of some attributes and elements have been shortened for readability.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="15"
MinorVersion="0"
MajorBuildNumber="842"
MinorBuildNumber="10"
Version="V2_8"
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:GetItemResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:GetItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:Message>
<t:ItemId Id="AAMkADE4="
ChangeKey="CQAAABYA" />
<t:Subject>Project priorities</t:Subject>
<t:ToRecipients>
<t:Mailbox>
<t:Name>[email protected]</t:Name>
<t:EmailAddress>[email protected]</t:EmailAddress>
<t:RoutingType>SMTP</t:RoutingType>
<t:MailboxType>OneOff</t:MailboxType>
</t:Mailbox>
</t:ToRecipients>
</t:Message>
</m:Items>
</m:GetItemResponseMessage>
</m:ResponseMessages>
</m:GetItemResponse>
</s:Body>
</s:Envelope>
The second message, the SendItem request message, specifies the ItemId of the email
message to send, as well as the SavedItemFolderId , which specifies the folder in which
to save the sent item.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:SendItem SaveItemToFolder="true">
<m:ItemIds>
<t:ItemId Id="AAMkADE4="
ChangeKey="CQAAABYA" />
</m:ItemIds>
<m:SavedItemFolderId>
</m:SavedItemFolderId>
</m:SendItem>
</soap:Body>
</soap:Envelope>
The server responds to the SendItem request with a SendItemResponse message that
includes a ResponseCode value of NoError, which indicates that the email was sent
successfully.
This example assumes that service is a valid ExchangeService object and that the user
has been authenticated to an Exchange server.
C#
message.ToRecipients.Add("[email protected]");
// Identify the extended property that can be used to specify when to send
the email.
// Set the time that will be used to specify when the email is sent.
// In this example, the email will be sent one minute after the next line
executes,
// Specify when to send the email by setting the value of the extended
property.
message.SetExtendedProperty(PidTagDeferredSendTime, sendTime);
message.Body = str.ToString();
Console.WriteLine("");
message.SendAndSaveCopy();
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:CreateItem MessageDisposition="SendAndSaveCopy">
<m:SavedItemFolderId>
</m:SavedItemFolderId>
<m:Items>
<t:Message>
<t:Subject>Delayed email</t:Subject>
<t:Body BodyType="HTML">
</t:Body>
<t:ExtendedProperty>
<t:ExtendedFieldURI PropertyTag="16367"
PropertyType="SystemTime" />
<t:Value>2014-01-02T21:09:52.000</t:Value>
</t:ExtendedProperty>
<t:ToRecipients>
<t:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:Mailbox>
</t:ToRecipients>
</t:Message>
</m:Items>
</m:CreateItem>
</soap:Body>
</soap:Envelope>
See also
Email and EWS in Exchange
Learn how to respond to email messages by using the EWS Managed API or EWS in
Exchange.
You can use the EWS Managed API or EWS to respond to messages by replying to them
or forwarding them to recipients.
Table 1. EWS Managed API methods and EWS operations for responding to email
messages
Reply to an EmailMessage.Reply
CreateItem , where the Items element has
email EmailMessage.CreateReply
a child element of either ReplyToItem or
message ReplyAllToItem .
Forward an EmailMessage.Forward
CreateItem , where the Items element has
email EmailMessage.CreateForward a child element of ForwardItem .
message
The following code example shows how to use the Reply method to respond to an
email message.
This example assumes that service is a valid ExchangeService object and that the user
has been authenticated to an Exchange server. The local variable ItemId is the Id of
the item to respond to. The example calls the FindRecentlySent method to verify that
the message was marked as replied to.
C#
message.Reply(myReply, replyToAll);
FindRecentlySent(message);
The following code example shows how to use the CreateReply method to respond to
an email message.
C#
// Create the reply response message from the original email message.
responseMessage.BodyPrefix = myReply;
responseMessage.SendAndSaveCopy();
FindRecentlySent(message);
If you need to add an attachment to the response message, replace the call to the
SendAndSaveCopy method with the following code.
C#
reply.Attachments.AddFileAttachment("attachmentname.txt");
reply.Update(ConflictResolutionMode.AutoResolve);
reply.SendAndSaveCopy();
This is also the XML request that the EWS Managed API sends when calling either the
Reply or the CreateReply method.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:CreateItem MessageDisposition="SendAndSaveCopy">
<m:Items>
<t:ReplyAllToItem>
<t:ReferenceItemId Id="AAMkADE4="
ChangeKey="CQAAABYA" />
</t:ReplyAllToItem>
</m:Items>
</m:CreateItem>
</soap:Body>
</soap:Envelope>
If you need to add an attachment to your response message, call the CreateItem
operation as specified above, but change the MessageDisposition to SaveOnly. Then
call the CreateAttachment operation, followed by the SendItem operation.
Forward an email message by using the EWS
Managed API
The EWS Managed API provides two methods that you can use to forward messages:
Forward and CreateForward . The Forward method only takes two parameters: the
message to prepend to the existing body, and an array or collection of recipients,
depending on the overload you choose to use. If you need to add an attachment to the
message you're forwarding, or set additional properties on the new message, use the
CreateForward method, which enables you to set all the properties that are available on
an EmailMessage object.
The following code example shows how to use the Forward method to forward an email
message to one recipient.
This example assumes that service is a valid ExchangeService object and that the user
has been authenticated to an Exchange server. The local variable ItemId is the Id of
the item to forward. The example calls the FindRecentlySent method to verify that the
message was marked as forwarded.
C#
message.Forward(myForward, "[email protected]");
FindRecentlySent(message);
The following code example shows how to use the CreateForward method to forward
an email message to one recipient.
C#
// Create the reply response message from the original email message.
forwardMessage.ToRecipients.Add("[email protected]");
// Send and save a copy of the replied email message in the default Sent
Items folder.
forwardMessage.SendAndSaveCopy();
// Verify that the forwarded message was sent by calling FindRecentlySent.
FindRecentlySent(message);
If you need to add an attachment to the forwarded message, replace the call to the
SendAndSaveCopy method with the following code.
C#
forward.Attachments.AddFileAttachment("attachmentname.txt");
forward.Update(ConflictResolutionMode.AutoResolve);
forward.SendAndSaveCopy();
This is also the XML request that the EWS Managed API sends when calling either the
Forward or the CreateForward method.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:CreateItem MessageDisposition="SendAndSaveCopy">
<m:Items>
<t:ForwardItem>
<t:ToRecipients>
<t:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:Mailbox>
</t:ToRecipients>
<t:ReferenceItemId Id="AAAMkADE="
ChangeKey="CQAAABYA" />
</t:ForwardItem>
</m:Items>
</m:CreateItem>
</soap:Body>
</soap:Envelope>
If you need to add an attachment to your response message, call the CreateItem
operation, but change the MessageDisposition to SaveOnly. Then call the
CreateAttachment operation, followed by the SendItem operation.
C#
// Determine the last verb executed on the message and display output.
object responseType;
if (messageToCheck.TryGetProperty(PidTagLastVerbExecuted, out
responseType))
switch (((Int32)responseType))
break;
break;
break;
if (messageToCheck.TryGetProperty(PidTagLastVerbExecutionTime, out
ReplyTime))
Console.WriteLine(((DateTime)ReplyTime).ToString() + ".");
else
See also
Email and EWS in Exchange
Learn how to move and copy email messages by using the EWS Managed API or EWS in
Exchange.
You can use the EWS Managed API or EWS to move and copy email messages in a
mailbox.
Table 1. EWS Managed API methods and EWS operations for moving and copying
email messages
It's important to note that when you move or copy an email message into a different
folder, a new item is created in the new folder with a unique item ID, and the original
message is deleted. If you're moving or copying an email message between two folders
in the same mailbox, the new item is returned in the response, which gives you access to
the new item ID. However, if you're moving or copying an email message between two
mailboxes or between a mailbox and a public folder, the new item is not returned in the
response. To access the moved message in that scenario, use the EWS Managed API
FindItems method or EWS FindItem operation, create an extended property
definition for the PidTagSearchKey (0x300B0102) property, or create and set a custom
extended property and then search for the custom extended property in the new folder.
Deleting an email message is different than moving an item to the Deleted Items folder.
If you use the EWS Managed API Item.Delete method or the EWS DeleteItem
operation, the item specified in the request is removed from the original folder, and a
copy is placed in the Deleted Items folder with a new item ID. Unlike when you move or
copy any item, the new item is not returned in the Delete method or the DeleteItem
operation response. The steps involved in deleting an email by using the EWS Managed
API or EWS are the same as those for deleting any generic item from the Exchange
store.
Move an email message by using the EWS
Managed API
The following code example shows how to use the EmailMessage.Move method to
move an existing email message from one folder to another.
This example assumes that service is a valid ExchangeService object, and that ItemId
is the Id of the email message to move or copy.
C#
// Move the specified mail to the JunkEmail folder and store the returned
item.
// Check that the item was moved by binding to the moved email message
This is also the XML request that is sent by the EWS Managed API when calling the
Move method. The values of some attributes and elements have been shortened for
readability.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:MoveItem>
<m:ToFolderId>
</m:ToFolderId>
<m:ItemIds>
<t:ItemId Id="AfwDoAAA="
ChangeKey="CQAAABYAAAApjGm7TnMWQ5TzjbhziLL0AAF25sM1" />
</m:ItemIds>
</m:MoveItem>
</soap:Body>
</soap:Envelope>
This example assumes that service is a valid ExchangeService object, and that ItemId
is the Id of the email message to copy. The values of some parameters have been
shortened for readability.
C#
// Copy the orignal message into another folder in the mailbox and store the
returned item.
// Check that the item was copied by binding to the copied email message
This is also the XML request that is sent by the EWS Managed API when calling the
Copy method. The values of some attributes and elements have been shortened for
readability.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:CopyItem>
<m:ToFolderId>
</m:ToFolderId>
<m:ItemIds>
<t:ItemId Id="2TSeSAAA="
ChangeKey="CQAAABYAAAApjGm7TnMWQ5TzjbhziLL0AAF2d+3+" />
</m:ItemIds>
</m:CopyItem>
</soap:Body>
</soap:Envelope>
The server responds to the CopyItem request with a CopyItemResponse message that
includes a ResponseCode value of NoError, which indicates that the email message
was copied successfully. The response also includes the ItemId for the email message in
the new folder, which is important to store because the ItemId is different in the new
folder.
See also
Email and EWS in Exchange
Learn about how to find conversations, apply actions to conversations, and get items in
conversations by using the EWS Managed API or EWS in Exchange.
In the context of Exchange, conversations are a way to group and manage a related set of
email messages. They can also provide a way to view related messages. Exchange defines
conversations based on the Message-ID value of the first email message in a thread. All
replies and related messages reference the original message's Message-ID header in their
References and In-Reply-To headers.
Additionally, inside the SOAP envelope, for each message received in a mailbox, Exchange
sets specific properties and elements.
ConversationTopic ConversationTopic Contains a normalized form of the subject value that was
set on the original message. This is the same as the
Thread-Topic message header. This value is read-only.
Exchange applies the same ConversationTopic value to replies to the first message and then
updates the ConversationIndex value to represent the message's position relative to the
original message. If the subject of the email thread changes, Exchange applies a new
ConversationTopic value and new ConversationIndex values to the new conversation.
Table 2. EWS Managed API methods and EWS operations for working with conversations
In order to… Use this EWS Managed API method or methods Use this EWS operation
Find ExchangeService.FindConversation
FindConversation
conversations
In order to… Use this EWS Managed API method or methods Use this EWS operation
Apply Conversation.EnableAlwaysCategorizeItems
ApplyConversationAction
conversation Conversation.EnableAlwaysDeleteItems
actions Conversation.EnableAlwaysMoveItems
ExchangeService.CopyItemsInConversations
ExchangeService.DeleteItemsInConversations
ExchangeService.DisableAlwaysCategorizeItemsInConversations
ExchangeService.DisableAlwaysDeleteItemsInConversations
ExchangeService.DisableAlwaysMoveItemsInConversations
ExchangeService.EnableAlwaysCategorizeItemsInConversations
ExchangeService.EnableAlwaysDeleteItemsInConversations
ExchangeService.EnableAlwaysMoveItemsInConversations
ExchangeService.MoveItemsInConversations
ExchangeService.SetFlagStatusForItemsInConversations
ExchangeService.SetReadStateForItemsInConversations
ExchangeService.SetRetentionPolicyForItemsInConversations
one or more
conversations
This example assumes that service is a valid ExchangeService object and that the user has
been authenticated to an Exchange server.
C#
// Create the view of conversations returned in the response. This view will
return at most 10 results.
// Search the Inbox for conversations and return a results set with the
specified view.
ApplyConversationActions(service, conversation);
Console.WriteLine("");
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:FindConversation>
<m:IndexedPageItemView MaxEntriesReturned="10"
Offset="0"
BasePoint="Beginning" />
<m:ParentFolderId>
</m:ParentFolderId>
<m:QueryString>subject:news</m:QueryString>
</m:FindConversation>
</soap:Body>
</soap:Envelope>
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="15"
MinorVersion="0"
MajorBuildNumber="883"
MinorBuildNumber="10"
Version="V2_10"
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<FindConversationResponse ResponseClass="Success"
xmlns="https://schemas.microsoft.com/exchange/services/2006/messages">
<ResponseCode>NoError</ResponseCode>
<Conversations>
<Conversation
xmlns="https://schemas.microsoft.com/exchange/services/2006/types">
<UniqueRecipients>
<String>Sadie Daniels</String>
</UniqueRecipients>
<GlobalUniqueRecipients>
<String>Sadie Daniels</String>
</GlobalUniqueRecipients>
<UniqueUnreadSenders>
<String>Ronnie Sturgis</String>
</UniqueUnreadSenders>
<GlobalUniqueUnreadSenders>
<String>Ronnie Sturgis</String>
</GlobalUniqueUnreadSenders>
<UniqueSenders>
<String>Ronnie Sturgis</String>
</UniqueSenders>
<GlobalUniqueSenders>
<String>Ronnie Sturgis</String>
</GlobalUniqueSenders>
<LastDeliveryTime>2014-02-18T20:42:26Z</LastDeliveryTime>
<GlobalLastDeliveryTime>2014-02-18T20:42:26Z</GlobalLastDeliveryTime>
<HasAttachments>false</HasAttachments>
<GlobalHasAttachments>false</GlobalHasAttachments>
<MessageCount>1</MessageCount>
<GlobalMessageCount>1</GlobalMessageCount>
<UnreadCount>1</UnreadCount>
<GlobalUnreadCount>1</GlobalUnreadCount>
<Size>9330</Size>
<GlobalSize>9330</GlobalSize>
<ItemClasses>
<ItemClass>IPM.Note</ItemClass>
</ItemClasses>
<GlobalItemClasses>
<ItemClass>IPM.Note</ItemClass>
</GlobalItemClasses>
<Importance>Normal</Importance>
<GlobalImportance>Normal</GlobalImportance>
<ItemIds>
<ItemId Id="sVCyAAA="
ChangeKey="CQAAAA==" />
</ItemIds>
<GlobalItemIds>
<ItemId Id="sVCyAAA="
ChangeKey="CQAAAA==" />
</GlobalItemIds>
<LastModifiedTime>2014-02-18T20:42:26Z</LastModifiedTime>
<InstanceKey>AQAAAAAAAQABAAAACbFYggAAAAA=</InstanceKey>
<HasIrm>false</HasIrm>
<GlobalHasIrm>false</GlobalHasIrm>
</Conversation>
</Conversations>
<TotalConversationsInView>1</TotalConversationsInView>
<IndexedOffset>1</IndexedOffset>
</FindConversationResponse>
</s:Body>
</s:Envelope>
This example assumes that service is a valid ExchangeService object and that the user has
been authenticated to an Exchange server.
For a complete list of methods that apply conversation actions, see Table 2.
C#
categories.Add("Customer");
categories.Add("System Integrator");
// synchronously after enabling this rule and after all item categorization
has been applied.
conversation.EnableAlwaysCategorizeItems(categories, true);
// Apply an always move rule to all items in the conversation and move the
items
// to the Drafts folder. Process the request asynchronously and return the
response.
conversation.EnableAlwaysMoveItems(WellKnownFolderName.Drafts, false);
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:ApplyConversationAction>
<m:ConversationActions>
<t:ConversationAction>
<t:Action>AlwaysMove</t:Action>
<t:ProcessRightAway>false</t:ProcessRightAway>
<t:DestinationFolderId>
</t:DestinationFolderId>
</t:ConversationAction>
</m:ConversationActions>
</m:ApplyConversationAction>
</soap:Body>
</soap:Envelope>
In this example, all conversation items in the default Deleted Items and Drafts folders are
ignored.
This example assumes that service is a valid ExchangeService object and that the user has
been authenticated to an Exchange server.
C#
try
FindItemsResults<Item> results =
service.FindItems(WellKnownFolderName.Inbox,
new ItemView(1));
ItemSchema.Subject,
ItemSchema.DateTimeReceived);
{ WellKnownFolderName.DeletedItems, WellKnownFolderName.Drafts };
properties,
null,
foldersToIgnore,
ConversationSortOrder.TreeOrderDescending);
items.Add(item);
Console.WriteLine(srException);
We recommend that you cache the SyncState property for subsequent requests to get items
in the conversation.
In this example, all conversation items in the default Deleted Items and Drafts folders are
ignored.
This example assumes that service is a valid ExchangeService object and that the user has
been authenticated to an Exchange server.
C#
try
// Find the first two items in the Inbox. This item will be used to call
the GetConversationItems operation.
FindItemsResults<Item> results =
service.FindItems(WellKnownFolderName.Inbox, new ItemView(2));
// Get the conversation identifier of the first two items in the Inbox.
convR1.ConversationId = convId1;
convR2.ConversationId = convId2;
conversations.Add(convR1);
conversations.Add(convR2);
// Specify the properties that will be returned for the items in the
conversation.
ItemSchema.Subject,
ItemSchema.DateTimeReceived);
{ WellKnownFolderName.DeletedItems, WellKnownFolderName.Drafts };
ServiceResponseCollection<GetConversationItemsResponse> responses =
service.GetConversationItems(conversations, properties,
foldersToIgnore,
ConversationSortOrder.TreeOrderDescending);
Console.WriteLine(srException);
As a best practice, we recommend that you return only the properties that the client
application requires, rather than using the FirstClassProperties option for the
BasePropertySet class. We recommend that you cache the SyncState property for subsequent
requests to get items in the conversation.
In this example, all conversation items in the default Deleted Items and Drafts folders are
ignored.
To get items from more than one conversation, include additional Conversation elements.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m=https://schemas.microsoft.com/exchange/services/2006/messages
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:GetConversationItems>
<m:ItemShape>
<t:BaseShape>IdOnly</t:BaseShape>
<t:AdditionalProperties>
</t:AdditionalProperties>
</m:ItemShape>
<m:FoldersToIgnore>
</m:FoldersToIgnore>
<m:SortOrder>TreeOrderDescending</m:SortOrder>
<m:Conversations>
<t:Conversation>
</t:Conversation>
</m:Conversations>
</m:GetConversationItems>
</soap:Body>
</soap:Envelope>
The ItemId, SyncState, and ConversationId elements have been shortened for readability.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="15"
MinorVersion="0"
MajorBuildNumber="873"
MinorBuildNumber="9"
Version="V2_9"
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:GetConversationItemsResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:GetConversationItemsResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Conversation>
<t:SyncState>AAAAYAm1</t:SyncState>
<t:ConversationNodes>
<t:ConversationNode>
<t:InternetMessageId>&lt;994051d7c1a346efbfce8dec2cbad509
@SN2SR01MB006.com&gt;</t:InternetMessageId>
<t:ParentInternetMessageId>&lt;faa2b1df30074380abe3527b0cd18ca5
@SN2SR01MB001.com&gt;</t:ParentInternetMessageId>
<t:Items>
<t:Message>
<t:ItemId Id="AYB1NAAA="
ChangeKey="CQAAABYAAAD/oydcA+SPQZGbKWNyvNIZAAAAYCHq" />
<t:DateTimeReceived>2014-01-02T13:15:00Z</t:DateTimeReceived>
</t:Message>
</t:Items>
</t:ConversationNode>
<t:ConversationNode>
<t:InternetMessageId>&lt;faa2b1df30074380abe3527b0cd18ca5
@SN2SR01MB001.com&gt;</t:InternetMessageId>
<t:ParentInternetMessageId>&lt;6a8e7658524b41cda7cdc3f23c1074a5
@SN2SR01MB001.com&gt;</t:ParentInternetMessageId>
<t:Items>
<t:Message>
<t:ItemId Id="lQAAAA=="
ChangeKey="CQAAABYAAAD/oydcA+SPQZGbKWNyvNIZAAAAYAu8" />
<t:DateTimeReceived>2014-01-02T10:02:08Z</t:DateTimeReceived>
</t:Message>
</t:Items>
</t:ConversationNode>
<t:ConversationNode>
<t:InternetMessageId>&lt;bcdb185495834370a874a1e7ebedbb96
@SN2SR01MB005.com&gt;</t:InternetMessageId>
<t:ParentInternetMessageId>&lt;e52a4de6b98d484887e141da094a2ce6
@SN2SR01MB006.com&gt;</t:ParentInternetMessageId>
<t:Items>
<t:Message>
<t:ItemId Id="igAAAA=="
ChangeKey="CQAAABYAAAD/oydcA+SPQZGbKWNyvNIZAAAAYAuj" />
<t:DateTimeReceived>2014-01-02T16:20:10Z</t:DateTimeReceived>
</t:Message>
</t:Items>
</t:ConversationNode>
<t:ConversationNode>
<t:InternetMessageId>&lt;e52a4de6b98d484887e141da094a2ce6
@SN2SR01MB006.com&gt;</t:InternetMessageId>
<t:ParentInternetMessageId>&lt;f0db3ead01db4fe087d98022149aa16f
@SN2SR01MB001.com&gt;</t:ParentInternetMessageId>
<t:Items>
<t:Message>
<t:ItemId Id="iwAAAA=="
ChangeKey="CQAAABYAAAD/oydcA+SPQZGbKWNyvNIZAAAAYAul" />
<t:DateTimeReceived>2014-01-02T15:30:10Z</t:DateTimeReceived>
</t:Message>
</t:Items>
</t:ConversationNode>
<t:ConversationNode>
<t:InternetMessageId>&lt;f0db3ead01db4fe087d98022149aa16f
@SN2SR01MB001.com&gt;</t:InternetMessageId>
<t:ParentInternetMessageId>&lt;88b1884ecaaa4f68b081c009d827e8c6
@SN2SR01MB003.com&gt;</t:ParentInternetMessageId>
<t:Items>
<t:Message>
<t:ItemId Id="jQAAAA=="
ChangeKey="CQAAABYAAAD/oydcA+SPQZGbKWNyvNIZAAAAYAuq" />
<t:DateTimeReceived>2014-01-02T14:20:10Z</t:DateTimeReceived>
</t:Message>
</t:Items>
</t:ConversationNode>
<t:ConversationNode>
<t:InternetMessageId>&lt;88b1884ecaaa4f68b081c009d827e8c6
@SN2SR01MB003.com&gt;</t:InternetMessageId>
<t:ParentInternetMessageId>&lt;faa2b1df30074380abe3527b0cd18ca5
@SN2SR01MB001.com&gt;</t:ParentInternetMessageId>
<t:Items>
<t:Message>
<t:ItemId Id="kAAAAA=="
ChangeKey="CQAAABYAAAD/oydcA+SPQZGbKWNyvNIZAAAAYAux" />
<t:DateTimeReceived>2014-01-02T12:52:09Z</t:DateTimeReceived>
</t:Message>
</t:Items>
</t:ConversationNode>
</t:ConversationNodes>
</m:Conversation>
</m:GetConversationItemsResponseMessage>
</m:ResponseMessages>
</m:GetConversationItemsResponse>
</s:Body>
</s:Envelope>
Version differences
When you are using Exchange Server 2010 Service Pack 1 (SP1), the FindConversation
method has fewer options available, and the FindConversation operation has fewer
elements in the request.
Table 3. Exchange 2010 SP1 version support for FindConversation
SortOrder
ParentFolderId
The FindConversation EWS Managed API method and the FindConversation EWS method are
not available in the initial release version of Exchange 2010 or in Exchange 2007.
See also
Email and EWS in Exchange
Use search filters with EWS in Exchange
Exchange 2013: Find conversations in mailboxes programmatically
Exchange 2013: Apply actions to manage conversations in a mailbox
Extract an entity from an email message
by using EWS in Exchange
Article • 01/15/2020 • 7 minutes to read
Learn how to extract information from the body of an email message by using the EWS
Managed API or EWS in Exchange.
You can use the EWS Managed API or EWS to access the addresses, contacts, email
addresses, meeting suggestions, phone numbers, tasks, and URLs that an Exchange
server extracts from email messages. You can then use this information for new
applications or to suggest follow up actions in existing applications. For example, if a
contact entity, meeting suggestion, or task suggestion is identified in an email, your
application can suggest that a new item with prepopulated information be created. By
using extracted entities, you can capitalize on the intent behind the data — and help
users seamlessly integrate their email message content into actionable results.
Entity extraction for addresses, contacts, email addresses, meeting suggestions, phone
numbers, tasks, and URLs is already built in to every item in the Exchange store. If you're
using the EWS Managed API, the Item.EntityExtractionResult property retrieves the
entities for you in an Item.Bind method call. If you're using EWS, the
EntityExtractionResult element gets all the extracted entities for you in a GetItem
operation call. After you retrieve the results of the extracted entities, you can walk
through each entity collection to gather pertinent information. For example, if a meeting
suggestion was extracted, you can retrieve the suggested meeting subject, attendee list,
start time, and end time.
Table 1. EWS Managed API properties and EWS elements that contain extracted
entities
Addresses EntityExtractionResult.Addresses
Addresses
Contacts EntityExtractionResult.Contacts
Contacts
URLs EntityExtractionResult.Urls
Urls
Hi Sadie
Are you free this Friday at 7 to join us for a dinner party at our house?
Please RSVP to either myself or Mara ([email protected]) before Friday morning. Best
for you organics (http://www.bestforyouorganics.com) will be catering so we can
Also, can you forward this to Magdalena? I don't have her contact information.
Ronnie
This example assumes that service is a valid ExchangeService object, and that ItemId
is the Id of the email message to move or copy.
C#
public static void ExtractEntities(ExchangeService service, ItemId ItemId)
Console.WriteLine(" ");
if (item.EntityExtractionResult != null)
if (item.EntityExtractionResult.Addresses != null)
Console.WriteLine("--------------------Addresses----------------
-----------");
Console.WriteLine(" ");
if (item.EntityExtractionResult.Contacts != null)
Console.WriteLine("--------------------Contacts-----------------
-----------");
Console.WriteLine("Addresses: {0}",
contact.Addresses);
Console.WriteLine(" ");
if (item.EntityExtractionResult.EmailAddresses != null)
Console.WriteLine("--------------------Email addresses----------
-----------");
Console.WriteLine(" ");
if (item.EntityExtractionResult.MeetingSuggestions != null)
Console.WriteLine("--------------------Meeting suggestions------
-----------");
Console.WriteLine("Location: {0}",
meetingSuggestion.Location);
Console.WriteLine(" ");
if (item.EntityExtractionResult.PhoneNumbers != null)
Console.WriteLine("--------------------Phone numbers------------
-----------");
Console.WriteLine("Type: {0}",
phone.Type);
Console.WriteLine(" ");
if (item.EntityExtractionResult.TaskSuggestions != null)
Console.WriteLine("--------------------Task suggestions---------
-----------");
Console.WriteLine(" ");
if (item.EntityExtractionResult.Urls != null)
Console.WriteLine("--------------------URLs---------------------
-----------");
Console.WriteLine(" ");
text
--------------------Addresses---------------------------
--------------------Contacts----------------------------
Addresses:
Business name:
Phone numbers:
URLs:
--------------------Email addresses---------------------
--------------------Meeting suggestions-----------------
Meeting string: Are you free this Friday at 7 to join us for a dinner
party at our house?
Location:
--------------------Phone numbers-----------------------
Type: Unspecified
--------------------Task suggestions--------------------
--------------------URLs--------------------------------
URL: http://www.bestforyouorganics.com
Notice that all addresses, contacts, email addresses, phone numbers, tasks, and URLs
were extracted as expected. The meeting suggestion, however, is a bit more complex.
Notice the start time and end time of the meeting suggestion are not what you might
expect. The start time in the email is "this Friday at 7", but the extracted value for the
start time is 10/1/0104 2:00:00 PM. This is because the start time and end time extracted
by the server are encoded dates. For more information about how to interpret dateTime
values in meeting suggestions, see [MS-OXCEXT]: Client Extension Message Object
Protocol .
This is also the XML request that is sent by the EWS Managed API when you use the
Bind method to Extract all entities from an email by using the EWS Managed API.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:GetItem>
<m:ItemShape>
<t:BaseShape>IdOnly</t:BaseShape>
<t:AdditionalProperties>
</t:AdditionalProperties>
</m:ItemShape>
<m:ItemIds>
</m:ItemIds>
</m:GetItem>
</soap:Body>
</soap:Envelope>
The server responds to the GetItem request with a GetItemResponse message that
includes a ResponseCode value of NoError, which indicates that the email message
was retrieved successfully. The response also includes the EntityExtractionResult for
each extracted entity.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="15"
MinorVersion="0"
MajorBuildNumber="883"
MinorBuildNumber="10"
Version="V2_10"
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:GetItemResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:GetItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:Message>
<t:ItemId Id="sVC5AAA="
ChangeKey="CQAAABYAAAD32nSTjepyT63rYH17n9THAAAOOqJN"
/>
<t:EntityExtractionResult>
<t:Addresses>
<t:AddressEntity>
<t:Position>LatestReply</t:Position>
</t:AddressEntity>
</t:Addresses>
<t:MeetingSuggestions>
<t:MeetingSuggestion>
<t:Position>LatestReply</t:Position>
<t:Attendees>
<t:EmailUser>
<t:Name>Ronnie Sturgis</t:Name>
<t:UserId>[email protected]</t:UserId>
</t:EmailUser>
<t:EmailUser>
<t:Name>Sadie Daniels</t:Name>
<t:UserId>[email protected]</t:UserId>
</t:EmailUser>
</t:Attendees>
<t:Subject>dinner party</t:Subject>
<t:StartTime>0104-10-01T19:00:00Z</t:StartTime>
<t:EndTime>0104-10-01T19:30:00Z</t:EndTime>
</t:MeetingSuggestion>
</t:MeetingSuggestions>
<t:TaskSuggestions>
<t:TaskSuggestion>
<t:Position>LatestReply</t:Position>
<t:Assignees>
<t:EmailUser>
<t:Name>Sadie Daniels</t:Name>
<t:UserId>[email protected]</t:UserId>
</t:EmailUser>
</t:Assignees>
</t:TaskSuggestion>
</t:TaskSuggestions>
<t:EmailAddresses>
<t:EmailAddressEntity>
<t:Position>LatestReply</t:Position>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:EmailAddressEntity>
</t:EmailAddresses>
<t:Contacts>
<t:Contact>
<t:Position>LatestReply</t:Position>
<t:PersonName>Mara</t:PersonName>
<t:EmailAddresses>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:EmailAddresses>
<t:ContactString>Mara
([email protected]</t:ContactString>
</t:Contact>
</t:Contacts>
<t:Urls>
<t:UrlEntity>
<t:Position>LatestReply</t:Position>
<t:Url>http://www.bestforyouorganics.com</t:Url>
</t:UrlEntity>
</t:Urls>
<t:PhoneNumbers>
<t:Phone>
<t:Position>LatestReply</t:Position>
<t:OriginalPhoneString>612-555-
0158</t:OriginalPhoneString>
<t:PhoneString>6125550158</t:PhoneString>
<t:Type>Unspecified</t:Type>
</t:Phone>
</t:PhoneNumbers>
</t:EntityExtractionResult>
</t:Message>
</m:Items>
</m:GetItemResponseMessage>
</m:ResponseMessages>
</m:GetItemResponse>
</s:Body>
</s:Envelope>
Notice that all addresses, contacts, email addresses, phone numbers, tasks, and URLs
were extracted as expected. The meeting suggestion, however, is a bit more complex.
Notice the start time and end time of the meeting suggestion are not what you might
expect. The start time in the email was "this Friday at 7", but the extracted value for the
start time is 10/1/0104 2:00:00 PM. This is because the start time and end time extracted
by the server are encoded dates. For more information about interpreting dateTime
values in meeting suggestions, see [MS-OXCEXT]: Client Extension Message Object
Protocol .
See also
Email and EWS in Exchange
Item.EntityExtractionResult
EntityExtractionResult
Process email messages in batches by
using EWS in Exchange
Article • 01/15/2020 • 12 minutes to read
Learn how to create, get, update, and delete batches of email messages in a single call
by using the EWS Managed API or EWS in Exchange.
You can use the EWS Managed API or EWS to work with batches of email messages to
reduce the number of calls a client makes to an Exchange server. When you use the EWS
Managed API to create, get, update, delete, and send messages in batches, you use
ExchangeService object methods, whereas when you work with single email messages,
you use EmailMessage object methods. If you are using EWS, you use the same
operations to work with both single and batches of email messages.
Table 1. EWS Managed API methods and EWS operations for working with batches of
email messages
In order to… Use this EWS Managed API Use this EWS
method operation
batches
In this article, you'll learn how to complete basic tasks for batches of email messages by
using the EWS Managed API or EWS.
This example assumes that service is a valid ExchangeService object and that the user
has been authenticated to an Exchange server.
C#
message1.ToRecipients.Add("[email protected]");
message2.ToRecipients.Add("[email protected]");
message3.ToRecipients.Add("[email protected]");
ServiceResponseCollection<ServiceResponse> response =
service.CreateItems(messageItems, WellKnownFolderName.Drafts,
MessageDisposition.SaveOnly, null);
try
itemIds.Add(message.Id);
// Print out the exception and the last eight characters of the
item ID.
if (response.OverallResult == ServiceResult.Success)
Console.WriteLine("\r\n");
// If the method did not return success, print the result message for
each email.
else
int counter = 1;
// Print out the result and the last eight characters of the
item ID.
Console.WriteLine("\r\n");
counter++;
return itemIds;
Note that the example only saves the messages in the Drafts folder; it does not send the
messages. For more about how to send the messages, see Send email messages in
batches by using the EWS Managed API.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:CreateItem MessageDisposition="SaveOnly">
<m:SavedItemFolderId>
</m:SavedItemFolderId>
<m:Items>
<t:Message>
<t:Subject>Project priorities</t:Subject>
<t:ToRecipients>
<t:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:Mailbox>
</t:ToRecipients>
</t:Message>
<t:Message>
<t:ToRecipients>
<t:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:Mailbox>
</t:ToRecipients>
</t:Message>
<t:Message>
<t:Subject>Code Blast</t:Subject>
<t:ToRecipients>
<t:Mailbox>
<t:EmailAddress>[email protected]</t:EmailAddress>
</t:Mailbox>
</t:ToRecipients>
</t:Message>
</m:Items>
</m:CreateItem>
</soap:Body>
</soap:Envelope>
Note that the example only saves the messages in the Drafts folder; it does not send the
messages. For more about how to send the messages, see Send email messages in
batches by using EWS.
Send email messages in batches by using the
EWS Managed API
You use the same code to send email messages in batches that you use to create email
messages in batches, except that a few of the CreateItems method parameters
change. So, to send email messages by using the EWS Managed API, use the code you
use to create email messages in batches, and replace the call to the CreateItems
method with the call in the following example. In this example, the messages are created
in the Sent Items folder, and the message disposition is changed to
MessageDisposition.SendAndSaveCopy , so that the message is sent, and not just
saved locally.
C#
ServiceResponseCollection<ServiceResponse> response =
service.CreateItems(messageItems, WellKnownFolderName.SentItems,
MessageDisposition.SendAndSaveCopy, null);
XML
<m:CreateItem MessageDisposition="SendAndSaveCopy">
<m:SavedItemFolderId>
<t:DistinguishedFolderId Id="sentitems" />
</m:SavedItemFolderId>
This example assumes that service is a valid ExchangeService object and that the user
has been authenticated to an Exchange server.
C#
// Create a property set that limits the properties returned by the Bind
method to only those that are required.
ServiceResponseCollection<GetItemResponse> response =
service.BindToItems(itemIds, propSet);
try
messageItems.Add(message);
if (response.OverallResult == ServiceResult.Success)
Console.WriteLine("\r\n");
return messageItems;
The ItemId and ChangeKey attributes have been shortened for readability.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:GetItem>
<m:ItemShape>
<t:BaseShape>IdOnly</t:BaseShape>
<t:AdditionalProperties>
</t:AdditionalProperties>
</m:ItemShape>
<m:ItemIds>
<t:ItemId Id="m4NxAAA="
ChangeKey="CQAAABYAAAApjGm7TnMWQ5TzjbhziLL0AAF/yKB0" />
<t:ItemId Id="m4NyAAA="
ChangeKey="CQAAABYAAAApjGm7TnMWQ5TzjbhziLL0AAF/yKB1" />
<t:ItemId Id="m4NzAAA="
ChangeKey="CQAAABYAAAApjGm7TnMWQ5TzjbhziLL0AAF/yKB2" />
</m:ItemIds>
</m:GetItem>
</soap:Body>
</soap:Envelope>
The server responds to the GetItem request with a GetItemResponse message that
includes the first class properties for each of the requested messages.
Update email messages in batches by using the
EWS Managed API
You can get email messages in batches by using the EWS Managed API UpdateItems
method, as shown in the following example.
For a list of writable email message properties, see Email properties and elements in
EWS in Exchange.
For details about how to send a draft message after it's been updated, see Sending
email messages by using the EWS Managed API.
This example assumes that service is a valid ExchangeService object and that the user
has been authenticated to an Exchange server.
C#
// Print out confirmation with the last eight characters of the item
ID and the email subject.
ServiceResponseCollection<UpdateItemResponse> response =
service.UpdateItems(messageItems, WellKnownFolderName.Drafts,
ConflictResolutionMode.AutoResolve, MessageDisposition.SaveOnly, null);
if (response.OverallResult == ServiceResult.Success)
// If the method did not return success, print the result message for
each email.
else
int counter = 1;
counter++;
return messageItems;
For a list of writable email message elements, see Email properties and elements in EWS
in Exchange.
For details about how to send a draft message after it's been updated, see Send a draft
email message by using EWS.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:UpdateItem MessageDisposition="SaveOnly"
ConflictResolution="AutoResolve">
<m:SavedItemFolderId>
</m:SavedItemFolderId>
<m:ItemChanges>
<t:ItemChange>
<t:ItemId Id="m4OVAAA="
ChangeKey="CQAAABYAAAApjGm7TnMWQ5TzjbhziLL0AAF/yKCy" />
<t:Updates>
<t:SetItemField>
<t:Message>
</t:Message>
</t:SetItemField>
</t:Updates>
</t:ItemChange>
<t:ItemChange>
<t:ItemId Id="m4OWAAA="
ChangeKey="CQAAABYAAAApjGm7TnMWQ5TzjbhziLL0AAF/yKCz" />
<t:Updates>
<t:SetItemField>
<t:Message>
</t:Message>
</t:SetItemField>
</t:Updates>
</t:ItemChange>
<t:ItemChange>
<t:ItemId Id="m4OXAAA="
ChangeKey="CQAAABYAAAApjGm7TnMWQ5TzjbhziLL0AAF/yKC0" />
<t:Updates>
<t:SetItemField>
<t:Message>
</t:Message>
</t:SetItemField>
</t:Updates>
</t:ItemChange>
</m:ItemChanges>
</m:UpdateItem>
</soap:Body>
</soap:Envelope>
This example assumes that service is a valid ExchangeService object and that the user
has been authenticated to an Exchange server.
C#
ServiceResponseCollection<ServiceResponse> response =
service.DeleteItems(itemIds, DeleteMode.SoftDelete, null,
AffectedTaskOccurrence.AllOccurrences);
// DeleteItems returns success even if it does not find all the item
IDs.
if (response.OverallResult == ServiceResult.Success)
else
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:DeleteItem DeleteType="SoftDelete"
AffectedTaskOccurrences="AllOccurrences">
<m:ItemIds>
<t:ItemId Id="m4OkAAA="
ChangeKey="CQAAABYAAAApjGm7TnMWQ5TzjbhziLL0AAF/yKDE" />
<t:ItemId Id="m4OlAAA="
ChangeKey="CQAAABYAAAApjGm7TnMWQ5TzjbhziLL0AAF/yKDF" />
<t:ItemId Id="m4OmAAA="
ChangeKey="CQAAABYAAAApjGm7TnMWQ5TzjbhziLL0AAF/yKDG" />
</m:ItemIds>
</m:DeleteItem>
</soap:Body>
</soap:Envelope>
To verify the success of a batch process by using the EWS Managed API, you can check
that the OverallResult property of the ServiceResponseCollection is equal to
ServiceResult.Success . If so, all the emails were processed successfully. If the
OverallResult is not equal to ServiceResult.Success, one or more of the emails were not
processed successfully. Each of the objects returned in the ServiceResponseCollection
contains the following properties:
ErrorCode
ErrorDetails
ErrorMessage
ErrorProperties
Result
These properties contain information about why the email messages could not be
processed as requested. The examples in this article print out the Result, ErrorCode, and
ErrorMessage for each failed message. You can use these results to investigate the issue.
For EWS, to verify the success of a batched process, check the ResponseClass attribute
for each item being processed. The following is the basic structure of the
ResponseMessageType, the base type from which all response messages are derived.
XML
<MessageText/>
<ResponseCode/>
<DescriptiveLinkKey/>
<MessageXml/>
</ResponseMessage>
The ResponseClass attribute is set to Success if the email was processed successfully, or
Error if the email was not processed successfully. For email messages, you will not
encounter a Warning during batch processing. If the ResponseClass is Success, the
ResponseCode element that follows is also always set to NoError. If the
ResponseClass is Error, you need to check the values of the MessageText ,
ResponseCode, and MessageXml elements to determine what caused the problem.
DescriptiveLinkKey is currently unused.
See also
Email and EWS in Exchange
Learn about folders and mailbox items and how your EWS Managed API or EWS client represents
them.
Folders are the organizing element of an Exchange mailbox. Folders can contain mailbox items,
such as email messages, contacts, appointments, meetings, and tasks, or they can contain other
folders. Exchange includes different types of folders, but the folder types are similar to each other.
The main difference between them is the type of item they contain.
Items, however, have unique types. Each item type has a different set of properties or schema to
define it. In this article, we'll discuss the types of folders and items that are available and the
differences between them.
Folders
Folders all derive from the same base class or base type, the Folder class in the EWS Managed
API, or the Folder type in EWS. The following figure shows the EWS Managed API classes and
EWS types.
Figure 1. EWS Managed API folder classes and EWS folder types
The primary difference between each of the folder classes and folder types is that you can only
create a certain type of item in each type of folder. One other difference is in how the client
displays information in a folder. For example, Exchange allows you to create appointments in the
Calendar folder. You can move other types of items into the Calendar folder after you create
them, but Outlook won't display them. Outlook only displays calendar items such as
appointments and meetings in the Calendar folder, even if another type of item exists in the
folder.
Table 1. EWS Managed API folder classes and EWS folder types
EWS Managed EWS type FolderClass Contains Notes
API class value
Folder
Folder
IPF.Note Email This is the generic folder class or type
messages or for the following EWS Managed API
folders. WellKnownFolderName folders and
EWS DistinguishedFolderId folders:
SearchFolder
SearchFolder
IPF.Note Contents are The items that meet the search criteria
determined are not actually contained in the search
by a folder; instead, they are located
restriction or elsewhere in the mailbox.
filter. Search To ensure that Search folders are
folders do not available in Outlook, create them in the
have Finder folder.
subfolders.
EWS Managed EWS type FolderClass Contains Notes
API class value
TasksFolder
TasksFolder
IPF.Task Contains work None.
items to
complete.
Folder structure
Folders provide a mailbox structure. This includes the IPM Subtree, known as the Top of
Information Store in EWS, where most users interact with their mailbox, as well as system folders
that most users never see, which are in the Non-IPM Subtree or Root in EWS. The following figure
shows the folder structure for a user and indicates which folders are for the user's items and
which are system folders.
Well-known folders
Of the folders in a mailbox, some are special folders. These equate to well-known folders in the
EWS Managed API, or distinguished folders in EWS. Some of these folders have restrictions on the
folder name, where they are located in the folder structure, and whether they can be deleted.
Other "generic" (non-special) folders do not have the same restrictions. It is important for you to
be familiar with the following well-known or distinguished folders because they are the root
system, user, and search folders, and are applicable to most implementations.
For a complete list of the EWS Managed API WellKnownFolderName property values, see the
WellKnownFolderName enumeration. For a complete list of the EWS DistinguishedFolderId
values, see DistinguishedFolderId .
Folder properties
In the EWS Managed API, the folder properties are all derived from the base Folder class. And
in EWS, all folders use the folder elements that are available on the Folder type. Most of the
folder-related properties and elements are straightforward (parent folder ID, display name, and so
on), but a few require a little more explanation.
The following caveats apply to the EWS Managed API Folder.FolderClass property or the EWS
FolderClass element:
If set, the value of the property or element must agree with the derived class or type of the
folder. For example, the FolderClass property or element can't indicate that the folder is a
Contacts folder while the class or type of the folder indicates the folder is a Calendar folder.
You can either create folders of a specific type without setting the FolderClass property or
element, or you can create a folder with the generic folder type and specify the FolderClass
property or element. Both options create the same result.
After you set the FolderClass value by creating a specific type of folder or by setting the
FolderClass property or element itself, you cannot change it. For example, you cannot
change an IPF.Note folder to an IPF.Contact folder. You can, however, change it to an
IPF.Note.Contoso folder.
Any FolderClass value that does not use one of the predefined prefixes is treated as an
IPF.Note folder. For example, a FolderClass value of IAmAFolderClass is treated as an
IPF.Note folder.
The folder class value is extensible. This means that the default FolderClass values listed in Table 1
are treated as prefixes and you can add custom values. For example, you can create a folder with
a FolderClass value of IPF.Contact.Contoso, and it is treated as a Contacts folder.
You can determine what permissions the client has on the folders, such as delete, read, and
modify, by using the EWS Managed API Folder.EffectiveRights property or the EWS
EffectiveRights element.
Public folders
Public folders are designed for shared access and provide an easy and effective way to collect,
organize, and share information with other people in your workgroup or organization. You can
also use public folders to archive distribution group content. For in-depth information about
public folders, see Public folder access with EWS in Exchange.
Hidden folders
All the folders that Exchange creates at the root of the mailbox are hidden, and you can use the
EWS Managed API or EWS to hide additional folders under the Top of Information Store. For more
information about hidden folders, see Work with hidden folders by using EWS in Exchange.
Search folders
Search folders are just like regular folders, except that they have a property or element that
defines the search filter. You can create search folders in any folder in an Exchange mailbox, and
you create them in the same way that you create any other folder. However, for a search folder to
appear in Outlook, Outlook Web App, or Outlook Live, SearchFolder objects that you create by
using the EWS Managed API must be located in the WellKnownFolderName.SearchFolders
folder, and SearchFolder types that you create by using EWS must be located in the
DistinguishedFolderId.SearchFolders folder. If the search folder is created in a different location,
it is still available and you can view it in custom client applications.
Items
EWS in Exchange uses Items to represent individual email messages, appointments, meetings,
contacts, distribution lists, tasks, posts, and other items, in a mailbox. Items are either strongly
typed, which means that they have a specific associated class or schema, or not strongly typed,
also known as generic items. Generic items are Item objects in the EWS Managed API and
Item types in EWS. Common items like email messages, contacts, distribution lists, posts, and
tasks are strongly typed, and you can set specific schematized properties or elements on them.
Appointment
CalendarItem
Contact
Contact
ContactGroup
DistributionList
EmailMessage
Message
PostItem
PostItem
Task
Task
EWS Managed API strongly typed items derive from the base Item class. However, you usually
work with one of the derived types listed in Table 3, and not with the Item class directly. When
you work with the ItemCollection class, however, you might work directly with instances of the
Item class. In that case, you should implement logic that determines the type of item in the store
that the instance of the Item class represents. To work with that item, you should bind to the item
by using an instance of the class that represents the item.
Items in folders
Some folders have restrictions about the types of items that they can contain. These are
restrictions that the Exchange mailbox database applies to folders, not client view limitations.
CalendarFolder CalendarFolder You can only create new EWS Managed API Appointment objects
and EWS CalendarItem types in the Calendar folder. You can
move other item types into the Calendar folder, but the client might
not display them.
ContactsFolder ContactsFolder You can only create new EWS Managed API Contact and
ContactGroup objects, or EWS Contact types or
DistributionList types in the Contacts folder. You can move other
item types into the Contacts folder, but the client might not display
them
SearchFolder
SearchFolder
No restrictions. Items are not actually located in the Search folder;
they are located elsewhere in the mailbox.
TasksFolder
TasksFolder
You can only create new EWS Managed API Task objects or EWS
Task types in the Tasks folder. You can move other item types into
the Tasks folder, but the client might not display them
In this section
Work with folders by using EWS in Exchange
See also
Develop web service clients for Exchange
Start using web services in Exchange
EWS client design overview for Exchange
Work with folders by using EWS in
Exchange
Article • 02/11/2022 • 12 minutes to read
Learn how to create, get, update, and delete folders by using the EWS Managed API or
EWS in Exchange.
EWS in Exchange uses folders to structure and organize mailboxes. You can create new,
get, update, and delete folders by using the EWS Managed API or EWS. Each of the
methods or operations listed in the following table is performed on a Folder object, a
Folder type, or one of the derived folder classes or types.
Table 1. Methods and operations for creating, getting, updating and deleting folders
These examples assume that service is a valid ExchangeService object and that the
user has been authenticated to an Exchange server.
C#
folder.FolderClass = "IPF.Note";
folder.Save(WellKnownFolderName.Inbox);
C#
folder.Save(WellKnownFolderName.Inbox);
If you try to create an instance of a specific class and also set the FolderClass property,
the ErrorNoFolderClassOverride error is thrown.
Note that you cannot batch the creation of multiple folders in a single method call by
using the EWS Managed API.
This is also the XML request that the EWS Managed API sends when you create a new
folder and call the Folder.Save method.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:CreateFolder>
<m:ParentFolderId>
</m:ParentFolderId>
<m:Folders>
<t:Folder>
<t:FolderClass>IPF.Note</t:FolderClass>
<t:DisplayName>Custom Folder</t:DisplayName>
</t:Folder>
</m:Folders>
</m:CreateFolder>
</soap:Body>
</soap:Envelope>
7 Note
This example assumes that service is a valid ExchangeService object and that the user
has been authenticated to an Exchange server.
C#
// As a best practice, limit the properties returned to only those that are
required.
// Bind to an existing folder and get only the properties specified in the
PropertySet.
If you need to return additional properties, add properties from the FolderSchema
class to the PropertySet, or use one of the overloaded Bind methods that returns all
first class properties.
Note that you cannot get multiple folders at one time by using the EWS Managed API.
You have to call the Bind method on each folder separately.
To get a single folder, send a GetFolder operation request message to the server. In
the following example, the BaseShape is set to IdOnly, so only the FolderId of the
specified folder is returned. The FolderIds element indicates that the folder to retrieve
is the Inbox folder.
This is also the XML request that the EWS Managed API sends when you bind to a folder
by using the Folder.Bind method.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:GetFolder>
<m:FolderShape>
<t:BaseShape>IdOnly</t:BaseShape>
</m:FolderShape>
<m:FolderIds>
</m:FolderIds>
</m:GetFolder>
</soap:Body>
</soap:Envelope>
The following XML example shows the GetFolderResponse message that is sent from
the server to the client in response to the GetFolder operation request. It only contains
the FolderId value of the Inbox folder. The values of some attributes and elements
have been shortened for readability.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="15"
MinorVersion="0"
MajorBuildNumber="800"
MinorBuildNumber="16"
Version="V2_6"
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance"/>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:GetFolderResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:GetFolderResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Folders>
<t:Folder>
<t:FolderId Id="AAAENAAA="
ChangeKey="AQAAABYAAAAPxolXAHv3TaHUnjW8wWqXAAAEkbCr"/>
</t:Folder>
</m:Folders>
</m:GetFolderResponseMessage>
</m:ResponseMessages>
</m:GetFolderResponse>
</s:Body>
</s:Envelope>
In this example, a FolderView class object is created to limit the results of the
Folder.FindFolders method response. This scenario limits the properties to return to
the following: Id , DisplayName , and the extended property that indicates whether
the folder is a hidden folder. Set the FolderView.Traversal value to Deep to perform a
recursive search so that the server retrieves the subfolders, and set the root folder to
MsgFolderRoot, so that the server returns all the user's folders (and the server does not
return system folders in the Non-IPM Subtree).
This example assumes that service is a valid ExchangeService object and that the user
has been authenticated to an Exchange server.
C#
// Create a new folder view, and pass in the maximum number of folders to
return.
// so that your results will indicate whether the folder is a hidden folder.
// In this case, return the folder ID, DisplayName, and the value of the
isHiddenProp
// extended property.
view.Traversal = FolderTraversal.Deep;
FindFoldersResults findFolderResults =
service.FindFolders(WellKnownFolderName.MsgFolderRoot, view);
This is also the XML request that the EWS Managed API sends when you call the
FindFolders method.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:FindFolder Traversal="Deep">
<m:FolderShape>
<t:BaseShape>IdOnly</t:BaseShape>
<t:AdditionalProperties>
<t:ExtendedFieldURI PropertyTag="4340"
PropertyType="Boolean" />
</t:AdditionalProperties>
</m:FolderShape>
<m:IndexedPageFolderView MaxEntriesReturned="100"
Offset="0"
BasePoint="Beginning" />
<m:ParentFolderIds>
</m:ParentFolderIds>
</m:FindFolder>
</soap:Body>
</soap:Envelope>
The following XML example shows the FindFolderResponse message that is sent from
the server to the client in response to the FindFolder operation request. It contains only
the FolderId , the DisplayName , and the value of the PR_ATTR_HIDDEN extended
property for all the subfolders under the msgrootfolder folder. If the Value element is
set to true, the folder should be hidden in the client view.
This is also the XML response that the EWS Managed API sends when you get multiple
folders by using the FindFolder method. The values of some attributes and elements
have been shortened for readability, and some folders have not been included for
brevity.
XML
<s:Header>
<h:ServerVersionInfo MajorVersion="15"
MinorVersion="0"
MajorBuildNumber="815"
MinorBuildNumber="6"
Version="V2_7"
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance"/>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:FindFolderResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:FindFolderResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:RootFolder IndexedPagingOffset="16"
TotalItemsInView="16"
IncludesLastItemInRange="true">
<t:Folders>
<t:CalendarFolder>
<t:FolderId Id="AAAEOAAA="
ChangeKey="AgAAABYAAAAPxolXAHv3TaHUnjW8wWqXAAAAAAA3"/>
<t:DisplayName>Calendar</t:DisplayName>
<t:ExtendedProperty>
<t:ExtendedFieldURI PropertyTag="0x10f4"
PropertyType="Boolean"/>
<t:Value>false</t:Value>
</t:ExtendedProperty>
</t:CalendarFolder>
<t:ContactsFolder>
<t:FolderId Id="AAAEPAAA="
ChangeKey="AwAAABYAAAAPxolXAHv3TaHUnjW8wWqXAAAAAAA4"/>
<t:DisplayName>Contacts</t:DisplayName>
<t:ExtendedProperty>
<t:ExtendedFieldURI PropertyTag="0x10f4"
PropertyType="Boolean"/>
<t:Value>false</t:Value>
</t:ExtendedProperty>
</t:ContactsFolder>
<t:ContactsFolder>
<t:FolderId Id="AAAUKAAA="
ChangeKey="AwAAABYAAAAPxolXAHv3TaHUnjW8wWqXAAAAAAS5"/>
<t:DisplayName>Recipient Cache</t:DisplayName>
<t:ExtendedProperty>
<t:ExtendedFieldURI PropertyTag="0x10f4"
PropertyType="Boolean"/>
<t:Value>true</t:Value>
</t:ExtendedProperty>
</t:ContactsFolder>
<t:Folder>
<t:FolderId Id="AAAUJAAA="
ChangeKey="AQAAABYAAAAPxolXAHv3TaHUnjW8wWqXAAAAAASx"/>
<t:ExtendedProperty>
<t:ExtendedFieldURI PropertyTag="0x10f4"
PropertyType="Boolean"/>
<t:Value>true</t:Value>
</t:ExtendedProperty>
</t:Folder>
</t:Folders>
</m:RootFolder>
</m:FindFolderResponseMessage>
</m:ResponseMessages>
</m:FindFolderResponse>
</s:Body>
</s:Envelope>
First, create a PropertySet to limit the number of properties that the server returns in
the Folder.Bind response. We recommend that you use the IdOnly BasePropertySet
to reduce calls to the Exchange database. Next, use the Bind method to bind to the
folder to update. Then, update the DisplayName property, and use the
Folder.Update method to save the changes.
In this example, we assume that service is a valid ExchangeService object and that the
user has been authenticated to an Exchange server. The local variable folderId is the Id
of the folder to update.
C#
folder.Update();
First, send a GetFolder operation request message to get the folder to update, as
shown in Get a folder hierarchy by using EWS.
This is also the XML request that the EWS Managed API sends when you update a folder
by using the Folder.Update method. The values of some attributes and elements have
been shortened for readability.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:UpdateFolder>
<m:FolderChanges>
<t:FolderChange>
<t:FolderId Id="OrV9ZAAA="
ChangeKey="AQAAABYAAABVzRdyy/cHS4XTC9itCRdUAAAOrXWb" />
<t:Updates>
<t:SetFolderField>
<t:Folder>
</t:Folder>
</t:SetFolderField>
</t:Updates>
</t:FolderChange>
</m:FolderChanges>
</m:UpdateFolder>
</soap:Body>
</soap:Envelope>
To delete a folder by using the EWS Managed API, first, use the Folder.Bind method to
bind to the service object to the folder to delete. Next, use the Folder.Delete method
to delete the folder by using the HardDelete deletion mode.
This example assumes that service is a valid ExchangeService object and that the user
has been authenticated to an Exchange server. The local variable folderId is the Id of
the folder to delete.
C#
folder.Delete(DeleteMode.HardDelete);
To delete a folder by using EWS, first, send a GetFolder operation request message to
get the folder to update as shown in Get a folder by using EWS.
Next, send a DeleteFolder operation request message to the server to delete the
folder. The DeleteFolder operation request indicates that the DeleteType is HardDelete
and it includes the FolderId of the folder to delete.
This is also the XML request that the EWS Managed API sends when you delete a folder
by using the Folder.Delete method. The values of some attributes and elements have
been shortened for readability.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:DeleteFolder DeleteType="HardDelete">
<m:FolderIds>
<t:FolderId Id="OrV9ZAAA="
ChangeKey="AQAAABYAAABVzRdyy/cHS4XTC9itCRdUAAAOrXWf" />
</m:FolderIds>
</m:DeleteFolder>
</soap:Body>
</soap:Envelope>
Next steps
After you have retrieved the folders on the server, or made changes to folders, you
might want to synchronize your folder hierarchy or subscribe to notifications about
folder changes on the server.
See also
Folders and items in EWS in Exchange
Work with Exchange mailbox items by using EWS in Exchange
Deleting items by using EWS in Exchange
Develop web service clients for Exchange
Work with hidden folders by using EWS
in Exchange
Article • 03/15/2022 • 7 minutes to read
Learn how to make a folder hidden and find hidden folders by using the EWS Managed
API or EWS in Exchange.
With one exception, folders in the root of an Exchange mailbox (the non-IPM subtree)
are hidden from the user. Conversely, all folders in the MsgFolderRoot (the IPM subtree)
are visible to the user. So how do you hide a folder under the MsgFolderRoot? It's not
that tricky — it comes down to just one property, the PidTagAttributeHidden
(0x10F4000B) extended property. When this property is set to true, Outlook or another
client that uses the property to determine folder visibility will hide the folder from the
user's view. Because this is an extended property, it's more complex to use than your
average folder property, so this article will walk you through the main scenarios.
Table 1. EWS Managed API methods and EWS operations for working with hidden
folders
folders
Are you wondering what the one exception is — that is, what folder in the root IS visible
to users? It's the Finder folder (also known as the SearchFoldersWellKnownFolder
enumeration value, or the searchfoldersDistinguishedFolderId element value), which
contains users' search folders. Search folders created in the Finder folder are visible to
Outlook users. If you need to create a search folder that is not visible to users, move it
under the root folder to hide it. Unlike for other folders, setting the
PidTagAttributeHidden property to true will not hide a search folder in the Finder
folder.
This example assumes that service is a valid ExchangeService object for the mailbox
owner, that the user has been authenticated to an Exchange server, and that folderId is
a valid Folder.Id that identifies the folder to hide.
C#
folder.SetExtendedProperty(isHiddenProp, true);
folder.Update();
This is also the XML request that the EWS Managed API sends when you use the Bind
method to get a folder before making it a hidden folder.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:GetFolder>
<m:FolderShape>
<t:BaseShape>IdOnly</t:BaseShape>
<t:AdditionalProperties>
<t:ExtendedFieldURI PropertyTag="4340"
PropertyType="Boolean" />
</t:AdditionalProperties>
</m:FolderShape>
<m:FolderIds>
</m:FolderIds>
</m:GetFolder>
</soap:Body>
</soap:Envelope>
The server responds to the GetFolder request with a GetFolderResponse message that
includes a ResponseCode element value of NoError, which indicates that the folder
was retrieved successfully. The response also includes a Value for the
ExtendedProperty . In this example, the Value is set to false, which means that the
folder is currently not hidden.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="15"
MinorVersion="0"
MajorBuildNumber="898"
MinorBuildNumber="23"
Version="V2_10"
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:GetFolderResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:GetFolderResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Folders>
<t:Folder>
<t:FolderId Id="IQywAAAA=="
ChangeKey="AQAAABYAAAD32nSTjepyT63rYH17n9THAAAAABED" />
<t:ExtendedProperty>
<t:ExtendedFieldURI PropertyTag="0x10f4"
PropertyType="Boolean" />
<t:Value>false</t:Value>
</t:ExtendedProperty>
</t:Folder>
</m:Folders>
</m:GetFolderResponseMessage>
</m:ResponseMessages>
</m:GetFolderResponse>
</s:Body>
</s:Envelope>
This is also the XML request that the EWS Managed API sends when you use the Update
method to update a folder to make it a hidden folder.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:UpdateFolder>
<m:FolderChanges>
<t:FolderChange>
<t:FolderId Id="IQywAAAA=="
ChangeKey="AQAAABYAAAD32nSTjepyT63rYH17n9THAAAAABED"
/>
<t:Updates>
<t:SetFolderField>
<t:ExtendedFieldURI PropertyTag="4340"
PropertyType="Boolean" />
<t:Folder>
<t:ExtendedProperty>
<t:ExtendedFieldURI PropertyTag="4340"
PropertyType="Boolean" />
<t:Value>true</t:Value>
</t:ExtendedProperty>
</t:Folder>
</t:SetFolderField>
</t:Updates>
</t:FolderChange>
</m:FolderChanges>
</m:UpdateFolder>
</soap:Body>
</soap:Envelope>
This example assumes that service is a valid ExchangeService object for the mailbox
owner, and that the user has been authenticated to an Exchange server.
C#
folderView.Traversal = FolderTraversal.Deep;
FindFoldersResults findFolder =
service.FindFolders(WellKnownFolderName.MsgFolderRoot,
This is also the XML request that the EWS Managed API sends when you use the
FindFolders method to find all hidden folders.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:TimeZoneContext>
<t:TimeZoneDefinition Id="Central Standard Time" />
</t:TimeZoneContext>
</soap:Header>
<soap:Body>
<m:FindFolder Traversal="Deep">
<m:FolderShape>
<t:BaseShape>IdOnly</t:BaseShape>
<t:AdditionalProperties>
<t:ExtendedFieldURI PropertyTag="4340"
PropertyType="Boolean" />
</t:AdditionalProperties>
</m:FolderShape>
<m:IndexedPageFolderView MaxEntriesReturned="100"
Offset="0"
BasePoint="Beginning" />
<m:Restriction>
<t:IsEqualTo>
<t:ExtendedFieldURI PropertyTag="4340"
PropertyType="Boolean" />
<t:FieldURIOrConstant>
</t:FieldURIOrConstant>
</t:IsEqualTo>
</m:Restriction>
<m:ParentFolderIds>
</m:ParentFolderIds>
</m:FindFolder>
</soap:Body>
</soap:Envelope>
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="15"
MinorVersion="0"
MajorBuildNumber="898"
MinorBuildNumber="23"
Version="V2_10"
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:FindFolderResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:FindFolderResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:RootFolder IndexedPagingOffset="6"
TotalItemsInView="6"
IncludesLastItemInRange="true">
<t:Folders>
<t:ContactsFolder>
<t:FolderId Id="IBHgAAAA=="
ChangeKey="AwAAABYAAAD32nSTjepyT63rYH17n9THAAAAAACz" />
<t:DisplayName>{06967759-274D-40B2-A3EB-D7F9E73727D7}
</t:DisplayName>
<t:ExtendedProperty>
<t:ExtendedFieldURI PropertyTag="0x10f4"
PropertyType="Boolean" />
<t:Value>true</t:Value>
</t:ExtendedProperty>
</t:ContactsFolder>
<t:ContactsFolder>
<t:FolderId Id="IBHwAAAA=="
ChangeKey="AwAAABYAAAD32nSTjepyT63rYH17n9THAAAAAAC7" />
<t:DisplayName>{A9E2BC46-B3A0-4243-B315-60D991004455}
</t:DisplayName>
<t:ExtendedProperty>
<t:ExtendedFieldURI PropertyTag="0x10f4"
PropertyType="Boolean" />
<t:Value>true</t:Value>
</t:ExtendedProperty>
</t:ContactsFolder>
<t:ContactsFolder>
<t:FolderId Id="IBIQAAAA=="
ChangeKey="AwAAABYAAAD32nSTjepyT63rYH17n9THAAAAAADO" />
<t:DisplayName>GAL Contacts</t:DisplayName>
<t:ExtendedProperty>
<t:ExtendedFieldURI PropertyTag="0x10f4"
PropertyType="Boolean" />
<t:Value>true</t:Value>
</t:ExtendedProperty>
</t:ContactsFolder>
<t:ContactsFolder>
<t:FolderId Id="IBHQAAAA=="
ChangeKey="AwAAABYAAAD32nSTjepyT63rYH17n9THAAAAAACa" />
<t:DisplayName>Recipient Cache</t:DisplayName>
<t:ExtendedProperty>
<t:ExtendedFieldURI PropertyTag="0x10f4"
PropertyType="Boolean" />
<t:Value>true</t:Value>
</t:ExtendedProperty>
</t:ContactsFolder>
<t:Folder>
<t:FolderId Id="HAAAAA=="
ChangeKey="AQAAABYAAAD32nSTjepyT63rYH17n9THAAAAAACS" />
<t:ExtendedProperty>
<t:ExtendedFieldURI PropertyTag="0x10f4"
PropertyType="Boolean" />
<t:Value>true</t:Value>
</t:ExtendedProperty>
</t:Folder>
<t:Folder>
<t:FolderId Id="IQywAAAA=="
ChangeKey="AQAAABYAAAD32nSTjepyT63rYH17n9THAAAeZIBf" />
<t:DisplayName>TestFolder</t:DisplayName>
<t:ExtendedProperty>
<t:ExtendedFieldURI PropertyTag="0x10f4"
PropertyType="Boolean" />
<t:Value>true</t:Value>
</t:ExtendedProperty>
</t:Folder>
</t:Folders>
</m:RootFolder>
</m:FindFolderResponseMessage>
</m:ResponseMessages>
</m:FindFolderResponse>
</s:Body>
</s:Envelope>
After you have hidden or unhidden folders, you might want to get the folder hierarchy
or synchronize the folder hierarchy. The examples that show you how to get a folder
hierarchy by using the EWS Managed API or get a folder hierarchy by using EWS also
indicate which folders in the hierarchy are hidden.
See also
Folders and items in EWS in Exchange
Learn how to create, get, update, and delete items by using the EWS Managed API or
EWS in Exchange.
You can use the EWS Managed API or EWS to work with items in a mailbox. You can use
generic items — EWS Managed API Item objects or EWS Item types — to perform
some operations (getting an item or deleting an item by using the item's identifier);
however, most of the time you'll have to use a strongly typed item to perform a get or
update operation because you'll need access to the properties that are specific to the
strongly typed item.
For example, you can't use a generic item to retrieve an item that contains a start and
end date - you need an EWS Managed API Appointment object or an EWS
CalendarItem type to do that. And if you're using the EWS Managed API, you always
have to create strongly typed items, because the generic Item class does not have a
constructor. If you're working with an item that is not strongly typed, you can always use
the base Item class to work with the item.
Table 1. EWS Managed API methods and EWS operations for working with items
Create a None. You can only create specific item types by using the EWS CreateItem
Update an Item.Update
UpdateItem
item
Delete an Item.Delete
DeleteItem
item
In this article, you'll learn when you can use the generic base class and when you need
to use a strongly typed item to complete your task. The code examples will show you
how to use the base class, and what to do when you can't use the base class or it
doesn't fit your needs.
Create an item by using the EWS Managed API
The EWS Managed API does not have a publicly available constructor for the Item
class, so you must use the constructor for the specific item type you want to create in
order to create an item. For example, use the EmailMessage class constructor to
create a new email message, and the Contact class constructor to create a new
contact. Likewise, the server never returns generic Item objects in responses; all generic
items are returned as EmailMessage objects.
When you know the type of item to create, you can complete the task in just a few
steps. The steps are similar for all item types:
1. Initialize a new instance of one of the Item classes with the ExchangeService
object as a parameter.
2. Set properties on the item. The schemas are different for each item type, so
different properties are available for different items.
For example, you can create an EmailMessage object, set the Subject , Body , and
ToRecipients properties, and then send it by using the
EmailMessage.SendAndSaveCopy method.
C#
message.ToRecipients.Add("[email protected]");
message.SendAndSaveCopy();
To learn how to create a meeting or appointment item by using the EWS Managed API,
see Create appointments and meetings by using EWS in Exchange 2013.
For example, you can create an email message and send it by using the code in the
following example. This is also the XML request that the EWS Managed API sends when
you call the SendAndSaveCopy method.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:CreateItem MessageDisposition="SendAndSaveCopy">
<m:SavedItemFolderId>
</m:SavedItemFolderId>
<m:Items>
<t:Message>
<t:ToRecipients>
<t:Mailbox>
<t:EmailAddress>[email protected] </t:EmailAddress>
</t:Mailbox>
</t:ToRecipients>
</t:Message>
</m:Items>
</m:CreateItem>
</soap:Body>
</soap:Envelope>
To learn how to create a meeting or appointment item by using EWS, see Create
appointments and meetings by using EWS in Exchange 2013.
Get an item by using the EWS Managed API
To use the EWS Managed API to get an item if you know the Item.Id of the item to
retrieve, you simply call one of the Bind methods on the item, and the item is
retrieved. As a best practice, we recommend that you limit the properties returned to
only those that are required. This example returns the item Id property and the Subject
property.
This example assumes that service is a valid ExchangeService object and that the user
has been authenticated to an Exchange server. The local variable itemId is the Id of
the item to update.
C#
// As a best practice, limit the properties returned to only those that are
required.
If you're searching for an item that meets specific criteria, do the following:
For example, if you want to retrieve unread email messages in the Inbox, use the code in
the following example. This example uses a SearchFilterCollection to limit the results of
the FindItems method to unread messages, and limits the ItemView to limit results to
one item. This particular code only works on EmailMessage objects because the
EmailMessageSchema.IsRead value is part of the SearchFilter.
C#
SearchFilter sf = new
SearchFilter.SearchFilterCollection(LogicalOperator.And, new
SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false));
FindItemsResults<Item> findResults =
service.FindItems(WellKnownFolderName.Inbox, sf, view);
Alternatively, you can use a PropertySet to limit the results of the search as shown in
the following code example. This example uses the FindAppointments method to
retrieve up to five appointments that occur in the next 30 days. This code of course only
works on calendar items.
C#
// Initialize values for the start and end times, and the number of
appointments to retrieve.
// Set the start and end time and number of appointments to retrieve.
FindItemsResults<Appointment> appointments =
calendar.FindAppointments(cView);
Note that the information the server returns in the Bind method response is different
than the information that the server returns for a FindItem or FindAppointment method
response. The Bind method can return all the schematized properties, whereas the
FindItem and FindAppointment methods do not return all the schematized properties.
So if you need full access to the item, you'll have to use the Bind method. If you don't
have the item Id of the item you'd like to retrieve, use the FindItem or
FindAppointment methods to retrieve the Id, and then use the Bind method to retrieve
the properties you need.
To learn how to get a meeting or appointment item by using the EWS Managed API, see
Get appointments and meetings by using EWS in Exchange.
Get an item by using EWS
If you know the ItemId of the item to retrieve, you can get the item by using the
GetItem operation.
The following example shows the XML request to get the Subject of an item with a
specific ItemId. This is also the XML request that the EWS Managed API sends when
calling the Bind method on an ItemId. The values of some attributes and elements
have been shortened for readability.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:GetItem>
<m:ItemShape>
<t:BaseShape>IdOnly</t:BaseShape>
<t:AdditionalProperties>
</t:AdditionalProperties>
</m:ItemShape>
<m:ItemIds>
</m:ItemIds>
</m:GetItem>
</soap:Body>
</soap:Envelope>
The following example shows the XML response that the server returns after it processes
the GetItem operation. The response indicates the item was retrieved successfully. The
values of some attributes and elements have been shortened for readability.
XML
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="15"
MinorVersion="0"
MajorBuildNumber="815"
MinorBuildNumber="6"
Version="V2_7"
xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance"/>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:GetItemResponse
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:GetItemResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Items>
<t:Message>
<t:ItemId Id="GJc/NAAA="
ChangeKey="CQAAABYAAAAPxolXAHv3TaHUnjW8wWqXAAAGJd9Z"/>
</t:Message>
</m:Items>
</m:GetItemResponseMessage>
</m:ResponseMessages>
</m:GetItemResponse>
</s:Body>
</s:Envelope>
If you do not know the ItemId of the item you want to retrieve, you can use the
FindItem operation to find the item. In order to use the FindItem operation, you must
first identify the folder that you're searching. You can identify the folder by using its
DistinguinguishedFolderName or by using the FolderId . You can use either the
FindFolder or SyncFolderHierarchy operations to get the FolderId you need. Then
use the FindItem operation to search that folder for results that match the search filter.
Unlike the EWS Managed API, EWS does not provide a separate find operation for
appointments. The FindItem operation retrieves items of all types.
The following example shows the XML FindItem operation request that is sent to the
server to find appointments in the Calendar folder that occur in the next 30 days. The
values of some attributes and elements have been shortened for readability.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:FindItem Traversal="Shallow">
<m:ItemShape>
<t:BaseShape>IdOnly</t:BaseShape>
<t:AdditionalProperties>
</t:AdditionalProperties>
</m:ItemShape>
<m:ParentFolderIds>
<t:FolderId Id="AAAEOAAA="
ChangeKey="AgAAABYAAAAqRr3mNdNMSasqx/o9J13UAAAAAAA3" />
</m:ParentFolderIds>
</m:FindItem>
</soap:Body>
</soap:Envelope>
The server responds to the FindItem request with a FindItemResponse message that
includes the ResponseCode value of NoError, which indicates that the operation
completed successfully. If any calendar items meet the filtering criteria, they are included
in the response.
Note that the information the server returns in the GetItem operation response is
different than the information the server returns in a FindItem or FindAppointment
operation response. The GetItem operation can return all the schematized properties,
whereas the FindItem and FindAppointment operations do not return all the
schematized properties. So if you need full access to the item, you'll have to use the
GetItem operation. If you don't have the ItemId of the item you'd like to retrieve, use
the FindItem or FindAppointment operations to retrieve the ItemId, and then use the
GetItem operation to retrieve the elements you need.
To learn how to get a meeting or appointment item by using EWS, see Get
appointments and meetings by using EWS in Exchange.
1. Use the Bind method to get the latest version of the item, unless you already
have it. To update properties specific to a strongly typed item, you'll have to bind
to that item type. To update properties available on the generic item type, you can
bind to the Item object.
For example, you can update the subject of an email by using the generic item type, as
shown in the code in the following example.
This example assumes that service is a valid ExchangeService object and that the user
has been authenticated to an Exchange server. The local variable itemId is the Id of
the item to update.
C#
item.Update(ConflictResolutionMode.AlwaysOverwrite);
To learn how to update a meeting or appointment item by using the EWS Managed API,
see Update appointments and meetings by using EWS in Exchange.
1. Use the GetItem operation to get the latest version of the item, unless you
already have it.
2. Use the UpdateItem operation to specify fields to update and assign new values
to those fields.
The following example shows the XML UpdateItem operation request that is sent to the
server to update the Subject value of the email message. The values of some
attributes and elements have been shortened for readability.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:UpdateItem MessageDisposition="SaveOnly"
ConflictResolution="AlwaysOverwrite">
<m:ItemChanges>
<t:ItemChange>
<t:ItemId Id="APdZjAAA="
ChangeKey="CQAAABYAAAAqRr3mNdNMSasqx/o9J13UAAAAPdgr" />
<t:Updates>
<t:SetItemField>
<t:Message>
<t:Subject>New subject</t:Subject>
</t:Message>
</t:SetItemField>
</t:Updates>
</t:ItemChange>
</m:ItemChanges>
</m:UpdateItem>
</soap:Body>
</soap:Envelope>
To learn how to update a meeting or appointment item by using EWS, see Update
appointments and meetings by using EWS in Exchange.
If you need to find the item before deleting it, do the following:
1. Call the FindItems or FindAppointments method to find the item to delete.
For example, the following code shows how to move an email message to the Deleted
Items folder.
This example assumes that service is a valid ExchangeService object and that the user
has been authenticated to an Exchange server. The local variable itemId is the Id of
the item to update.
C#
item.Delete(DeleteMode.MoveToDeletedItems);
For more details about deleting items, see Deleting items by using EWS in Exchange. To
learn how to delete a meeting or appointment item by using the EWS Managed API, see
Delete appointments and cancel meetings by using EWS in Exchange.
The following example shows the XML request that is sent to the server to move the
email message to the Deleted Items folder. The values of some attributes and elements
have been shortened for readability.
XML
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<m:DeleteItem DeleteType="MoveToDeletedItems">
<m:ItemIds>
<t:ItemId Id="APdZjAAA="
ChangeKey="CQAAABYAAAAqRr3mNdNMSasqx/o9J13UAAANIFzC" />
</m:ItemIds>
</m:DeleteItem>
</soap:Body>
</soap:Envelope>
For more details about deleting items, see Deleting items by using EWS in Exchange. To
learn how to delete a meeting or appointment item by using EWS, see Delete
appointments and cancel meetings by using EWS in Exchange.
See also
Folders and items in EWS in Exchange
Work with folders by using EWS in Exchange
Deleting items by using EWS in Exchange
Deleting items by using EWS in
Exchange
Article • 09/14/2022 • 7 minutes to read
Find out how you can use the EWS Managed API or EWS in Exchange to delete items
either by moving them to the Deleted Items folder or to the dumpster.
Have you ever asked yourself what the difference is between moving items to the
Deleted Items folder, and moving them to the dumpster? You might be curious about
the different options for handling deleted items and how to implement those options in
your application. Exchange Web Services (EWS) includes three options for handling
deleted items. This article will hopefully clear up any confusion you might have about
the differences between them.
The Deleted Items folder - When you delete items in a mailbox, this is where they
go.
The dumpster (aka the Recoverable Items folder) - When you remove items from a
mailbox, this is where they go.
Figures 1 and 2 show what the deletion process looks like for items and folders in a
mailbox.
You can delete items and folders three different ways, depending on how "permanent"
you would like the deletion to be.
to the
Deleted This is like putting a piece of paper in the recycle bin by your desk. You can easily grab
Items it if you need it again.
folder
You can use any deletion operation that implements the move to the Deleted Items
folder option to perform this action.
You can also use the MoveItem operation ( Item.Move() ) or the MoveFolder
operation ( Folder.Move() ) to move an item or folder to the Deleted Items folder.
delete
This is like emptying your recycle bin into your curbside container. You can still access
the item if you need to, it's just a little harder.
For more about the dumpster (also called the Recoverable Items folder) and scenarios
such as eDiscovery or litigation holds, see Recoverable Items Folder on TechNet.
Soft deletions aren't recommended for applications that target Exchange 2007. In
Exchange 2007, soft deletions are handled by setting a bit on the item to indicate that it
will be moved to the dumpster at an unspecified time.
Soft delete traversals, or searches of items that have been soft deleted via the FindItem
operation , are not supported in Exchange Online, Exchange Online as part of Office
365, and versions of Exchange starting with Exchange 2010.
delete
Hard-deleted items are placed in the Purges folder of the dumpster. This is like when
the recycling truck empties your curbside recycle container. The items cannot be
accessed from an email client like Outlook or Outlook Web App, and, unless there is a
hold set on the mailbox, the items will be permanently deleted after a set period of
time.
You can read more about item retention in the article Configure Deleted Item Retention
and Recoverable Items Quotas .
NOTE: Folders are not placed in the Purges folder when they are hard deleted. Hard-
deleted folders are removed from the mailbox.
The move to the Deleted Items folder and the hard delete options are transactional,
which means that by the time the web service call finishes, the item has been moved to
the Deleted Items folder or the dumpster.
To help you better understand the ecosystem of folders that are used to store deleted
items, the following figure shows the hierarchy of folders that can contain deleted items.
The folder names are as they appear in the DistinguishedFolderIdNameType schema
type, or the WellKnownFolderName enumeration in the EWS Managed API.
Table 3: EWS operations and EWS Managed API methods for deleting items
DeleteItem operation
Item.Delete method
Exchange Deletes items
2007 from a
ExchangeService.DeleteItems mailbox.
method
CreateItem operation
Appointment.Accept method
Exchange Indirectly
2007 moves an
Appointment.AcceptTentatively item to the
method
Deleted Items
folder
Appointment.CancelMeeting whenever a
method
response to a
meeting
Appointment.Decline
request is
sent or the
MeetingRequest.Accept method
response is
set on the
MeetingRequest.AcceptTentatively appointment.
method
The deletion
Meeting