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