This page covers configuration and management of multipart objects objects.

Object Overview

Multipart Uploads

Endpoint, URL, and Supported Methods

Objects are managed via the storage server API at [http|https]://[hostname]:[port]/v1.0/tenants/[tenant-guid]/buckets/[bucket-guid]/uploads.

By default, the storage server is accessible on port 8001 for the View REST API, and 8002 for the S3-compatible API. Note: storage pools are not manageable via the S3 API.

Supported methods include: GET HEAD PUT DELETE

Structure

Storage pool objects can have one of many structures depending on the type of storage pool. Currently, local disk, Amazon S3, and Azure BLOB storage pools can be configured. For assistance with configuring an Amazon S3 storage pool or an Azure BLOB storage pool, contact support.

A fully populated storage pool using local disk is shown below.:

{
    "GUID": "31a2b7b8-dc22-4e93-ad9d-5bab6d78d81b",
    "TenantGUID": "00000000-0000-0000-0000-000000000000",
    "BucketGUID": "00000000-0000-0000-0000-000000000000",
    "PoolGUID": "00000000-0000-0000-0000-000000000000",
    "NodeGUID": "eb8f61fb-2a01-4edc-974b-fbb79d1a61c8",
    "OwnerGUID": "00000000-0000-0000-0000-000000000000",
    "UploadGUID": "af08c091-c82a-4034-9a49-348850b8e5f8",
    "Key": "foo.txt",
    "StartedUtc": "2025-04-03T09:52:05.002013Z",
    "LastAccessUtc": "2025-04-03T09:52:05.002013Z",
    "CreatedUtc": "2025-04-03T09:52:05.002014Z",
    "ExpirationUtc": "2025-04-10T09:52:05.017974Z",
    "Parts": []
}

Properties:

  • GUID GUID globally unique identifier for the object
  • TenantGUID GUID globally unique identifier for the tenant
  • BucketGUID GUID globally unique identifier for the bucket
  • PoolGUID GUID globally unique identifier for the pool
  • NodeGUID GUID globally unique identifier for the node
  • OwnerGUID GUID globally unique identifier for the owner
  • UploadGUID GUID globally unique identifier for the Upload
  • Key string file name of the object
  • StartedUtc string timestamp from started, in UTC time
  • StartedUtc string timestamp from started, in UTC time
  • CreatedUtc datetime timestamp from creation, in UTC time
  • ExpirationUtc string timestamp from expiration, in UTC time
  • Parts array array of parts

Create

To create, call PUT /v1.0/tenants/[tenant-guid]/buckets/[bucket-guid]/uploads with the properties of the storage pool as defined above, using the storage server.

Note: once a storage pool has been written, it cannot be updated.

curl --location --request PUT 'http://view.homedns.org:8001/v1.0/tenants/00000000-0000-0000-0000-000000000000/buckets/00000000-0000-0000-0000-000000000000/uploads' \
--header 'Content-Type: text/plain' \
--header 'Authorization: ••••••' \
--data '{
    "Key": "foo.txt"
}'
import { ViewStorageSdk } from "view-sdk";

const storage = new ViewStorageSdk(
  "00000000-0000-0000-0000-000000000000", //tenant Id
  "default", //access token
  "http://localhost:8001/" //endpoint
);

const createMultipartUpload = async () => {
  try {
    const response = await storage.createMultipartUpload(
      "00000000-0000-0000-0000-000000000000",
      {
        Key: "hello.txt",
      }
    );
    console.log(response, "Multipart upload created successfully");
  } catch (err) {
    console.log("Error creating multipart upload:", err);
  }
};

createMultipartUpload();

Read

To read an object by key, call GET /v1.0/tenants/[tenant-guid]/buckets/[bucket-guid]/uploads/[key]. If the object exists, it will be returned as a JSON object in the response body. If it does not exist, a 404 will be returned with a NotFound error response.

curl --location 'http://view.homedns.org:8001/v1.0/tenants/00000000-0000-0000-0000-000000000000/buckets/00000000-0000-0000-0000-000000000000/uploads/hello.txt' \
--header 'Authorization: ••••••' \
import { ViewStorageSdk } from "view-sdk";

const storage = new ViewStorageSdk(
  "00000000-0000-0000-0000-000000000000", //tenant Id
  "default", //access token
  "http://localhost:8001/" //endpoint
);

const retrieveMultipartUpload = async () => {
  try {
    const response = await storage.retrieveMultipartUpload(
      "00000000-0000-0000-0000-000000000000",
      "hello.txt"
    );
    console.log(response, "Multipart upload retrieved successfully");
  } catch (err) {
    console.log("Error retrieving multipart upload:", err);
  }
};
retrieveMultipartUpload();

Read all

o read all objects, call GET /v1.0/tenants/[tenant-guid]/pools/buckets/[bucket-guid]/uploads. If the object exists, it will be returned as an array of JSON object in the response body

curl --location --request GET 'http://view.homedns.org:8001/v1.0/tenants/00000000-0000-0000-0000-000000000000/buckets/00000000-0000-0000-0000-000000000000/uploads' \
--header 'Content-Type: text/plain' \
--header 'Authorization: ••••••' \
import { ViewStorageSdk } from "view-sdk";

const storage = new ViewStorageSdk(
  "00000000-0000-0000-0000-000000000000", //tenant Id
  "default", //access token
  "http://localhost:8001/" //endpoint
);

const retrieveMultipartUploads = async () => {
  try {
    const response = await storage.retrieveMultipartUploads(
      "00000000-0000-0000-0000-000000000000"
    );

    console.log(response, "Multipart uploads retrieved successfully");
  } catch (err) {
    console.log("Error retrieving multipart uploads:", err);
  }
};
retrieveMultipartUploads();


