Resources

VNTANA Resource API – Downloading an Asset

API – Downloading an Asset

Admin API Base URL: https://api-platform.vntana.com

Public API Base URL: https://api.vntana.com

For a collection of all Endpoints in our Admin API, view the documentation here. To view the collection of Public Endpoints, view the documentation hereNote: In the following guide and aforementioned documentation, you will see referenced in numerous Endpoints something called a Client. This refers to the workspaces one can create on the Platform within an Organization. The Client nomenclature is a legacy reference being replaced with Workspace.

Another key feature of the VNTANA Platform is the ability to download the Original file that was uploaded as well as the GLB, FBX, and USDZ formatted versions of the Optimized 3D model when applicable. This is possible using both the Admin API and the Public API.

Note: In order to download the thumbnail or associated files, the Asset must be ‘Published’ on the Platform, meaning it is in either the Live Internal or Live Public state.

Downloading File via Admin API

There are two options available for downloading files via the Admin API: direct download and resumable download. Both options will require proper authentication and retrieval of the Asset’s uuid.

As with all endpoints in the Admin API, you must first obtain the appropriate level of authentication by generating a Refresh Token. View this guide to learn more about authentication.

  1. Log in using an Authentication Key or email / password.

    • Returns an x-auth-token in the Response Headers.

  2. Retrieve a list of Organizations and store the needed Organization’s UUID.

    • Pass the x-auth-token from Step 1 in the Request Headers.

      1
      { ‘x-auth-token’ : ‘Bearer ‘ + x_auth_token }
    • This step can be skipped if the Organization UUID is already stored locally.

  3. Generate a Refresh Token for the Organization.

    • Pass the x-auth-token from Step 1 in the Request Headers.

      1
      2
      3
      4
      {
      ‘x-auth-token’ : ‘Bearer ‘ + x_auth_token
      ‘organizationUuid’ : ‘string’
      }
    • Returns the Refresh Token as the Response Header x-auth-token.

  4. Retrieve a list of Workspaces and store the needed UUID.

    • Pass the x-auth-token in the Request Headers.

    • This step can be skipped if the Workspace UUID is already stored locally.

  5. Generate a Refresh Token for the Workspace (Organization Admin / Owner users must skip this step).

    • Pass the Refresh Token from Step 3 in the Request Headers with the Organization and Client UUID’s.

      1
      2
      3
      4
      5
      {
      ‘x-auth-token’ : ‘Bearer ‘ + refreshToken,
      ‘organizationUuid’ : ‘string’,
      ‘clientUuid’ : ‘string’
      }
    • Returns the Refresh Token as the Response Header x-auth-token.

Once Authenticated, you will need to make a request to retrieve the UUID of the Asset(s) you wish to download a file for. If you have the UUID stored locally, this step can be skipped. For more information on how to search for Assets on the Platform, view this guideNote: Assets that are in the Draft state will not be returned in search requests, only those in Live Internal or Live Public.

Use this endpoint to search for an Asset to retrieve its UUID.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Method: POST
Endpoint: /v1/products/clients/search
Headers: { ‘x-auth-token’ : ‘Bearer ‘ + refreshToken }
Request Body: {
‘page’ : 1,
‘size’ : 10,
‘clientUuids’ : [ ‘some-client-uuid’ ],
‘searchTerm’ : ‘string’,
‘organizationUuid’ : ‘some-org-uuid’,
‘tagsUuids’ : [],
‘tagName’ : ‘string’,
‘attributeKey’ : ‘string’,
‘attributeValue’ : ‘string’
}
Resumable Download

The recommended way to download files from Platform is via resumable download. This can be used for more than Assets, but we will focus on this use case in this guide. With resumable download, you can set a range of bytes to download in order to handle large downloads using parallel chunk downloads, or simply resume a download that was stopped by setting the range to continue from where the previous download stopped.

Generating a Signed URL

