Dat Protocol

DEP-0003: HTTP Pinning Service API

Title: DEP-0003: HTTP Pinning Service API

Short Name: 0003-http-pinning-service-api

Type: Standard

Status: Draft (as of 2018-04-18)

Github PR: Draft

Authors: Paul Frazee

Summary

An HTTP API for adding and removing Dat data.

Motivation

Users frequently make use of "pinning services" to keep their Dat data online independently of their personal devices. By specifying a standard API for accessing pinning services, we can integrate interfaces for these services to Dat clients (including the Dat CLI and Beaker Browser). For example, in the Dat CLI, it will be possible to execute commands such as:

dat publish --name myarchive my-pinning-service.com

Service description (PSA) document

Servers should host the PSA service-description document at /.well-known/psa. It may be fetched using a GET request. This document will fit the following schema:

{
  "PSA": 1,
  "title": "My Pinning Service",
  "description": "Keep your Dats online!",
  "links": [{
    "rel": "https://archive.org/services/purl/purl/datprotocol/spec/pinning-service-account-api",
    "title": "User accounts API",
    "href": "/v1/accounts"
  }, {
    "rel": "https://archive.org/services/purl/purl/datprotocol/spec/pinning-service-dats-api",
    "title": "Dat pinning API",
    "href": "/v1/dats"
  }]
}

You can read more about the PSA Service Discovery Protocol.

The PSA document must provide links to two API resources: the User Accounts API, and the Dat Pinning API. These resources should be indicated by the https://archive.org/services/purl/purl/datprotocol/spec/pinning-service-account-api and https://archive.org/services/purl/purl/datprotocol/spec/pinning-service-dats-api rel-types, respectively. (These rel-types will need to be updated with the final URLs for their specifications.) If either API is absent from the PSA document, the service will be rejected.

User accounts API

The user-accounts API should provide the following resources:

POST /login     Create a new session with an existing account.
POST /logout    End a session.
GET  /account   Get information about the account attached to the current session.

POST /login

Create a new session with an existing account.

Request body (JSON). All fields required:

{
  username: String
  password: String
}

Handler should generate a session and return the identifier in the response. Response body (JSON):

{
  sessionToken: String
}

POST /logout

End a session.

Request should include authentication header.

GET /account

Get information about the account attached to the current session.

Request should include authentication header.

Response body (JSON):

{
  username: String, the accounts username (required)
  email: String, the accounts email (optional)
  diskUsage: Number, how much disk space has the user's data taken? (optional)
  diskQuota: Number, how much disk space can the user's data take? (optional)
  updatedAt: Number, the Unix timestamp of the last time the user account was updated (optional)
  createdAt: Number, the Unix timestamp of the last time the user account was updated (optional)
}

If diskQuota is not included or is set to 0, the service is acting as a "registry" and will not host the files.

Dat pinning API

The dat pinning API should provide the following resources:

GET  /            List all Dat data pinned by this account.
POST /add         Add a Dat to this account's list of pins.
POST /remove      Remove a Dat from this account's list of pins.
GET  /item/:key   Get information about a Dat in the account's list of pins.
POST /item/:key   Update information about a Dat in the account's list of pins.

GET /

List all Dat data pinned by this account.

Request should include authentication header.

Response body (JSON):

{
  items: [{
    url: String, dat url
    name: String, optional shortname assigned by the user
    title: String, optional title extracted from the dat's manifest file
    description: String, optional description extracted from the dat's manifest file
    additionalUrls: Array of Strings, optional list of URLs the dat can be accessed at
  }]
}

POST /add

Add a Dat to this account's list of pins.

Request should include authentication header. Request body (JSON):

{
  url: String, required url/key of the dat
  name: String, optional shortname for the archive
  domains: Array of Strings, optional list of domain-names the dat should be made available at
}

POST /remove

Remove a Dat from this account's list of pins.

Request should include authentication header. Request body (JSON):

{
  url: String, required url/key of the dat
}

GET /item/:key

Get information about a Dat in the account's list of pins. Key must be the pubkey of the dat.

Response body (JSON):

{
  url: String, dat url
  name: String, optional shortname assigned by the user
  title: String, optional title extracted from the dat's manifest file
  description: String, optional description extracted from the dat's manifest file
  additionalUrls: Array of Strings, optional list of URLs the dat can be accessed at
}

POST /item/:key

Update information about a Dat in the account's list of pins. Key must be the pubkey of the dat.

Request body (JSON):

{
  name: String, optional shortname for the archive
  domains: Array of Strings, optional list of domain-names the dat should be made available at
}

Authentication

Clients should use the User accounts API to fetch a session token from the service. This token should be included in the Authentication header using the Bearer scheme.

Error responses

All error responses should respond with a JSON body which matches the following schema:

{
  message: String
}

The content of message will be displayed to the user. It should explain the error and, if appropriate, give steps for solving the issue. Other fields may be included in the response.

Rationale and alternatives

Unresolved questions

Changelog