# Uploading Data

This tutorial will walk you through uploading and downloading data with Parcel so that you can use the Oasis platform for storing and securing the most sensitive data in your application.

# Setup

If you haven't already, you will need to generate a keypair and register a server-side client for your application. You can refer to the Authentication part of Getting Started for more details.

Our API credentials consist of a client ID, which is a string, and a private key, encoded as a JSON web key:

const apiCreds = {
  // Client ID. Replace this with your service client ID, e.g. "C92EAFfH67w4bGkVMjihvkQ"
  clientId: process.env.ACME_SERVICE_CLIENT_ID!,
  // Client key
  privateKey: {
    use: 'sig',
    kty: 'EC',
    crv: 'P-256',
    alg: 'ES256',
    x: 'ej4slEdbZpwYG-4T-WfLHpMBWPf6FItNNGFEHsjdyK4',
    y: 'e4Q4ygapmkxku_olSuc-WhSJaWiNCvuPqIWaOV6P9pE',
    d: '_X2VJCigbOYXOq0ilXATJdh9c2DdaSzZlxXVV6yuCXg',
} as const;

We use these credentials to instantiate the Parcel client:

const parcel = new Parcel(apiCreds);

# Uploading a Document

Pieces of data stored on the Oasis platform are known as documents. When creating new document, you will need to provide two parameters, the raw data itself and then pieces of metadata that describe the document.

  • data is the actual piece of data you are storing and can be a string, Blob, Readable, or Uint8Array. Parcel is backed by an encrypted blob store and does not interpret documents, so you are free to use this however you want; you will just need to be prepared to read back and interpret the document format when you download the document later.

  • details contains document metadata, including the title and tags. Tags are a flexible array of strings meant to help you identify, filter, and query documents later. You should feel free to use these however you wish.

In this example, we will upload a simple string as a document, giving it a title and two tags:

const data = 'Hello private world!';
const documentDetails = { title: 'My first document', tags: ['greeting', 'english'] };
let document: Document;
try {
  document = await parcel.uploadDocument(data, { details: documentDetails, toApp: undefined })
} catch (error: any) {
  console.error('Failed to upload document');
  throw error;

console.log(`Created document ${document.id} with title ${document.details.title}`);

If the document upload is successful, we will get back an ID for the document. We can use this ID to retrieve the document later. Depending on your architecture, you may want to persist this ID to your own backend for easy document retrieval.

# Downloading a Document

Next, we will download and verify the document using the document ID from before.

// Let's download the above document using its ID.
// By default, the document owner can download the data.
const download = parcel.downloadDocument(document.id);
const saver = fs.createWriteStream(`./user_data`);
try {
  await download.pipeTo(saver);
  console.log(`Document ${document.id} has been downloaded to ./user_data`);
} catch (error: any) {
  console.error(`Failed to download document ${document.id}`);
  throw error;

const output = fs.readFileSync('./user_data', 'utf-8');
console.log(`Hey document owner! Here's your data: ${output}\n`);

You should see the string we uploaded previously:

Hey document owner! Here's your data: Hello private world!

Notice that we are able to download the document without any specific access policies. By default, we are the owner of documents we upload, and owners can always access their own documents.

You can view the full example in the Parcel Examples repository.

In the following two tutorials, we will show you how to connect to your users' Oasis accounts and how to manage data that belongs to other identities, like those of your users.