With the necessary UUID in hand, you will need to generate a Signed URL for the entity. To do this, you can call the following endpoint:

1
2
3
4
5
6
7
8
9
10
11
Method: POST
Endpoint: /v1/storage/download/clients/sign-url
Headers: {
‘x-auth-token’ : ‘Bearer ‘ + refreshToken,
‘Origin’ : ‘https://api-platform.vntana.com’
}
Body: {
‘entityUuid’: ‘string’,
‘storeType’: ‘string’,
‘format’ : ‘string”
}

In the body of the request you will identify the file to download:

  • entityUuid – [REQUIRED] The UUID of the entity. In the case of our Asset example, this will be the assetUuid/productUuid.

  • storeType – [REQUIRED] Indicates what type of stored entity this is. The allowable options are:

    • ASSET – Refers to the original file for an Asset (not optimized formats)

    • MODEL – Refers to an optimized format of an uploaded 3D Asset.

    • ATTACHMENT – Refers to a file that was uploaded to an Asset as an attachment.

    • RENDER – Refers to one of the static renders generated via the Renders tab of an Asset.

    • TURNTABLE – Refers the turntable generated via the Renders tab of an Asset.

  • format – [OPTIONAL] Used when pulling a 3D file, can be FBX | USDZ | GLB | OBJ | STEP.

A successful generation will return the following:

1
2
3
4
5
6
7
8
{
“success”:true,
“errors”:[],
“response”:{
“requestUuid”:”d2db28bb-e015-4037-8961-e05ca127de75″,
“location”:”string”
}
}

where location is the signedUrl to use for downloading.

Downloading from the Signed URL

With the signedUrl in hand, we can now make a GET request to pull the file data:

1
2
3
4
5
Method: GET
URL: {{ signedURL }}
Headers: {
‘Range’: ‘bytes=0-1999’ // Optional
}

The response content can then be streamed elsewhere or written to a file locally. In the headers, we set a Range. This is optional, but can be used to break up the download into chunks, either to do separate chunks in parallel or at different times.

To keep track of what has been downloaded, the response headers from this request can be read for the Content-Range and Content-Length. The above example may show:

1
2
Content-Range: bytes 0-1999/11955
Content-Length: 2000

Going off the above example where we sent Range: bytes=0-1999, we see that the returned number of bytes is 2000 from Content-Length, and that this covered the first 2000 bytes out of a possible 11,955 bytes from Content-Range. Visit this Google reference to learn more about ranges and how to use them.

Resumable Download Postman

A separate Postman collection is available to test out the resumable download process. It includes the authentication steps, but skips the Asset searching. You will need to fill in the required parameters for the body of the request to generate a signed url, but otherwise the collection can be run from authentication to download. Note: In the authentication steps it includes both email and auth key options, as well as client refresh token. Disable what is not needed based on your credentials.

Additional Download Methods

Alternatively, it is possible to download the original asset and optimized model using another method which doesn’t rely on first generating a signed url, but with the tradeoff that you cannot control the download process or resume. 

Starting from the same place with proper authentication and an Asset uuid, you will also need to retrieve the clientUuid if you don’t already have it. You can use the following endpoint to retrieve a list of Workspaces and pull the correct uuidNote: If you have a Webhook configured to notify you of a product.completed event, meaning it has finished Optimization and is ready to be downloaded, the clientUuid will be passed in the payload sent by the Webhook.

The Request structure is as follows:

1
2
3
Method: GET
Endpoint: /v1/clients/client-organizations
Headers: { ‘x-auth-token’ : ‘Bearer ‘ + refreshToken}

The Response structure is as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
“success”: true,
“errors”: [],
“response”: {
“totalCount”: 1,
“grid”: [
{
“uuid”: “string”,
“slug”: “some-client-slug”,
“name”: “Some Client,
“role”: “ORGANIZATION_ADMIN”,
“imageBlobId”: “string”,
“created”: “2020-01-31T19:17:23.972”
}
]
}
}

