Skip to content

Upload files with the MASV API

View as Markdown

Upload files directly to MASV’s private cloud infrastructure using the API.

Be aware of storage expiry when planning your upload workflow:

Files uploaded to MASV belong to a package object — a virtual directory inside of MASV. Each package contains a token that can be used to upload files to that specific virtual directory. A package can be created by interacting with different API endpoints (for example, Portals or Teams).

All requests to upload endpoints require a token passed as an HTTP header, X-Package-Token. This token authorizes the user to add and remove files from the package until the package is finalized.

For each file in the package:

  1. Add file to the package (API action)
  2. Create the file in cloud storage
  3. Collect metadata from cloud storage service
  4. Identify the number of file chunks
  5. Obtain authorized URLs to upload each chunk
  6. Upload all chunks to cloud storage
  7. Collect metadata for each uploaded chunk
  8. After all chunks are uploaded, finalize the file

Then finalize the package.

loop [For each chunk] loop [For each file] Create Package Package ID + access token Add file to Package Create blueprint Create file in cloud storage (blueprint) Upload ID Obtain upload URLs (chunk count) Pre-signed URLs (blueprints) Upload chunk (PUT) ETag Finalize file (ETags + upload ID) File finalized Finalize Package Package finalized — delivery triggered Client MASV API Cloud Storage
Diagram source
sequenceDiagram
participant Client
participant API as MASV API
participant Storage as Cloud Storage
Client->>API: Create Package
API-->>Client: Package ID + access token
loop For each file
Client->>API: Add file to Package
API-->>Client: Create blueprint
Client->>Storage: Create file in cloud storage (blueprint)
Storage-->>Client: Upload ID
Client->>API: Obtain upload URLs (chunk count)
API-->>Client: Pre-signed URLs (blueprints)
loop For each chunk
Client->>Storage: Upload chunk (PUT)
Storage-->>Client: ETag
end
Client->>API: Finalize file (ETags + upload ID)
API-->>Client: File finalized
end
Client->>API: Finalize Package
API-->>Client: Package finalized — delivery triggered

MASV’s API abstracts interactions with cloud storage services by creating a Blueprint object with four properties:

NameTypeDescription
urlStringURL that the request should be forwarded to
methodStringThe HTTP method to use (GET, POST, PUT, DELETE)
headersJSONKey-value map of header names and their values
bodyStringHTTP request body

MASV lets you set the chunk size, which divides larger files into segments for transfer. The default chunk size is 100 MiB, but you can adjust the chunk_size parameter to optimize for speed or reliability.

Storage services like Amazon S3 limit the number and size range for chunks. MASV uses the endpoint https://api.massive.app/v1/system/packages/spec to pass chunk parameters:

ParameterDescription
max_chunk_countMaximum number of chunks permitted (10,000 for S3)
max_chunk_sizeMaximum chunk size in bytes (5 GiB for S3)
min_chunk_sizeMinimum chunk size in bytes (5 MiB for S3)

Each package belongs to either a Team or Portal on MASV. To create a package for a Team, you must provide an API key. To create a package for a Portal, you do not need an API key (but must provide an access code if the Portal requires it).

MethodRoute
POST/teams/{team_id}/packages
NameTypeRequiredDescription
X-API-KEYStringYesAPI key
Content-TypeStringYesMust be application/json
NameTypeRequiredDescription
access_limitIntegerNoOverride default number of downloads
descriptionStringYesDescription of the package
nameStringYesName of the package
passwordStringNoPassword required to download
recipientsString[]YesEmail address of recipient(s)
unlimited_storageBooleanNoEnable unlimited extended storage
chunk_sizeIntegerNoChunk size in bytes for all file uploads in this package
Terminal window
# Store your API key in an environment variable — never hardcode it.
# See /api/api-keys/ for key management best practices.
curl -d '{"access_limit":$ACCESS_LIMIT, "description":"$DESCRIPTION", "name":"$NAME", "password": "$PASSWORD", "recipients":["$RECIPIENT_EMAIL"]}' \
-H "X-API-KEY: $API_KEY" \
-H "Content-Type: application/json" \
-X POST https://api.massive.app/v1/teams/$TEAM_ID/packages

Returns 201 Created with the package object including id and access_token.

