Skip to content

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/upload or digital-assets/version/upload)
    • Supports both new asset uploads and version uploads
    • Normalizes file extensions using normalizeFileExtension utility

S3 Upload API Endpoints ​

JavaScript Files (.js)

  • api/s3.js - S3 upload API endpoints called by Adobe CC Integration Asset Upload API
    • GET /s3/start-upload - Initiates multipart upload session
    • GET /s3/get-upload-url - Generates presigned URL for uploading a part
    • POST /s3/complete-upload - Completes multipart upload session
    • GET /s3/get-signed-url - Generates signed URL for accessing uploaded asset

Utility Functions ​

JavaScript Files (.js)

  • utils/index.js - Contains normalizeFileExtension function
    • 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 upload
  • workspace_id (Number, required) - Workspace ID
  • category_id (Number, optional) - Folder ID for organizing the asset
  • asset_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 file
  • workspaceId (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-upload
  • assetId (Number) - Asset ID from start-upload
  • workspaceId (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 ID
  • workspaceId (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 token
  • Content-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 token
  • Content-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 ​

  1. Authentication Verification

    • Verify user authentication token via GET /user
    • If authentication fails, return error
  2. File Chunking

    • Split file into 10MB chunks
    • Each chunk will be uploaded as a separate part
  3. Initiate Multipart Upload

    • Call GET /s3/start-upload with fileType and workspaceId
    • Receive uploadId and assetId from response
  4. Upload File Parts

    • For each chunk:
      • Get presigned URL via GET /s3/get-upload-url with:
        • PartNumber (1-indexed)
        • UploadId from step 3
        • assetId from step 3
        • workspaceId
      • Upload chunk directly to S3 via PUT <presignedUrl>
        • Set Content-Type header to file MIME type
      • Collect ETag from response headers
      • Store part information (ETag + PartNumber) for completion
  5. Complete Multipart Upload

    • Call POST /s3/complete-upload with:
      • Parts array (ETag + PartNumber for each part)
      • UploadId from step 3
      • assetId from step 3
      • workspaceId
  6. Get Signed URL

    • Call GET /s3/get-signed-url with assetId and workspaceId
    • Receive signedUrl for accessing the uploaded file
  7. Upload Metadata

    • Normalize file extension using normalizeFileExtension utility
    • If asset_id is provided (version upload):
      • Call POST /digital-assets/version/upload with version metadata
    • If asset_id is not provided (new asset):
      • Call POST /digital-assets/upload with asset metadata
    • Include signedUrl as display_file in metadata
  8. Return Response

    • Return asset/version data including:
      • asset_id
      • display_file_name
      • category_id
      • created_at
      • For versions: version and assets_version_id

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 data

Request/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., .jpg not jpg)
  • 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 ​

  1. Chunk Size: Use 10MB chunks for optimal performance
  2. Error Handling: Implement retry logic for failed parts
  3. Progress Tracking: Track upload progress per chunk
  4. Token Management: Ensure tokens are valid before starting upload
  5. Metadata Validation: Validate metadata before uploading to DAM backend
  6. File Extension: Always normalize file extensions for consistency