Common Exchange API Concepts

From Rackspace Email & Apps API
Revision as of 14:49, 18 April 2014 by Appscp (talk | contribs) (added more detail around async errors)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

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.