Important: When dealing with Assets containing 3D files, there are likely multiple formats available for download. To verify the format you wish to download is available, you can retrieve the necessary data from a search request and see the optimized and converted formats in the responses asset -> models section. The models parameter will contain the available formats and each one’s conversionStatus will indicate whether it completed conversion or failed.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
{
“success”: true,
“errors”: [],
“response”: {
“totalCount”: 3,
“grid”: [
{
“uuid”: “”,
“clientUuid”: “string”,
“clientSlug”: “string”,
“name”: “7098_1”,
“locations”: [],
“tags”: [],
“variantGroups”: [],
“status”: “LIVE”,
“conversionStatus”: “COMPLETED”,
“asset”: {
“generationRequestUuid”: “string”,
“thumbnailBlobId”: “string.png”,
“assetBlobId”: “string.glb”,
“assetOriginalName”: “string.glb”,
“assetOriginalSize”: 212247520,
“materialBlobId”: null,
“conversionFormats”: [
“GLB”,
“USDZ”,
“FBX”
],
“models”: [
{
“uuid”: “string”,
“conversionFormat”: “GLB”,
“modelBlobId”: “string.glb”,
“conversionStatus”: “COMPLETED”,
“conversionError”: null,
“modelSize”: 52777040,
“optimizationThreeDComponents”: {},
“originalThreeDComponents”: {}
},
{
“uuid”: “string”,
“conversionFormat”: “USDZ”,
“modelBlobId”: “string.usdz”,
“conversionStatus”: “COMPLETED”,
“conversionError”: null,
“modelSize”: 31200469,
“optimizationThreeDComponents”: {},
“originalThreeDComponents”: {}
},
{
“uuid”: “string”,
“conversionFormat”: “FBX”,
“modelBlobId”: “string.fbx”,
“conversionStatus”: “COMPLETED”,
“conversionError”: null,
“modelSize”: 31200469,
“optimizationThreeDComponents”: {},
“originalThreeDComponents”: {}
}
]
},
“created”: “2022-09-28T22:15:52.729”,
“attributes”: [],
“updated”: “2022-09-28T22:46:45.285679”,
“pipelineUuid”: “2453de9a-ecf5-418e-9e9d-dd0f85adc904”,
“malwareProcessingStatus”: null
}
]
}
}

With the Asset UUID(s) in hand, you can call one of the following endpoints to download the file:

1
2
3
4
5
Method: GET
Endpoint: /v1/products/some-product-uuid/download/asset
Headers: { ‘x-auth-token’ : ‘Bearer ‘ + refreshToken }
Query Params: ‘clientUuid’, ‘version’
Example URL: https://api-platform.vntana.com/v1/products/some-product-uuid/download/asset?clientUuid=some-client-uuid
1
2
3
4
5
Method: GET
Endpoint: /v1/products/some-product-uuid/download/model
Headers: { ‘x-auth-token’ : ‘Bearer ‘ + refreshToken }
Query Params: ‘clientUuid’, ‘version’, ‘conversionFormat’ where conversionFormat can be GLB, FBX, or USDZ
Example URL: https://api-platform.vntana.com/v1/products/some-product-uuid/download/model?clientUuid=some-client-uuid&conversionFormat=GLB

The difference between the two is in the endpoint URL, for the original file you pass asset in the URL and for the optimized you pass model as well as a query parameter for the format (GLB, FBX, or USDZ). The data from the endpoint will need to be streamed into a file and unlike other endpoints that return the data in the Response Body, the entire Response content will simply be the data that needs to be streamed into a file.

Important: If the Asset you are looking to download is a non-3D file, you are simply using the first endpoint /download/asset

Downloading Specific Versions

It is possible to identify the specific version to download by passing the version query parameter to either of the two endpoints. So long as the version exists, it’ll download the requested file associated with it. Leaving the param out will default to return the requested files for the ‘current’ version.

