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