SpiderOak Storage API

The SpiderOak API is separated into two sections: shares and storage. Shares are portions of a user's backup set that they designate as public. As such, shares do not have passwords (for now). Storage is a user's entire backup set, and we need to know the user's password in order to decrypt the tree/file contents. Also, shares are just a set of folders, whereas in storage, we have devices, each with its own set of folders.

IMPORTANT NOTE: Accessing your data remotely through the web is the only instance when your data does become readable; however, these machines are only accessible by a select number of SpiderOak employees. For continued zero-knowledge privacy we only recommend accessing your data through the SpiderOak client, as it downloads the data before decrypting it.

The two sections will be rooted at https://spideroak.com/share/ and https://spideroak.com/storage/respectively ( api_root).

Base32 User/Share IDs

ShareIDs and Usernames in WebAPI URLs are base32-encoded, with the trailing equals signs ("=") removed. For example, the ShareID for my_share_idwould be NV4V643IMFZGKX3JMQ.

Share rooms are identified by a share id and room key. The root for a given share is <api_root>/<b32_share_id>/<room_key>/(note the trailing slash).

A GET request at the share root will return a JSON object with information about the share, and a list of top-level folders contained in the share. For example:

GET /share/NV4V643IMFZGKX3JMQ/my_room_key/ HTTP/1.1
HTTP/1.1 200 OK
Date: Mon, 29 Nov 2010 18:16:10 GMT

{
    stats: {
        start_date: null,
        room_name: "This is the name of the room",
        room_description: "This is a long multiline description of the room",
        number_of_files: <integer number of all files contained in the share>,
        number_of_folders: <integer number of all folders contained in the share>,
        firstname: "the users's first name",
        lastname: "the users's last name"
    },
    dirs: [
        ["display name of folder", "path/to/folder/"]
    ]
}

A folder resource will have a trailing slash, and a GET request will return a list of subfolders and files contained in the directory:

GET /share/NV4V643IMFZGKX3JMQ/my_room_key/path/to/folder/ HTTP/1.1
HTTP/1.1 200 OK
Date: Mon, 29 Nov 2010 18:16:10 GMT

{
    dirs: [
        ["display name of folder", "subfolder/"]
    ],
    files: [
        {
            url: "relative url to download file",
            name: "filename",
            size: <file size in bytes>,
            ctime: <unix timestamp creation time>,
            mtime: <unix timestamp modification time>,
            preview_25: "relative url of 25px file preview, if available",
            preview_48: "relative url of 48px file preview, if available",
            preview_228: "relative url of 228px file preview, if available",
            preview_800: "relative url of 800px file preview, if available",
            versions: <number of historical versions available>
        }
    ]
}

preview_* members

For file objects representing images, there may be preview_* members where *is a number representing the width of the image. If a preview is not available at a given size, that member will not be set in the file object. If there are no previews available for a file, a generic icon should be used.

versions member

See Historical Versions.

Folder zipfiles

A folder can be downloaded as a zip archive by appending a ?format=zipquery string to the folder url. Note that the response will not have a content-length header, as the zip data is generated on the fly.

GET /share/NV4V643IMFZGKX3JMQ/my_room_key/path/to/folder/?format=zip HTTP/1.1
HTTP/1.1 200 OK
Date: Mon, 29 Nov 2010 18:16:10 GMT

<zip data>

Storage

The storage api is mostly the same as the share api with some key differences:

  • The root URL for a user is <api_root>/<b32_username>/
  • Must be logged in (see next section).
  • The root resource, instead of having statsand dirs members will have a devicesmember, which is effectively the same as dirs, except the items represent a user's devices rather than folders.

Logging in

There are two ways to log in.

  • Cookie-based session. Sending a POST request to <api_root>/<b32_username>/loginform-encoded with password=<user's password>will set a session cookie that will allow the other resources to be accessed.
  • HTTP-authentication. Any resource can be accessed with HTTP basic authentication using the user's username and password.

HTTP-auth session login

Any resource can be accessed using standard HTTP basic authentication. Since SpiderOak uses SSL encryption for all web requests, only basic authentication is needed, so digest and other HTTP auth mechanisms are not supported.

GET /storage/NV4V643IMFZGKX3JMQ/ HTTP/1.1
HTTP/1.1 401 Unauthorized
Date: Mon, 29 Nov 2010 18:16:10 GMT
WWW-Authenticate: Basic realm=SpiderOak/my_share_id

When using the cookie-based session login resource, the response to the POST request will be plaintext and start with either ' login:' or ' location:'. If it starts with 'login', the client must repeat the POST request at the URL specified after the colon. If the response starts with 'location', then the URL after the colon is the URL of the SpiderOak web user interface for that user, suitable for opening in the user's web browser directly. For example code that demonstrates logging in, see sidebar.js, remote_login() .

POST /storage/NV4V643IMFZGKX3JMQ/login HTTP/1.1
Content-type: application/x-www-form-urlencoded
Content-length: 20

password=my_password
HTTP/1.1 200 OK
Date: Mon, 29 Nov 2010 18:16:10 GMT
Content-type: text/plain

login:https://spideroak.com/other/login/url

Repeat the request at the new URL:

POST /other/login/url HTTP/1.1
Content-type: application/x-www-form-urlencoded
Content-length: 20

password=my_password
HTTP/1.1 200 OK
Date: Mon, 29 Nov 2010 18:16:10 GMT
Content-type: text/plain
Set-Cookie: spideroak=<hash> Path=/; secure

location:/browse/storage/my_share_id

List of Devices

