Skip to content
Robert Schroll edited this page Jan 1, 2021 · 20 revisions

This is the interesting API. The current endpoint host is document-storage-production-dot-remarkable-production.appspot.com, but the Service Discovery should be used to make sure that the right one is used.

All requests should be made with a Bearer authentication header. Input and Output is JSON.

General Item Info

The Storage API uses a JSON object to represent individual file or folder items. These items are passed to and from the calls described below. Not all of the fields are always present or needed.

The items used in the API are similar but not the same as the *.metadata files located on the reMarkable device itself.

{
	"ID": "10280264-2546-4319-a150-0cd02ca69c2d",
	"Version": 2,
	"Message": "",
	"Success": true,
	"BlobURLGet": "",
	"BlobURLGetExpires": "0001-01-01T00:00:00Z",
	"ModifiedClient": "2018-01-24T21:02:59.624624Z",
	"Type": "CollectionType",
	"VissibleName": "Projects",
	"CurrentPage": 0,
	"Bookmarked": false,
	"Parent": "6d6ad886-5d8d-4b3e-aa6f-b05d46d31e83"
}
Field Type Description
ID uuid The unique ID of this object. UUID-4 format. This is always required!
Version integer The item's version counting starts at 1
Message string This is used in API replies to return error messages regarding this item
Success boolean This is used in API replies to signal that an error occurred handling this item (=false)
BlobURLGet string the download URL
BlobURLGetExpires datetime when above URL expires
BlobURLPut string Where the data for the file can be uploaded
BlobURLPutExpires datetime when above URL expires
ModifiedClient datetime The last modified date time as set on the client that created the item
Type type The type of the object. See below for available types
VissibleName string The file's label. Yes, there is a typo in this key.
CurrentPage integer The currently open page, starting at 0
Bookmarked boolean is this bookmarked?
Parent uuid The ID of the parent object or empty if this is a top level object

The Type is sent as string using the following values:

  • DocumentType for Notebooks
  • CollectionType for Folders

datetimes are specified in ISO 8601 format.

Note that all calls accepting items as input, expect an array of items and will alway return a corresponding array of items. However the example PHP implementation will always pass single items (eg. arrays of a single item) to make error handling easier.

Listing Item Information

Method Endpoint Payload Result
GET document-storage/json/2/docs none list of items

This call queries all folders and files available. The reMarkable Tablet stores all files in a totally flat hierarchy and so does the cloud service.

The response is an array of items in no apparent order. You will need to make sense of the hierarchy by inspecting the Parent attribute of each item. Items with an empty Parent attribute are located at the root level.

Response Example

[{
	"ID": "10280264-2546-4319-a150-0cd02ca69c2d",
	"Version": 2,
	"Message": "",
	"Success": true,
	"BlobURLGet": "",
	"BlobURLGetExpires": "0001-01-01T00:00:00Z",
	"ModifiedClient": "2018-01-24T21:02:59.624624Z",
	"Type": "CollectionType",
	"VissibleName": "Projects",
	"CurrentPage": 0,
	"Bookmarked": false,
	"Parent": "6d6ad886-5d8d-4b3e-aa6f-b05d46d31e83"
}]

Optional parameters

Parameter Type Description
doc UUID-4 When this parameter is present only the given document is returned. The result is still an array!
withBlob boolean When any trueish value is passed, the results will contain a valid BlobURLGet attribute that can be used to download the document

Downloading

When you pass the withBlob parameter, you can download the document data from the returned BlobURLGet attribute using a simple GET request.

The data you receive is a Zip-File containing the data described in the reMarkable Wiki namely:

  • {id}.content
  • {id}.pagedata
  • {id}.lines if there are any drawings
  • {id}.pdf if this is a document (not a notebook)
  • {id}.thumbnails/*.jpg Thumbnail files per page

There seems to be no way to download a readymade annotated PDF. You would need to create this yourself by combining the PDF and the lines file.

Uploading a Document

Method Endpoint Payload Result
PUT document-storage/json/2/upload/request list of items list of items

To create a document you have to create an upload request first, then upload the actual data to the returned BlobURLPut. Finally you need to update the metadata to make the entry visible.

You need to create the ID (UUID-4) yourself. The uploaded file data needs to be a zip file as described in the download section. You can omit generating any thumbnails and when generating the .content file it seems to be okay to not have a pageCount attribute and make the transform attribute an empty array.

Newly created elements always need to have a Version of 1!

Payload Example

The following payload creates a new document at the top level.

[{
    "ID": "1dd71dfc-a463-4317-9428-ece0bff128b9",
    "Type": "DocumentType",
    "Version": 1
}]

Response Example

The following example shows the result returned by the API. Please note that not the complete Item MetaData is returned, only the minimal data to identify the new item and the upload URL is contained.

The result contains a BlobURLPut attribute where the actual file content (PDF format) should be sent to using the PUT method.

[{
	"ID": "1dd71dfc-a463-4317-9428-ece0bff128b9",
	"Version": 1,
	"Message": "",
	"Success": true,
	"BlobURLPut": "https://storage.googleapis.com/remarkable-production-document-storage/user-auth0%7C5a68dc51cb30df3877a1d7c4/1dd71dfc-a463-4317-9428-ece0bff128b9?Expires=1517253532\u0026GoogleAccessId=remarkable-production%40appspot.gserviceaccount.com\u0026Signature=RklnAKXYxl6%2FEDXxAj%2B0d8W8IrqymHYeNZoPXEcHTGdjc1F0%2B8jsxsYFC7AVYVYG2yHt3R3ujTaWfaV1fa%2BX1MMjdLEjzsbhDv5F5HW3dJ4OHtllwBMi7HY8pEj%2FIO2c0PkY1vhfNuRriAhhPKVMm3Y17g7vdm%2Bcli90QtIvdh%2FlHfPh8OWhlZ%2BShH5fwEzNH%2Bs5EgUoq2YVqEOzWdPUclSPQGp9PbKQwJuKw7tTynjbfQCV%2FRFrh2zDn%2BK7Pci4CVCMjZCKfFqUThTxVmPEBLHtC%2F2oKWTOL4CQ8FQPtAWIPmL65zm7iGIlmfkTzu9BRpUov86QXds6tpSFSLcAmQ%3D%3D",
	"BlobURLPutExpires": "2018-01-29T19:18:52.854382809Z"
}]

Note that the request PUTing the document should either have no Content-Type header or an empty Content-Type header. Other headers will cause the signature check to fail, resulting in a 403 response.

After the data has been uploaded, you need to do a metadata update as described in the next section to make it visible. There you can also provide a name and last modified date.

:?: how to upload a new version of an existing file?

Updating Meta-Data and creating Folders

Method Endpoint Payload Result
PUT document-storage/json/2/upload/update-status list of items list of items

This call allows you to update the metadata of an existing item. You can use this to move or rename items or to bookmark them.

This call is also used to create folders. When creating a new folder the version needs to start at 1. Creating a folder follows the same rules as creating the metadata for a File Upload.

❓ do you need to pass a complete item? Or just the ID and the attributes you want to change?

❓ what happens if you change the Version?

Deleting an Item

Method Endpoint Payload Result
PUT /document-storage/json/2/delete list of items list of items

This allows for deleting items. It is only needed to pass two attributes: the ID and the Version. The Version needs to match the current version on the server.

❓ is it possible to access/restore earlier versions?

❓ should the actual file content be deleted as well? How?

Payload Example

[{
    "ID": "1dd71dfc-a463-4317-9428-ece0bff128b9",
    "Version": 1
}]