207 Multi-Status

207 Multi-Status is used primarily by WebDAV servers. I don’t think it’s used much outside of WebDAV, if at all.

The WebDAV specification describes this statuscode as an indicator to a client that multiple operations happened, and that the status for each operation can be found in the body of the response.

So unlike other 2xx codes, getting a 207 doesn’t necessarily mean the operation succeeded. It just means that the client should inspect the body to get the true information about the operation.

The most common WebDAV example is that it has a feature to get information about multiple resources all at once via the PROPFIND HTTP method. The server can then report information about each individual resource via this code.

Here’s an example of a typical 207 response:

HTTP/1.1 207 Multi-Status
Content-Type: application/xml; charset="utf-8"
Content-Length: xxxx

<d:multistatus xmlns:d="DAV:">
    <d:response>
        <d:href>/calendars/johndoe/home/132456762153245.ics</d:href>
        <d:propstat>
            <d:prop>
                <d:getetag>"xxxx-xxx"</d:getetag>
            </d:prop>
            <d:status>HTTP/1.1 200 OK</d:status>
        </d:propstat>
    </d:response>
    <d:response>
        <d:href>/calendars/johndoe/home/fancy-caldav-client-1234253678.ics</d:href>
        <d:propstat>
            <d:prop>
                <d:getetag>"5-12"</d:getetag>
            </d:prop>
            <d:status>HTTP/1.1 200 OK</d:status>
        </d:propstat>
    </d:response>
</d:multistatus>

In the preceeding response, 2 resources are reported and for each a getetag WebDAV property is reported. Fully explaining the WebDAV model is outside the scope of this article.

You could imagine that 207 might be repurposed by some JSON-based API. For example, if a client made some kind of batch request, and a server wants to report back on the success of each individual item.

Perhaps this response looks somewhat like this:

HTTP/1.1 207 Multi-Status
Content-Type: application/json
Content-Length: xxxx

{
  "results": [
    {
      "href": "/batch/5/item/1",
      "status": 200
    },
    {
      "href": "/batch/5/item/2",
      "status": 200
    },
    {
      "href": "/batch/5/item/3",
      "status": 400
    },
    {
      "href": "/batch/5/item/4",
      "status": 403
    }
}

I have some doubts whether this is a good idea though. Some questions I would want to ask are:

  • HTTP prefers requests to either fully succeed or fully fail. Do we really need to report on individual items or can we do this atomically instead?
  • If we do want to report on multiple items, why not make these multiple HTTP requests instead?

If doing multiple HTTP requests is too expensive, I think it’s wise to first see if there’s possibilities to reduce the cost of multiple HTTP requests, before breaking HTTP semantics. HTTP/2 might help because it allows for multiple requests to be pipelined, and it keeps a single connection open.

References

  • RFC4918 - HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)

HTTP series

This article is part of an ongoing series about the HTTP protocol.

If you want to follow along as I write them, you can Subscribe to my Atom feed or Mailing list.

Informational 1xx

Successful 2xx

Redirection 3xx

Client Error 4xx

Web mentions