Common Exchange API Concepts
The following applies to Exchange routes that link to this page. No v0 route supports these concepts.
Data Models
Mailbox
Required for Create*
Field Name | Data Type | Verbs | Description | |
---|---|---|---|---|
Common Name* | String | GET, POST | The resource's username | |
Display Name* | String | GET, POST, PUT | The resource's display name | |
Alias | String | GET | Read only | |
IsHiddenFromAddressList | Boolean | GET, POST, PUT | If true, not displayed in public address book. | |
Status | String | GET | Current status of resource. (See Asynchronous Statuses) | |
Error | Error | GET | Returns error information about the latest operation on the resource. (See Asynchronous Errors) |
Error
(See Asynchronous Errors)
Field Name | Data Type | Verbs | Description |
---|---|---|---|
Action | "get", "post", "put", "delete" | GET | |
Message | String | GET | |
Details | String | GET | |
Code | Integer | GET | |
Uri | Uri | GET | URI to GET to retrieve full detail |
Serialization
XML and JSON are supported.
For XML, fields called "Value" are represented by the inner XML of a node.
Listings
Query parameters for listings:
Field Name | Data Type | Description |
---|---|---|
Search | String | A value to filter the list by Common Name and Display Name. |
Marker | String | The common name of the last item from the previous listing call. Use this to get the next page of data. |
Limit | Integer | The maximum number of items to return. |
Sort | String | The value to sort by; must be "CN" or "DisplayName" for primary resources like Distribution Lists and Resources |
Order | String | asc or desc, to specify which way to order the data |
PreviousPage | Boolean | Returns the previous page based on Marker. If Marker is not specified, then the last page is returned. |
ExportTo | String | For listings that support exporting, this value can be a valid email address. An email will be sent containing a link to a CSV file of the requested data. |
Listings use markers for pagination. To get the next page of data, set the marker parameter to common name of the last item of the list that was most recently returned. To get the previous page of data, set the marker to the common name of the first item of the list that was most recently returned, and set PreviousPage to true.
Demonstration
In this demonstration, there are 5 Resources on the example.com domain, room.101 through room.105.
We can list all of the Resources Mailboxes on the domain. The response includes a Resource Mailbox’s property in an array of the list results. For listings, the name of this property is dependent on the resource type. (For the Resources resource, the property is called ResourceMailboxes, but for the Distribution List resource, the property is called DistributionLists.)”
The Total property shows that there are 5 items total, that the limit for this page is 50, and that the items are sorted by Common Name ascending.
Request: GET /v1/customers/all/domains/example.com/ex/resources Response: 200 OK { "ResourceMailboxes":[ { "Type":"Room", "PhoneNumber":null, "Upn":"room.101@example.com", "ResourceCapacity":0, "CustomProperties":[ ], "CommonName":"room.101", "DisplayName":"Room 101", "Alias":"room.101.example.com", "IsHiddenFromAddressList":false, "PrimarySmtpAddress":null, "EmailAddresses":null, "Status":"Ready", "LegacyExchangeDn":"/o=e14s/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=room.101f16" }, { "Type":"Room", "PhoneNumber":null, "Upn":"room.102@example.com", "ResourceCapacity":0, "CustomProperties":[ ], "CommonName":"room.102", "DisplayName":"Room 102", "Alias":"room.102.example.com", "IsHiddenFromAddressList":false, "PrimarySmtpAddress":null, "EmailAddresses":null, "Status":"Ready", "LegacyExchangeDn":"/o=e14s/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=room.10269d" }, { "Type":"Room", "PhoneNumber":null, "Upn":"room.103@example.com", "ResourceCapacity":0, "CustomProperties":[ ], "CommonName":"room.103", "DisplayName":"Room 103", "Alias":"room.103.example.com", "IsHiddenFromAddressList":false, "PrimarySmtpAddress":null, "EmailAddresses":null, "Status":"Ready", "LegacyExchangeDn":"/o=e14s/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=room.1037e9" }, { "Type":"Room", "PhoneNumber":null, "Upn":"room.104@example.com", "ResourceCapacity":0, "CustomProperties":[ ], "CommonName":"room.104", "DisplayName":"Room 104", "Alias":"room.104.example.com", "IsHiddenFromAddressList":false, "PrimarySmtpAddress":null, "EmailAddresses":null, "Status":"Ready", "LegacyExchangeDn":"/o=e14s/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=room.10400c" }, { "Type":"Room", "PhoneNumber":null, "Upn":"room.105@example.com", "ResourceCapacity":0, "CustomProperties":[ ], "CommonName":"room.105", "DisplayName":"Room 105", "Alias":"room.105.example.com", "IsHiddenFromAddressList":false, "PrimarySmtpAddress":null, "EmailAddresses":null, "Status":"Ready", "LegacyExchangeDn":"/o=e14s/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=room.105f62" } ], "Sort":"cn", "Limit":50, "Total":5, "Order":"asc" }
Search
The request below demonstrates the Search option. We search for "3", which returns results that match both the Common Name and Display Name.
Total denotes that there is only 1 item that matches this search criteria. This example shows all items on one page, however the Total can be more than the Limit if the results do not fit in one response.
Request: GET /v1/customers/all/domains/example.com/ex/resources?search=g Response: 200 OK { "ResourceMailboxes":[ { "Type":"Room", "PhoneNumber":null, "Upn":"room.103@example.com", "ResourceCapacity":0, "CustomProperties":[ ], "CommonName":"room.103", "DisplayName":"Room 103", "Alias":"room.103.example.com", "IsHiddenFromAddressList":false, "PrimarySmtpAddress":null, "EmailAddresses":null, "Status":"Ready", "LegacyExchangeDn":"/o=e14s/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=room.1037e9" } ], "Sort":"cn", "Search":"3", "Limit":50, "Total":5, "Order":"asc" }
Limit
The request below demonstrates the Limit option
Request: GET /v1/customers/all/domains/example.com/ex/resources?limit=2 Response: 200 OK { "ResourceMailboxes":[ { "Type":"Room", "PhoneNumber":null, "Upn":"room.101@example.com", "ResourceCapacity":0, "CustomProperties":[ ], "CommonName":"room.101", "DisplayName":"Room 101", "Alias":"room.101.example.com", "IsHiddenFromAddressList":false, "PrimarySmtpAddress":null, "EmailAddresses":null, "Status":"Ready", "LegacyExchangeDn":"/o=e14s/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=room.101f16" }, { "Type":"Room", "PhoneNumber":null, "Upn":"room.102@example.com", "ResourceCapacity":0, "CustomProperties":[ ], "CommonName":"room.102", "DisplayName":"Room 102", "Alias":"room.102.example.com", "IsHiddenFromAddressList":false, "PrimarySmtpAddress":null, "EmailAddresses":null, "Status":"Ready", "LegacyExchangeDn":"/o=e14s/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=room.10269d" } ], "Sort":"cn", "Limit":2, "Total":5, "Order":"asc" }
Marker
The request below demonstrates the Marker option. We are getting the next page of results from the previous example.
Request: GET /v1/customers/all/domains/example.com/ex/resources?marker=room.103 Response: 200 OK { "ResourceMailboxes":[ { "Type":"Room", "PhoneNumber":null, "Upn":"room.104@example.com", "ResourceCapacity":0, "CustomProperties":[ ], "CommonName":"room.104", "DisplayName":"Room 104", "Alias":"room.104.example.com", "IsHiddenFromAddressList":false, "PrimarySmtpAddress":null, "EmailAddresses":null, "Status":"Ready", "LegacyExchangeDn":"/o=e14s/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=room.10400c" }, { "Type":"Room", "PhoneNumber":null, "Upn":"room.105@example.com", "ResourceCapacity":0, "CustomProperties":[ ], "CommonName":"room.105", "DisplayName":"Room 105", "Alias":"room.105.example.com", "IsHiddenFromAddressList":false, "PrimarySmtpAddress":null, "EmailAddresses":null, "Status":"Ready", "LegacyExchangeDn":"/o=e14s/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=room.105f62" } ], "Sort":"cn", "Marker":"room.103", "Limit":50, "Total":5, "Order":"asc" }
PreviousPage
This request demonstrates the PreviousPage option. We are getting the previous page of results from the previous example. Notice how the results are the same as from two examples previous.
Request: GET /v1/customers/all/domains/example.com/ex/resources?marker=room.103&previousPage=true Response: 200 OK { "ResourceMailboxes":[ { "Type":"Room", "PhoneNumber":null, "Upn":"room.101@example.com", "ResourceCapacity":0, "CustomProperties":[ ], "CommonName":"room.101", "DisplayName":"Room 101", "Alias":"room.101.example.com", "IsHiddenFromAddressList":false, "PrimarySmtpAddress":null, "EmailAddresses":null, "Status":"Ready", "LegacyExchangeDn":"/o=e14s/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=room.101f16" }, { "Type":"Room", "PhoneNumber":null, "Upn":"room.102@example.com", "ResourceCapacity":0, "CustomProperties":[ ], "CommonName":"room.102", "DisplayName":"Room 102", "Alias":"room.102.example.com", "IsHiddenFromAddressList":false, "PrimarySmtpAddress":null, "EmailAddresses":null, "Status":"Ready", "LegacyExchangeDn":"/o=e14s/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=room.10269d" } ], "Sort":"cn", "Marker":"room.106", "Limit":50, "Total":5, "Order":"asc" }
Sort and Order
This request demonstrates the Sort and Order options.
Request: GET /v1/customers/all/domains/example.com/ex/resources?sort=DisplayName&Order=desc Response: 200 OK { "ResourceMailboxes":[ { "Type":"Room", "PhoneNumber":null, "Upn":"room.105@example.com", "ResourceCapacity":0, "CustomProperties":[ ], "CommonName":"room.105", "DisplayName":"Room 105", "Alias":"room.105.example.com", "IsHiddenFromAddressList":false, "PrimarySmtpAddress":null, "EmailAddresses":null, "Status":"Ready", "LegacyExchangeDn":"/o=e14s/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=room.105f62" }, { "Type":"Room", "PhoneNumber":null, "Upn":"room.104@example.com", "ResourceCapacity":0, "CustomProperties":[ ], "CommonName":"room.104", "DisplayName":"Room 104", "Alias":"room.104.example.com", "IsHiddenFromAddressList":false, "PrimarySmtpAddress":null, "EmailAddresses":null, "Status":"Ready", "LegacyExchangeDn":"/o=e14s/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=room.10400c" }, { "Type":"Room", "PhoneNumber":null, "Upn":"room.103@example.com", "ResourceCapacity":0, "CustomProperties":[ ], "CommonName":"room.103", "DisplayName":"Room 103", "Alias":"room.103.example.com", "IsHiddenFromAddressList":false, "PrimarySmtpAddress":null, "EmailAddresses":null, "Status":"Ready", "LegacyExchangeDn":"/o=e14s/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=room.1037e9" }, { "Type":"Room", "PhoneNumber":null, "Upn":"room.102@example.com", "ResourceCapacity":0, "CustomProperties":[ ], "CommonName":"room.102", "DisplayName":"Room 102", "Alias":"room.102.example.com", "IsHiddenFromAddressList":false, "PrimarySmtpAddress":null, "EmailAddresses":null, "Status":"Ready", "LegacyExchangeDn":"/o=e14s/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=room.10269d" }, { "Type":"Room", "PhoneNumber":null, "Upn":"room.101@example.com", "ResourceCapacity":0, "CustomProperties":[ ], "CommonName":"room.101", "DisplayName":"Room 101", "Alias":"room.101.example.com", "IsHiddenFromAddressList":false, "PrimarySmtpAddress":null, "EmailAddresses":null, "Status":"Ready", "LegacyExchangeDn":"/o=e14s/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=room.101f16" } ], "Sort":"DisplayName", "Limit":50, "Total":5, "Order":"desc" }
Asynchronous Statuses
POST, PUT, and DELETE operations are asynchronous. That means that submitting a request will return a success code (204 No Content), but the request itself is not processed immediately. Rather, the request is added to a queue to be completed by another worker. POST, PUT, and DELETE requests will not be accepted unless the resource's status is Ready.
Status | Description |
---|---|
Creating | A POST request is being processed. |
Updating | A PUT request is being processed. |
Deleting | A DELETE request is being processed. |
Ready | The last request for the resource was successful. |
Error | The last request for the resource failed. |
The following annotated HTTP requests and responses demonstrate all of the statuses except for Error. For a demonstration of the Error status, see Asynchronous Errors
Demonstration
Submit a request to create a basic Resource. The request is accepted and will be processed.
Request: POST /v1/customers/all/domains/example.com/ex/resources/ { "CommonName": "status.resource.100", "Type": "Room", "DisplayName": "Status Resource 100" } Response: 204 No Content
GET the Resource right away. The status shows that the Resource is being created.
Request: GET /v1/customers/all/domains/example.com/ex/resources/status.resource.100 Response: 200 OK { "Type":"Room", "PhoneNumber":null, "Upn":null, "ResourceCapacity":0, "CustomProperties":[ ], "CommonName":"status.resource.100", "DisplayName":"Status Resource 100", "Alias":null, "IsHiddenFromAddressList":false, "PrimarySmtpAddress":null, "EmailAddresses":null, "Status":"Creating", "LegacyExchangeDn":null }
Get the Resource again a bit later. The status shows that the resource is ready.
GET /v1/customers/all/domains/example.com/ex/resources/status.resource.100 Response: 200 OK { "Type":"Room", "PhoneNumber":null, "Upn":"status.resource.100@example.com", "ResourceCapacity":0, "CustomProperties":[ ], "CommonName":"status.resource.100", "DisplayName":"Status Resource 100", "Alias":"status.resource.100.example.com", "IsHiddenFromAddressList":false, "PrimarySmtpAddress":null, "EmailAddresses":null, "Status":"Ready", "LegacyExchangeDn":"/o=e14s/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=status.resource.100312" }
Submit a request to update the Resource. The request is accepted and will be processed.
Request: PUT /v1/customers/all/domains/example.com/ex/resources/status.resource.100 { "DisplayName": "Status Resource 100!!!" } Response: 204 No Content
GET the Resource right away. The status shows that the Resource is being updated.
Request: GET /v1/customers/all/domains/example.com/ex/resources/status.resource.100 Response: 200 OK { "Type":"Room", "PhoneNumber":null, "Upn":"status.resource.100@example.com", "ResourceCapacity":0, "CustomProperties":[ ], "CommonName":"status.resource.100", "DisplayName":"Status Resource 100!!!", "Alias":"status.resource.100.example.com", "IsHiddenFromAddressList":false, "PrimarySmtpAddress":null, "EmailAddresses":null, "Status":"Updating", "LegacyExchangeDn":"/o=e14s/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=status.resource.100312" }
Get the Resource again a bit later. The status shows that the resource is ready.
Request: GET /v1/customers/all/domains/example.com/ex/resources/status.resource.100 Response: 200 OK { "Type":"Room", "PhoneNumber":null, "Upn":"status.resource.100@example.com", "ResourceCapacity":0, "CustomProperties":[ ], "CommonName":"status.resource.100", "DisplayName":"Status Resource 100!!!", "Alias":"status.resource.100.example.com", "IsHiddenFromAddressList":false, "PrimarySmtpAddress":null, "EmailAddresses":null, "Status":"Ready", "LegacyExchangeDn":"/o=e14s/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=status.resource.100312" }
Submit a request to delete the Resource. The request is accepted and will be processed.
Request: DELETE /v1/customers/all/domains/example.com/ex/resources/status.resource.100 Response: 204 No Content
GET the Resource right away. The status shows that the Resource is being deleted.
Request: GET /v1/customers/all/domains/example.com/ex/resources/status.resource.100 Response: 200 OK { "Type":"Room", "PhoneNumber":null, "Upn":"status.resource.100@example.com", "ResourceCapacity":0, "CustomProperties":[ ], "CommonName":"status.resource.100", "DisplayName":"Status Resource 100!!!", "Alias":"status.resource.100.example.com", "IsHiddenFromAddressList":false, "PrimarySmtpAddress":null, "EmailAddresses":null, "Status":"Deleting", "LegacyExchangeDn":"/o=e14s/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=status.resource.100312" }
Get the Resource again a bit later. The resource cannot be found, because it has been deleted.
Request: GET /v1/customers/all/domains/example.com/ex/resources/status.resource.100 Response: 200 OK { "itemNotFoundFault":{ "resourceType":"", "message":"The requested mailbox could not be found", "details":"10/2/2013 3:18:09 PM", "code":404 } }
Asynchronous Errors
A mailbox will go into an Error state if an error occurs after the initial request was accepted when creating, updating or deleting a mailbox.
This means that the mailbox will have a status of "Error" and will contain an Error property.
Error Uri
- The Error property has a Uri field that contains the location of the error details
- A GET on the location returns additional details about the error
- A DELETE on the location will clear the Error
- If the error occurred after a POST, deleting the error will also remove the associated mailbox
- If the error occurred after a PUT or DELETE, deleting the error will return the mailbox to its previous state before the error occurred
The following annotated HTTP requests and responses demonstrate all of the Error statuses and Error objects.
Demonstration
Generating, Viewing, and Deleting Errors
Adding a Resource with an invalid RequestInPolicy recipient will produce an asynchronous error. The request is accepted and will be processed
Request: POST /v1/customers/all/domains/example.com/ex/resources/ { "CommonName": "errored.room.100", "Type": "Room", "DisplayName": "Errored Error 100", "RequestInPolicy": { "Recipients": [ { "Value": "I do not exist and also contain invalid characters" } ] } } Response: 204 No Content
We can GET the resource immediately. While the resource is processing, the status is "Creating"
Request: GET /v1/customers/all/domains/example.com/ex/resources/errored.room.100 Response: 200 OK { "Type":"Room", "PhoneNumber":null, "Upn":null, "ResourceCapacity":0, "CustomProperties":[ ], "CommonName":"errored.room.100", "DisplayName":"Errored Error 100", "Alias":null, "IsHiddenFromAddressList":false, "PrimarySmtpAddress":null, "EmailAddresses":null, "Status":"Creating", "LegacyExchangeDn":null }
We can GET the resource again, once it is done processing. Now that the resource is done processing, the status has changed to Error, and the Error object has a URI.
Request: GET /v1/customers/all/domains/example.com/ex/resources/errored.room.100 Response: 200 OK { "Type":"Room", "PhoneNumber":null, "Upn":null, "ResourceCapacity":0, "CustomProperties":[ ], "CommonName":"errored.room.100", "DisplayName":"Errored Error 100", "Alias":null, "IsHiddenFromAddressList":false, "PrimarySmtpAddress":null, "EmailAddresses":null, "Status":"Error", "LegacyExchangeDn":null, "Error":{ "Action":null, "Message":null, "Details":null, "Code":0, "Uri":"/v1/customers/all/domains/example.com/ex/resources/errored.room.100/errors" } }
We can perform a GET on that Error URI to get the error.
Request: GET /v1/customers/all/domains/example.com/ex/resources/errored.room.100/errors Response: 200 OK { "Errors":[ { "Action":"post", "Message":"Error creating new resource mailbox", "Details":"System.Management.Automation.RemoteException: Couldn't find object \"e14s.mlsrvr.com/hosting/1191941/example.com/I do not exist and also contain invalid characters\". Please make sure that it was spelled correctly or specify a different object.", "Code":0, "Uri":null } ] }
We can perform a DELETE on the Error URI to clear the error. This operation is synchronous. When the HTTP response returns with success, the error has been deleted.
Request: DELETE /v1/customers/all/domains/example.com/ex/resources/errored.room.100/errors Response: 204 No Content
We can verify that the error is gone.
Request: GET /v1/customers/all/domains/example.com/ex/resources/errored.room.100/errors Response: 404 Not Found { "itemNotFoundFault":{ "resourceType":"", "message":"The requested mailbox could not be found", "details":"10/2/2013 2:25:39 PM", "code":404 } }
Since the error was with a POST, performing a GET on the resource now will return a 404.
Request: GET /v1/customers/all/domains/example.com/ex/resources/errored.room.100 Response: 404 Not Found { "itemNotFoundFault":{ "resourceType":"", "message":"The requested mailbox could not be found", "details":"10/2/2013 2:25:50 PM", "code":404 } }
Operating On a Resource That Is Errored
This next sequence demonstrates the behavior of resource that had an error while creating.
We create a Distribution List, adding a recipient that doesn't exist.
Request: POST https://api.emailsrvr.com/v1/customers/me/domains/example.com/ex/distributionLists/ { "CommonName": "add.error", "DisplayName": "Add Error", "Members": { "Recipients":[{ "Value": "doesnt.exist" }] } } Response: 204 No Content
When we GET the resource, we see that it is an error state.
Request: GET https://api.emailsrvr.com/v1/customers/me/domains/example.com/ex/distributionLists/add.error Response: 200 OK { "MemberCount": 0, "CommonName": "add.error", "DisplayName": "Add Error", "Alias": null, "IsHiddenFromAddressList": false, "PrimarySmtpAddress": null, "Status": "Error", "LegacyExchangeDn": null, "Error": { "Action": null, "Message": null, "Details": null, "Code": 0, "Uri": "/v1/customers/me/domains/example.com/ex/distributionLists/add.error/errors" } }
Trying to POST with the same Common Name will result in a 400.
Request: POST https://api.emailsrvr.com/v1/customers/me/domains/example.com/ex/distributionLists/ { "CommonName": "add.error", "DisplayName": "Add Error", } Response: 400 Bad Request { "badRequestFault": { "message": "The email address add.error@example.com is already in use.", "details": "4/18/2014 2:46:33 PM", "code": 400 } }
Trying to PUT a change to the resource will result in a 404. (If the resource was created, and the error was with an update, then trying to PUT a change to the resource will result in a 405.)
Request: PUT https://api.emailsrvr.com/v1/customers/me/domains/example.com/ex/distributionLists/add.error { "DisplayName": "Add Error!" } Response: 404 Not Found { "itemNotFoundFault": { "resourceType": "", "message": "The requested distribution list could not be found", "details": "4/18/2014 2:16:27 PM", "code": 404, } }
Trying to DELETE the resoruce will result in a 405.
Request: DELTE https://api.emailsrvr.com/v1/customers/me/domains/example.com/ex/distributionLists/add.error Response: 405 Method Not Allowed { "appsFault": { "message": "405 Method Not Allowed", "details": "4/18/2014 2:15:36 PM", "code": 405 } }
Calling DELETE on the error path returned by the resource will delete the error and the resource.