MethodRoute
POST/portals/{portal_id}/packages
NameTypeRequiredDescription
Content-TypeStringYesMust be application/json
X-Access-CodeStringNoURI encoded upload password (if required by Portal settings)
NameTypeRequiredDescription
descriptionStringYesDescription of the package
nameStringYesName of the package
senderStringYesEmail address of the Portal package sender
form_data_idStringNo*Form response ID. *Required if the Portal has an enabled custom form.
chunk_sizeIntegerNoChunk size in bytes
MethodRoute
POST/packages/{package_id}/files
NameTypeRequiredDescription
X-Package-TokenStringYesPackage JSON Web Token
Content-TypeStringYesMust be application/json
NameTypeRequiredDescription
kindStringYesType of file: file or directory
nameStringYesFile name
pathStringYesFile’s relative path
last_modifiedStringYesFile’s last modified date (UTC)
sizeIntegerNoFile size in bytes (strongly recommended)
chunk_sizeIntegerNoOverride the package-level chunk size
Terminal window
curl -d '{"kind":"file", "name":"my_video.mpeg", "path": "", "last_modified":"2018-12-17T16:14:34.450Z"}' \
-H "X-Package-Token: $PACKAGE_TOKEN" \
-H "Content-Type: application/json" \
-X POST https://api.massive.app/v1/packages/$PACKAGE_ID/files

Returns 201 Created with create_blueprint and file objects.

Step 3: Create the file in MASV’s cloud storage

Section titled “Step 3: Create the file in MASV’s cloud storage”

Use the create_blueprint from step 2 to construct an HTTP request to the cloud storage service. The response is XML containing an UploadId needed for subsequent steps.

Request pre-signed upload URLs for each of a file’s parts.

MethodRoute
POST/packages/{package_id}/files/{file_id}?start={start}&count={count}
NameTypeRequiredDescription
X-Package-TokenStringYesPackage JSON Web Token
Content-TypeStringYesMust be application/json
NameTypeRequiredDescription
upload_idStringYesID for the initiated multi-part upload
NameTypeRequiredDescription
startIntegerYesStarting index of the chunk (zero-indexed)
countIntegerYesNumber of chunk requests to generate
Terminal window
curl -d '{"upload_id":"$UPLOAD_ID"}' \
-H "X-Package-Token: $PACKAGE_TOKEN" \
-H "Content-Type: application/json" \
-X POST "https://api.massive.app/v1/packages/$PACKAGE_ID/files/$FILE_ID?start=$START&count=$COUNT"

Returns an array of blueprints in ascending order based on the chunk index.

Use each blueprint to upload the corresponding chunk as binary data in the request body.

Terminal window
curl -X PUT "$BLUEPRINT_URL" \
--data-binary @<(dd if=my_video.mpeg skip=0 count=104857600 iflag=skip_bytes,count_bytes)

MASV integrates with PubNub to indicate overall file upload progress on each package.

After all chunks have been uploaded, inform the API that the file upload is complete.

MethodRoute
POST/packages/{package_id}/files/{file_id}/finalize
NameTypeRequiredDescription
X-Package-TokenStringYesPackage JSON Web Token
Content-TypeStringYesMust be application/json
NameTypeRequiredDescription
chunk_extrasObject[]YesInformation about all chunks
chunk_extras[].part_numberStringYesChunk part number
chunk_extras[].etagStringYesChunk part hash
file_extras.upload_idStringYesThe upload ID from step 3
sizeIntegerYesThe file size
chunk_sizeIntegerRecommendedThe chunk size used when uploading
Terminal window
curl -d '{"chunk_extras":[{"part_number":"1","etag":"\"7be1b3cc95a04a6dd07d157ad6fae64a\""}], "file_extras":{"upload_id":"$UPLOAD_ID"}, "size":$FILE_SIZE, "chunk_size":$CHUNK_SIZE}' \
-H "X-Package-Token: $PACKAGE_TOKEN" \
-H "Content-Type: application/json" \
-X POST https://api.massive.app/v1/packages/$PACKAGE_ID/files/$FILE_ID/finalize

Returns 204 No Content.

Each file must match its declared size exactly:

After all files have been uploaded and finalized, indicate that the package is ready to be dispatched.

MethodRoute
POST/packages/{package_id}/finalize
NameTypeRequiredDescription
X-Package-TokenStringYesPackage JSON Web Token
Content-TypeStringYesMust be application/json
Terminal window
curl -H "X-Package-Token: $PACKAGE_TOKEN" \
-H "Content-Type: application/json" \
-X POST https://api.massive.app/v1/packages/$PACKAGE_ID/finalize

Returns 204 No Content.

You can create additional direct-download links or send a link to a specific email recipient after the upload has been finalized. See the Links page for more details.