Listing devices is similar to listing top-level share information as described above.

GET /storage/NV4V643IMFZGKX3JMQ/ HTTP/1.1
HTTP/1.1 200 OK
Date: Mon, 29 Nov 2010 18:16:10 GMT

{
    stats: {
        firstname: "the users's first name",
        lastname: "the users's last name"
        devices: <number of devices>,
        backupsize: "amount of data backed up",
        size: <storage plan size in GB>
    },
    devices: [
        ["display name of device", "url/of/device/"]
    ]
}

You can get extended information on each device by appending ?device_info=yesto the root URL:

GET /storage/NV4V643IMFZGKX3JMQ/?device_info=yes HTTP/1.1
HTTP/1.1 200 OK
Date: Mon, 29 Nov 2010 18:16:10 GMT

{
    stats: {
        firstname: "the users's first name",
        lastname: "the users's last name"
        devices: <number of devices>,
        backupsize: "amount of data backed up",
        size: <storage plan size in GB>
    },
    devices: [
        {
            name: "name of device",
            url: "relative url of device resource",
            lastcommit: <integer unix-style timestamp of last commit on device>,
            lastlogin: <integer unix-style timestamp of last device login>
        },
    ]
}

Historical Versions

SpiderOak stores historical versions of all files a user has backed up. The file objects returned by the folder resource, as outlined above, always represent the most recently backed up version of that file. If the versionsmember is greater than 1, then more versions are available for that file. You can retrieve file objects for past versions by appending ?format=version_infoto the urlmember of the main file object.

For example, if the folder resource returns a file object:

{
    url: "my_file.txt",
    name: "my_file.txt",
    size: 4,
    ctime: 123456343,
    mtime: 123456789,
    preview_800: "my_file.txt?preview_800",
    versions: 2
}

Then to retrieve the version info for that file, you would request my_file.txt?format=version_info:

GET /storage/NV4V643IMFZGKX3JMQ/path/to/my_file.txt?format=version_info HTTP/1.1
HTTP/1.1 200 OK
Date: Mon, 29 Nov 2010 18:16:10 GMT

[
    {
        url: "my_file.txt?version=0",
        name: "my_file.txt",
        size: 0,
        ctime: 123456343,
        mtime: 123456343,
        preview_800: "my_file.txt?version=0&preview_800",
    },
    {
        url: "my_file.txt?version=1",
        name: "my_file.txt",
        size: 4,
        ctime: 123456343,
        mtime: 123456789,
        preview_800: "my_file.txt?version=1&preview_800",
    }
]

To download a particular version of a file, or a preview of a particular version, use the urls contained in the file object for that version.

GET /storage/NV4V643IMFZGKX3JMQ/path/to/my_file.txt?version=1 HTTP/1.1

List of Shares

You can retrieve share room information through the storage section of the API for the logged-in user. A GET request to <api_root>/<b32_username>/shareswill return the user's share id and a list of shares:

GET /storage/NV4V643IMFZGKX3JMQ/shares HTTP/1.1
HTTP/1.1 200 OK
Date: Mon, 29 Nov 2010 18:16:10 GMT

{
    share_id: "<the share_id of the logged in user>",
    share_rooms: [
        {
            url: "https://spideroak.com/browse/share/<share_id>/<room_key>",
            room_key: "<room_key>",
            room_name: "This is the name of the room",
            room_description: "This is a long multiline description of the room",
        },
    ]
}

The urlmember is a friendly URL suitable for inserting in an e-mail or web page link that will take users to that share room's web interface.

Sharing a Single File from Storage

It is now possible to share a file in a user's storage area without that file having to be in a SpiderOak share. This is accomplished by sending a POST request (the postdata can be empty- it is ignored) to the file's download URL. This will return a URL in plain text that can be used for 3 days to download that file. Insert this link into an e-mail message or something to allow others to download the file without having to log in.

POST /storage/NV4V643IMFZGKX3JMQ/path/to/file_name.txt HTTP/1.1
Content-length: 0
HTTP/1.1 200 OK
Date: Mon, 29 Nov 2010 18:16:10 GMT
Content-type: text/plain

https://spideroak.com/storage/NV4V643IMFZGKX3JMQ/shared/1001-1-1001/file_name.txt?<hash>

Extending a Storage Login Session to a 3rd Party

Occasionally it is necessary to allow a 3rd party to retrieve a file from a user's storage without making that file generally available. This method can be used to allow a specified 3rd party IP address access to a specific storage resource for a limited time.

To extend access to a specified resource to a 3rd party, append ?format=session_extension&ip=<ip_addr>to the file's download URL. This will return a string, which you would then append to the original download URL, and send that new URL to the 3rd party to enable them access to the file. For example:

GET /storage/NV4V643IMFZGKX3JMQ/path/to/file_name.txt?format=session_extension&ip=192.168.1.2 HTTP/1.1
HTTP/1.1 200 OK
Date: Mon, 29 Nov 2010 18:16:10 GMT
Content-type: text/plain

<session_extension_hash>

Give the URL https://spideroak.com/storage/NV4V643IMFZGKX3JMQ/path/to/file_name.txt?se=<session_extension_hash> to the user at 192.168.1.2, and they can now use it to access the file.

GET /storage/NV4V643IMFZGKX3JMQ/path/to/file_name.txt?se=<session_extension_hash> HTTP/1.1

Displaying API Data

The SpiderOak web interface uses a custom jQuery treeview widget to display information returned by the API. You can download the treeview code (along with a simple example of usage) on the SpiderOak Code page.