Upload Part

To update, call PUT /v1.0/tenants/[tenant-guid]/buckets/[bucket-guid]/uploads/[key]/parts?partNumber=3 with the object properties using the Configuration server

curl --location --request PUT 'http://view.homedns.org:8001/v1.0/tenants/00000000-0000-0000-0000-000000000000/buckets/00000000-0000-0000-0000-000000000000/uploads/hello.txt/parts?partNumber=3' \
--header 'Content-Type: text/plain' \
--header 'Authorization: ••••••' \
--data 'Part 3.'
import { ViewStorageSdk } from "view-sdk";

const storage = new ViewStorageSdk(
  "00000000-0000-0000-0000-000000000000", //tenant Id
  "default", //access token
  "http://localhost:8001/" //endpoint
);

const uploadPartOfMultipartUpload = async () => {
  try {
    const response = await storage.uploadPartOfMultipartUpload(
      "00000000-0000-0000-0000-000000000000",
      "hello.txt",
      1,
      "Hey There"
    );

    console.log(response, "part uploaded successfully");
  } catch (err) {
    console.log("Error uploading part:", err);
  }
};

uploadPartOfMultipartUpload();

Retrieve Part

To update, call GET /v1.0/tenants/[tenant-guid]/buckets/[bucket-guid]/uploads/[key]/parts?partNumber=3 with the object properties using the Configuration server

curl --location 'http://view.homedns.org:8001/v1.0/tenants/00000000-0000-0000-0000-000000000000/buckets/00000000-0000-0000-0000-000000000000/uploads/foo.txt?partNumber=1' \
--header 'Authorization: ••••••' 
import { ViewStorageSdk } from "view-sdk";

const storage = new ViewStorageSdk(
  "00000000-0000-0000-0000-000000000000", //tenant Id
  "default", //access token
  "http://localhost:8001/" //endpoint
);

const retrievePartOfMultipartUpload = async () => {
  try {
    const response = await storage.retrievePartOfMultipartUpload(
      "00000000-0000-0000-0000-000000000000",
      "hello.txt",
      1
    );

    console.log(response, "part retrieved successfully");
  } catch (err) {
    console.log("Error retrieving part:", err);
  }
};

retrievePartOfMultipartUpload();

Delete Part

To delete an object by GUID, call DELETE /v1.0/tenants/[tenant-guid]/buckets/[bucket-guid]/uploads/[key].

curl --location --request DELETE 'http://view.homedns.org:8001/v1.0/tenants/00000000-0000-0000-0000-000000000000/buckets/00000000-0000-0000-0000-000000000000/uploads/foo.txt?partNumber=1' \
--header 'Authorization: ••••••' 
import { ViewStorageSdk } from "view-sdk";

const storage = new ViewStorageSdk(
  "00000000-0000-0000-0000-000000000000", //tenant Id
  "default", //access token
  "http://localhost:8001/" //endpoint
);

const deletePartOfMultipartUpload = async () => {
  try {
    const response = await storage.deletePartOfMultipartUpload(
      "00000000-0000-0000-0000-000000000000",
      "hello.txt",
      1
    );
    console.log(response, "part deleted successfully");
  } catch (err) {
    console.log("Error deleting part:", err);
  }
};
deletePartOfMultipartUpload();

Delete Multipart Upload

To read an object by key, call GET /v1.0/tenants/[tenant-guid]/buckets/[bucket-guid]/uploads/[key]. If the object exists, it will be returned as a JSON object in the response body. If it does not exist, a 404 will be returned with a NotFound error response.

curl --location --request DELETE 'http://view.homedns.org:8001/v1.0/tenants/00000000-0000-0000-0000-000000000000/buckets/00000000-0000-0000-0000-000000000000/uploads/foo.txt' \
--header 'Authorization: ••••••' 
import { ViewStorageSdk } from "view-sdk";

const storage = new ViewStorageSdk(
  "00000000-0000-0000-0000-000000000000", //tenant Id
  "default", //access token
  "http://localhost:8001/" //endpoint
);

const deleteMultipartUpload = async () => {
  try {
    const response = await storage.deleteMultipartUpload(
      "00000000-0000-0000-0000-000000000000",
      "hello.txt"
    );

    console.log(response, "part deleted successfully");
  } catch (err) {
    console.log("Error deleting multipart upload:", err);
  }
};
deleteMultipartUpload();

Complete Multipart Upload

To complete an upload by key, call POST /v1.0/tenants/[tenant-guid]/buckets/[bucket-guid]/uploads/[key]. If the object exists, it will be returned as a JSON object in the response body. If it does not exist, a 404 will be returned with a NotFound error response.

curl --location --request POST 'http://view.homedns.org:8001/v1.0/tenants/00000000-0000-0000-0000-000000000000/buckets/00000000-0000-0000-0000-000000000000/uploads/foo.txt' \
--header 'Authorization: ••••••' 
import { ViewStorageSdk } from "view-sdk";

const storage = new ViewStorageSdk(
  "00000000-0000-0000-0000-000000000000", //tenant Id
  "default", //access token
  "http://localhost:8001/" //endpoint
);

const completeMultipartUpload = async () => {
  try {
    const response = await storage.completeMultipartUpload(
      "00000000-0000-0000-0000-000000000000",
      "hello.txt"
    );

    console.log(response, "multipart upload completed successfully");
  } catch (err) {
    console.log("Error completing multipart upload:", err);
  }
};
completeMultipartUpload();