Appearance
Adobe CC Integration Asset Upload ​
Overview & Architecture ​
The Adobe CC Integration Asset Upload system provides a specialized API endpoint (/upload-asset) that enables Adobe Creative Cloud applications to upload digital assets directly to the DAM system. This integration handles multipart chunked file uploads, S3 storage operations, and asset metadata management.
Key Features ​
- Multipart Chunked Uploads: Handles large files by splitting them into 10MB chunks
- S3 Integration: Direct upload to AWS S3 using presigned URLs
- Version Support: Supports both new asset uploads and version uploads
- Token Authentication: Verifies user authentication before processing uploads
- Metadata Management: Uploads asset metadata to DAM backend after file upload completes
File Structure ​
Adobe CC Integration Asset Upload API ​
JavaScript Files (.js)
api/index.js(Lines 39-263) - Adobe CC Integration Asset Upload API (/upload-asset) endpoint implementation- Handles multipart chunked file uploads (10MB chunks)
- Verifies user authentication token
- Initiates S3 multipart upload via
/s3/start-upload - Uploads file parts to S3 via
/s3/get-upload-url - Completes multipart upload via
/s3/complete-upload - Retrieves signed URL via
/s3/get-signed-url - Uploads asset metadata to DAM backend (
digital-assets/uploadordigital-assets/version/upload) - Supports both new asset uploads and version uploads
- Normalizes file extensions using
normalizeFileExtensionutility
S3 Upload API Endpoints ​
JavaScript Files (.js)
api/s3.js- S3 upload API endpoints called by Adobe CC Integration Asset Upload APIGET /s3/start-upload- Initiates multipart upload sessionGET /s3/get-upload-url- Generates presigned URL for uploading a partPOST /s3/complete-upload- Completes multipart upload sessionGET /s3/get-signed-url- Generates signed URL for accessing uploaded asset
Utility Functions ​
JavaScript Files (.js)
utils/index.js- ContainsnormalizeFileExtensionfunction- Used by Adobe CC Integration Asset Upload API
- Normalizes file extensions for consistent handling
- Imported as:
const { normalizeFileExtension } = require('../utils')
API Endpoints ​
Adobe CC Integration Asset Upload Endpoint ​
POST /upload-asset ​
Main endpoint for Adobe CC Integration asset uploads.
Request:
- Method: POST
- Content-Type:
multipart/form-data - Headers:
Authorization: <token>- User authentication token
Body (multipart/form-data):
file(File, required) - File to uploadworkspace_id(Number, required) - Workspace IDcategory_id(Number, optional) - Folder ID for organizing the assetasset_id(Number, optional) - Asset ID for version upload (if uploading a new version)autoTag(Boolean, optional) - Auto-tagging flag for versions
Response:
json
{
"data": {
"code": 200,
"data": {
"asset_id": 123,
"display_file_name": "example.jpg",
"category_id": 456,
"created_at": "2024-01-01T00:00:00Z",
// For version uploads:
"version": 2,
"assets_version_id": 789
}
}
}Internal API Calls (to BASE_URL) ​
The Adobe CC Integration Asset Upload API makes the following internal API calls:
GET /s3/start-upload ​
Initiates multipart upload session.
Parameters:
fileType(String) - MIME type of the fileworkspaceId(Number) - Workspace ID
Returns:
json
{
"uploadId": "multipart-upload-id",
"assetId": 123
}GET /s3/get-upload-url ​
Generates presigned URL for uploading a file part.
Parameters:
PartNumber(Number) - Part number (1-indexed)UploadId(String) - Multipart upload ID from start-uploadassetId(Number) - Asset ID from start-uploadworkspaceId(Number) - Workspace ID
Returns:
json
{
"presignedUrl": "https://s3.amazonaws.com/..."
}PUT <presignedUrl> ​
Uploads file part directly to S3.
Headers:
Content-Type: <fileType>- MIME type of the file part
Response:
- ETag in response headers (used for completing upload)
POST /s3/complete-upload ​
Completes multipart upload session.
Body:
json
{
"Parts": [
{
"ETag": "etag-from-part-upload",
"PartNumber": 1
},
// ... more parts
],
"UploadId": "multipart-upload-id",
"assetId": 123,
"workspaceId": 456
}Returns:
json
{
"success": true,
"location": "s3://bucket/key"
}GET /s3/get-signed-url ​
Generates signed URL for accessing uploaded file.
Parameters:
assetId(Number) - Asset IDworkspaceId(Number) - Workspace ID
Returns:
json
{
"signedUrl": "https://s3.amazonaws.com/...?signature=..."
}External API Calls (to API_BASE_URL) ​
GET /user ​
Verifies user authentication token.
Headers:
Authorization: <token>- User authentication token
Returns:
json
{
"id": 123,
"email": "[email protected]",
// ... user data
}POST /digital-assets/upload ​
Uploads new asset metadata to DAM backend.
Query Parameters:
url_workspace_id=${workspaceId}- Workspace ID
Headers:
Authorization: <token>- User authentication tokenContent-Type: application/json
Body:
json
{
"workspace_id": 456,
"file_name": "example.jpg",
"display_file_name": "Example Image",
"display_file": "https://s3.amazonaws.com/...",
"auto_tag": false,
"mime_type": "image/jpeg",
"file_extension": ".jpg",
"file_size": 1024000,
"category_id": 789
}POST /digital-assets/version/upload ​
Uploads asset version metadata to DAM backend (used when asset_id is provided).
Query Parameters:
url_workspace_id=${workspaceId}- Workspace ID
Headers:
Authorization: <token>- User authentication tokenContent-Type: application/json
Body:
json
{
"asset_id": 123,
"auto_tag": true,
"display_file": "https://s3.amazonaws.com/...",
"display_file_name": "Example Image v2",
"file_extension": ".jpg",
"file_name": "example_v2.jpg",
"file_size": 1024000,
"mime_type": "image/jpeg",
"workspace_id": 456
}Upload Flow ​
Complete Upload Process ​
Authentication Verification
- Verify user authentication token via
GET /user - If authentication fails, return error
- Verify user authentication token via
File Chunking
- Split file into 10MB chunks
- Each chunk will be uploaded as a separate part
Initiate Multipart Upload
- Call
GET /s3/start-uploadwithfileTypeandworkspaceId - Receive
uploadIdandassetIdfrom response
- Call
Upload File Parts
- For each chunk:
- Get presigned URL via
GET /s3/get-upload-urlwith:PartNumber(1-indexed)UploadIdfrom step 3assetIdfrom step 3workspaceId
- Upload chunk directly to S3 via
PUT <presignedUrl>- Set
Content-Typeheader to file MIME type
- Set
- Collect ETag from response headers
- Store part information (ETag + PartNumber) for completion
- Get presigned URL via
- For each chunk:
Complete Multipart Upload
- Call
POST /s3/complete-uploadwith:Partsarray (ETag + PartNumber for each part)UploadIdfrom step 3assetIdfrom step 3workspaceId
- Call
Get Signed URL
- Call
GET /s3/get-signed-urlwithassetIdandworkspaceId - Receive
signedUrlfor accessing the uploaded file
- Call
Upload Metadata
- Normalize file extension using
normalizeFileExtensionutility - If
asset_idis provided (version upload):- Call
POST /digital-assets/version/uploadwith version metadata
- Call
- If
asset_idis not provided (new asset):- Call
POST /digital-assets/uploadwith asset metadata
- Call
- Include
signedUrlasdisplay_filein metadata
- Normalize file extension using
Return Response
- Return asset/version data including:
asset_iddisplay_file_namecategory_idcreated_at- For versions:
versionandassets_version_id
- Return asset/version data including:
Flow Diagram ​
Adobe CC Application
|
v
POST /upload-asset (multipart/form-data)
|
v
[1] GET /user (verify token)
|
v
[2] Split file into 10MB chunks
|
v
[3] GET /s3/start-upload
|--> Returns: uploadId, assetId
|
v
[4] For each chunk:
|--> GET /s3/get-upload-url
| |--> Returns: presignedUrl
| |
|--> PUT <presignedUrl> (upload chunk to S3)
| |--> Returns: ETag
|
v
[5] POST /s3/complete-upload
|--> Body: Parts[], UploadId, assetId, workspaceId
|
v
[6] GET /s3/get-signed-url
|--> Returns: signedUrl
|
v
[7] POST /digital-assets/upload (or /version/upload)
|--> Body: Asset metadata with signedUrl
|
v
[8] Return response with asset dataRequest/Response Examples ​
New Asset Upload Request ​
javascript
// POST /upload-asset
const formData = new FormData()
formData.append('file', fileBlob)
formData.append('workspace_id', 456)
formData.append('category_id', 789)
formData.append('autoTag', false)
fetch('/upload-asset', {
method: 'POST',
headers: {
'Authorization': 'Bearer <token>'
},
body: formData
})Version Upload Request ​
javascript
// POST /upload-asset
const formData = new FormData()
formData.append('file', fileBlob)
formData.append('workspace_id', 456)
formData.append('asset_id', 123) // Existing asset ID
formData.append('autoTag', true)
fetch('/upload-asset', {
method: 'POST',
headers: {
'Authorization': 'Bearer <token>'
},
body: formData
})Success Response ​
json
{
"data": {
"code": 200,
"data": {
"asset_id": 123,
"display_file_name": "example.jpg",
"category_id": 789,
"created_at": "2024-01-01T00:00:00Z"
}
}
}Version Upload Response ​
json
{
"data": {
"code": 200,
"data": {
"asset_id": 123,
"display_file_name": "example_v2.jpg",
"category_id": 789,
"created_at": "2024-01-01T00:00:00Z",
"version": 2,
"assets_version_id": 456
}
}
}Error Handling ​
Authentication Errors ​
If token verification fails:
json
{
"error": "Unauthorized",
"message": "Invalid or expired token"
}Upload Errors ​
If S3 upload fails:
json
{
"error": "Upload failed",
"message": "Failed to upload part to S3"
}Metadata Upload Errors ​
If metadata upload fails:
json
{
"error": "Metadata upload failed",
"message": "Failed to save asset metadata"
}Implementation Details ​
File Chunking ​
- Chunk Size: 10MB (10,485,760 bytes)
- Chunking Logic: Files larger than chunk size are split into multiple parts
- Part Numbering: 1-indexed (first part is PartNumber: 1)
File Extension Normalization ​
The normalizeFileExtension utility ensures consistent file extension handling:
- Converts to lowercase
- Ensures leading dot (e.g.,
.jpgnotjpg) - Handles edge cases and special characters
Multipart Upload Parts ​
Each part in the multipart upload requires:
- PartNumber: Sequential number starting from 1
- ETag: Returned from S3 after uploading the part
- Both are required when completing the upload
Presigned URLs ​
- Presigned URLs are valid for a limited time (typically 1 hour)
- Each part gets its own presigned URL
- URLs are used for direct upload to S3 (bypassing the server)
Signed URLs ​
- Signed URLs provide temporary access to uploaded files
- Used in asset metadata as
display_file - Typically valid for a longer duration than presigned URLs
Integration Points ​
With S3 Storage ​
- Uses AWS S3 multipart upload API
- Direct upload to S3 using presigned URLs
- Efficient for large files (reduces server load)
With DAM Backend ​
- Uploads metadata after file upload completes
- Supports both new assets and versions
- Maintains asset relationships and folder structure
With Authentication System ​
- Verifies user tokens before processing
- Ensures only authenticated users can upload
- Maintains workspace context
Best Practices ​
- Chunk Size: Use 10MB chunks for optimal performance
- Error Handling: Implement retry logic for failed parts
- Progress Tracking: Track upload progress per chunk
- Token Management: Ensure tokens are valid before starting upload
- Metadata Validation: Validate metadata before uploading to DAM backend
- File Extension: Always normalize file extensions for consistency
Related Documentation ​
- Upload Flow - General upload system documentation
- AWS S3 Storage - S3 integration details
- Analytics & Insights - Upload analytics tracking