Skip to main content

Overview

The File Management API allows you to handle file uploads to S3 with automatic user isolation, deduplication, and integrity verification. All files are scoped to individual users, ensuring data privacy and security.

Key Features

  • Direct S3 Uploads: Generate presigned URLs for client-side uploads
  • Automatic Deduplication: MD5-based file detection
  • User Isolation: Files are automatically scoped to authenticated users
  • Integrity Verification: MD5 hash validation
  • Flexible MD5 Format: Accepts both hex and base64 formats

Complete Upload Flow

Here’s a complete example of uploading a file:
1

Calculate MD5 Hash

Calculate the MD5 hash of your file. You can use code or an online MD5 generator:
  • Node.js
  • Online Tool
import crypto from 'crypto';
import fs from 'fs';

const fileBuffer = fs.readFileSync('document.pdf');
const md5Hex = crypto.createHash('md5').update(fileBuffer).digest('hex');
// or base64: .digest('base64')
2

Request Presigned URL

Call the presigned URL endpoint with file metadata:
const response = await fetch('https://production.runalloy.com/2025-09/connectors/files/upload/request', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'x-api-version': '2025-09',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    filename: 'document.pdf',
    mimeType: 'application/pdf',
    md5: md5Hex
  })
});

const { presignedUrl, md5, s3Key, type } = (await response.json()).presignedUrl;
3

Upload to S3

Use the presigned URL to upload directly to S3:
await fetch(presignedUrl, {
  method: 'PUT',
  headers: {
    'Content-Type': 'application/pdf',
    'Content-MD5': md5 // Use the base64 MD5 from step 2
  },
  body: fileBuffer
});
4

Use the File

The file is now stored in S3 and can be referenced by its s3Key in your application.You can verify your uploaded files using the List Files endpoint.

Using s3Key with Connector Actions

You can use the s3Key as file content in connector actions. For example, uploading to Google Drive:
curl --location 'https://production.runalloy.com/connectors/googleDrive/actions/uploadFile/execute' \
--header 'x-api-version: 2025-09' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{token}}' \
--data '{
    "credentialId": "6901cf34fa3f225f1ceaa28c",
    "requestBody": {
        "metadata": {
            "name": "w3img upload",
            "mimeType": "image/jpeg"
        },   
        "s3Key": "651eb6e11d156e0d7a42c76i_w3img.jpg"
    },
    "queryParameters": {
        "uploadType": "multipart"
    }
}'

Security

All files are automatically scoped to the authenticated user. Users cannot access or delete files belonging to other users.

User Isolation

  • List endpoint only returns files for the authenticated user
  • Delete endpoint validates file ownership before deletion

File Validation

  • MD5 verification ensures file integrity
  • S3 validates Content-MD5 header during upload
  • Invalid MD5 results in upload rejection

Best Practices

Use MD5 for Deduplication

Always provide MD5 hashes to avoid uploading duplicate files and verify integrity

Handle Presigned URL Expiry

Presigned URLs expire after 1 hour. Generate a new one if needed

Store S3 Keys

Save the returned s3Key in your database for future reference

Check File Existence

Use the type field to detect if a file already exists before uploading

Limits

FeatureLimit
Presigned URL Expiry1 hour
Maximum File Size5 GB (standard PUT)
S3 Bucketalloy-user-files
File Name Pattern{userId}_{sanitized_filename}.{extension}

FAQs

You can provide MD5 in either hex (32 characters) or base64 (24 characters) format. The system automatically converts hex to base64 if needed.Example:
  • Hex: 2942bfabb3d05332b66eb128e0842cff
  • Base64: KUK/q7PQUzK2brEo4IQs/w==
The system detects duplicate files using MD5 hashes and returns type: "existing". This helps you avoid re-uploading identical files.
For files larger than 5GB, you’ll need to use multipart uploads. Contact support for implementation details.
Use the browser’s native crypto API or libraries like spark-md5:
import SparkMD5 from 'spark-md5';

const spark = new SparkMD5.ArrayBuffer();
const fileReader = new FileReader();

fileReader.onload = (e) => {
  spark.append(e.target.result);
  const md5 = spark.end();
};

fileReader.readAsArrayBuffer(file);
No, files persist until explicitly deleted via the delete endpoint. Implement your own cleanup logic as needed.