Overview
libdaap
SourceForge

Digital Audio Access Protocol (DAAP)

This document describes the DAAP protocol and how to use it. It not complete at the moment, but it will hopefully point people in the right direction. We still don't know how iTunes actually plays music on another computer, but that's only because we haven't had time to look at it yet. Hopefully there won't be any nasty obstacles in the way.

Disclaimer: All the following information has been figured out using a network dump program; the iTunes binary has not be reverse-engineered in any way, and neither have any of the libraries that it links to. In addition, we (the contributors to the project) make no claims that the following information is valid, so use it at your own risk.

Basic Form

The iTunes music sharing server listens on TCP port 3689. All the requests are HTTP GET requests with one or two extra headers and most use the gzip content encoding, but the server is capable of sending responses without the encoding. It uses this encoding to transparently compress the data so that the library listing takes less time to transfer. The content type of the data is application/x-dmap-tagged. All this makes it trivial to get unencoded data from the server using curl or wget.

The only extra header on the request is Client-DAAP-Version, and iTunes sends "1.0" as the value. When using curl or wget this header does not get sent but iTunes doesn't seem to mind. The server returns a header called DAAP-Server whose value is "iTunes/4.0 (Mac OS X)".

Here is a sample request and response:

GET /server-info HTTP/1.1
Host: daap.example.com
Accept: */*
User-Agent: iTunes/4.0 (Macintosh; N; PPC)
Client-DAAP-Version: 1.0
Accept-Encoding: gzip

HTTP/1.1 200 OK
Date: Thu, 01 May 2003 18:00:28 GMT
DAAP-Server: iTunes/4.0 (Mac OS X)
Content-Type: application/x-dmap-tagged
Content-Length: 122
Content-Encoding: gzip

[binary data]

Data Format

It seems that the data is divided up into several named segments, which shall be called chunks in this project. Some of these chunks can contain other chunks, others contain data of various types. All numerical values are in big-endian format. The basic format of a chunk is the following:

bytes field description
0-3 Content code OSType (unsigned long), description of the contents of this chunk
4-7 Length Length of the contents of this chunk (not the whole chunk)
8- Data The data contained within the chunk

I have discovered that, for some reason, the top-level chunk you get from a request sometimes has a bad length encoded in it. One of the responses returns a length 12 bytes too small and another two responses return lengths 12 bytes too long. Since a request can only contain one top-level chunk, I have found the best way to work around this is to simply ignore the length in the top-level chunk and figure it out manually (it must be the total length of the data minus the length of the content code and the length field). This kludge does not apply for children of the top-level chunk (where such surgery would be difficult).

Request URIs

These are the basic types of request that iTunes uses.

/server-info

Gets information about the server, such as protocol version, name, and capabilities. [more info]

/content-codes

A very interesting request that gave the whole protocol away to me. Information about all the content codes used by chunks, their long names, and basic data types contained within. [more info]

/login

Begins a session. You need to have a session active to retrieve any real information from the server (song list, playlists, etc...).

/logout

Ends a session.

/update

To ensure that the client has the latest version of the library and playlists, iTunes uses a "revision number". This request returns the current revision number.

/databases

Returns a list of databases. iTunes currently only uses one database, which represents all the songs and playlists that it knows about. Maybe a future version could show the songs and playlists on an iPod for example? (Maybe it does already, I don't have an iPod to try this with yet)

/databases/[num]/items

Returns all the songs in the database.

/databases/[num]/containers

Returns all the playlists in the database.

/databases/[num]/containers/[num]/items

Returns all the items contained within a playlist.

/resolve

I haven't yet yad a look at this request yet. I know that it is used to play music and link directly to playlists, but that is all I had time to figure out. More on this later.