Getting File Name via Content-Disposition

The above GET request will return the Content-Disposition header in the response which will contain the name of the file using the extension of the format you requested be downloaded. The format of the response will be Content-Disposition: ‘attachment; filename=name.glb’, so you can extract the name and even edit it as needed.

Note: It is also possible to call the model endpoint with the blobId in the path, however doing this will change the value of the Content-Disposition header to set the name to the blobId, so it is recommended to not rely on this if you wish to get the name.

Downloading Model via Public API

You can also leverage the Public API to download the Optimized versions of your Assets, as well as the Original. The endpoint will require 4 parameters:

  • productUuid: The UUID of the Asset to download the files for.
  • blobId: The UUID of the converted file, unique for each format (GLB, FBX, or USDZ).
  • organizationSlug: Unique name-based identifier for the Organization.
  • clientSlug: Unique name-based identifier for the Workspace.

The clientSlug and organizationSlug are based on the (original) names of the Workspace and Organization. On the VNTANA Platform, Organization and Workspace names need not be unique, instead a slug is generated based on the originally entered name which is unique. These can be found in the URL of the Workspace or Organization in question. For example: https://platform.vntana.com/some-org-slug/some-client-slug.

The productUuid can be retrieved using the following Public endpoint:

1
2
3
4
5
6
7
8
9
10
11
12
Method: POST
Endpoint: https://api.vntana.com/products/organizations/{organizationSlug}/clients/{clientSlug}
Body: {
“attributeKey” : “string”,
“attributeValue” : “string”,
“page” : 1,
“size” : 10,
“description” : “string”,
“searchTerm” : “string”,
“tagName” : “string”,
“locationName” : “”
}

Note: The base URL of the Public API is different than that of the Admin API.

There are a few different options to filter the results of the search, but only page and size are actually required. This will return the productUuid in the Response body, as well as each formats blobId:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
{
“response”: {
“grid”: [
{
“asset”: {
“assetBlobId”: “string”,
“assetOriginalName”: “string”,
“conversionFormats”: [
“GLB”
],
“models”: [
{
“conversionFormat”: “GLB”,
“modelBlobId”: “string”,
“uuid”: “string”
}
],
“thumbnailBlobId”: “string”
},
“created”: “2022-06-30T15:25:22.031Z”,
“locations”: [
{
“name”: “string”,
“uuid”: “string”
}
],
“name”: “string”,
“tags”: [
{
“name”: “string”,
“uuid”: “string”
}
],
“uuid”: “string”
}
],
“totalCount”: 0
},
“success”: true
}

The blobId is the parameter modelBlobId found in response > grid > asset > models for each conversion format, whereas it’ll be assetBlobId found just in response > grid > asset. With all the necessary parameters, the model can be downloaded using the following endpoint:

1
2
Method: GET
Endpoint: https://api.vntana.com//assets/products/{productUuid}/organizations/{organizationSlug}/clients/{clientSlug}/{blobId}?download=true
Getting File Name via Content-Disposition

It is possible to retrieve the name of the original file that was uploaded to VNTANA with the response of the download GET request. It will be passed in the Content-Disposition header, however it is only returned if you include the download=true query param.

The format of the header will be Content-Disposition: ‘attachment; filename=name.glb’ where the extension will match the extension of the format you are trying to download, not the original files extension.

Postman Collection

To test these endpoints download the below Postman collections, containing examples for both the Public and Admin API processes. To use these collections, simply set the necessary global variables and run the collection as a whole, selecting which endpoints to make use of. If you wish to run each endpoint individually, simply activate the deactivated headers and ensure each endpoint has the necessary data (whether from global variables or directly entered into their endpoint specific locations). You can view our general Postman guide here.

On This Page

Accelerate Your
Digital Transformation

Learn how our platform can automate your 3D process.

Tap the magnifying glass to the left of your screen to search our resources.