diff --git a/client/djrandom_client/djfuse.py b/client/djrandom_client/djfuse.py
index b83d457b7d501c61397df4ebbe3299f5f0f424b9..a3b1fd5b365b65b781daa7a23e2578b2358902fc 100644
--- a/client/djrandom_client/djfuse.py
+++ b/client/djrandom_client/djfuse.py
@@ -11,20 +11,29 @@ from fuse import FUSE, Operations, LoggingMixIn
 
 
 class DJAPI(object):
+    """Stub for the remote HTTP API."""
 
     def __init__(self, server_url, api_key='fuse'):
         self._server_url = server_url
         self._api_key = api_key
         self._opener = urllib2.build_opener()
 
-    def get(self, url):
+    def _create_request(self, url, *moreurlparts):
+        if moreurlparts:
+            url += '/' + '/'.join(map(urllib.quote, moreurlparts))
 	print 'HTTP GET:', url
-        req = urllib2.Request(self._server_url + url)
+        return urllib2.Request(
+            '%s/%s' % (self._server_url, url),
+            headers={'User-Agent': 'djfuse/0.1',
+                     'X-Key': self._api_key})
+
+    def get(self, url, *moreurlparts):
+        req = self._create_request(url, *urlparts)
         return json.load(self._opener.open(req))
 
     def download(self, sha1, path):
         print 'HTTP DOWNLOAD:', sha1
-        req = urllib2.Request('%s/dl/%s' % (self._server_url, sha1))
+        req = self._create_request('/dl', sha1)
         resp = self._opener.open(req)
         with open(path, 'wb') as fd:
             shutil.copyfileobj(resp, fd)
diff --git a/server/djrandom/frontend/frontend.py b/server/djrandom/frontend/frontend.py
index 33fe69269d70adeadcc3291b3fb32cc004cbb832..091493f3063a4d7638e9694e472ef2bad1103908 100644
--- a/server/djrandom/frontend/frontend.py
+++ b/server/djrandom/frontend/frontend.py
@@ -27,6 +27,7 @@ storage_root = None
 searcher = None
 album_images = None
 
+API_KEY_HEADER = 'X-Key'
 USERID_COOKIE = 'USERID'
 
 
@@ -35,12 +36,15 @@ def check_session_before_request():
     # Recover the user id from the long-term cookie, if present,
     # otherwise just generate a new one.
     if 'userid' not in session:
-        if USERID_COOKIE in request.cookies:
+        # Give precedence to X-Key API requests (we can avoid
+        # setting cookies for them).
+        if API_KEY_HEADER in request.headers:
+            session['userid'] = request.headers[API_KEY_HEADER]
+        elif USERID_COOKIE in request.cookies:
             session['userid'] = request.cookies[USERID_COOKIE]
         else:
             session['userid'] = utils.random_token()
             session['_please_save_userid'] = True
-            log.info('created new userid: %s' % session['userid'])
 
 
 @app.after_request
@@ -82,7 +86,6 @@ def song_info_json(sha1):
     mp3 = MP3.query.get(sha1)
     if not mp3:
         abort(404)
-    # Use the mp3.to_dict() data, but add some more things...
     return jsonify(mp3.to_dict())