Skip to main content
Files are stored securely and can include images, documents, certificates, and other media.
Files are uploaded directly to objects and become part of their permanent record. Maximum file size is 50MB per upload.

Endpoint

curl -X POST "https://api.g2cplatform.com/v2/companies/{COMPANY_ID}/objects/{OBJECT_ID}/files" \
  -H "X-API-Key: YOUR_API_KEY" \
  -F "[email protected]" \
  -F "description=Purchase receipt for laptop" \
  -F "tags=receipt,purchase,warranty"

Request

HTTP Method

POST

URL

https://api.g2cplatform.com/v2/companies/{COMPANY_ID}/objects/{OBJECT_ID}/files

Path Parameters

ParameterTypeRequiredDescription
COMPANY_IDstring (UUID)Company identifier
OBJECT_IDstringObject identifier (UUID or external ID)

Request Body (multipart/form-data)

FieldTypeRequiredDescription
filefileFile to upload (max 50MB)
descriptionstringFile description (max 500 characters)
tagsstringComma-separated tags for categorization

Headers

X-API-Key: YOUR_API_KEY
Content-Type: multipart/form-data

Response

Success Response (201 Created)

{
  "id": "file_7f8a9b2c-4d5e-6f7g-8h9i-0j1k2l3m4n5o",
  "fileName": "receipt_laptop_001.pdf",
  "originalFileName": "document.pdf",
  "mimeType": "application/pdf",
  "size": 245760,
  "description": "Purchase receipt for laptop",
  "tags": ["receipt", "purchase", "warranty"],
  "uploadedAt": "2025-08-03T10:30:00Z",
  "uploadedBy": "api_user",
  "url": "https://api.g2cplatform.com/v2/companies/{COMPANY_ID}/files/file_7f8a9b2c-4d5e-6f7g-8h9i-0j1k2l3m4n5o",
  "checksum": "sha256:a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3"
}

Error Responses

400 Bad Request

{
  "error": "File is required",
  "code": "FILE_REQUIRED",
  "timestamp": "2025-08-03T10:30:00Z"
}

404 Not Found

{
  "error": "Object not found",
  "code": "OBJECT_NOT_FOUND",
  "timestamp": "2025-08-03T10:30:00Z"
}

413 Payload Too Large

{
  "error": "File size exceeds 50MB limit",
  "code": "FILE_TOO_LARGE",
  "timestamp": "2025-08-03T10:30:00Z"
}

415 Unsupported Media Type

{
  "error": "File type not supported",
  "code": "UNSUPPORTED_FILE_TYPE",
  "timestamp": "2025-08-03T10:30:00Z"
}

Implementation Examples

Basic File Upload

async function uploadFile(companyId, objectId, file, metadata = {}) {
  try {
    const formData = new FormData();
    formData.append('file', file);

    if (metadata.description) {
      formData.append('description', metadata.description);
    }

    if (metadata.tags && Array.isArray(metadata.tags)) {
      formData.append('tags', metadata.tags.join(','));
    }

    const response = await fetch(
      `https://api.g2cplatform.com/v2/companies/${companyId}/objects/${objectId}/files`,
      {
        method: 'POST',
        headers: {
          'X-API-Key': process.env.G2C_API_KEY
        },
        body: formData
      }
    );

    if (response.ok) {
      const fileData = await response.json();
      console.log('✅ File uploaded successfully:', fileData.fileName);
      return fileData;
    } else {
      const error = await response.json();
      throw new Error(`File upload failed: ${error.error}`);
    }
  } catch (error) {
    console.error('❌ File upload error:', error.message);
    throw error;
  }
}

// Usage
const fileInput = document.getElementById('file-input');
const file = fileInput.files[0];

const uploadedFile = await uploadFile('company-uuid', 'object-uuid', file, {
  description: 'Equipment manual for CNC machine',
  tags: ['manual', 'documentation', 'equipment']
});

File Upload with Validation

function validateFile(file, maxSize = 50 * 1024 * 1024) { // 50MB default
  const errors = [];

  if (!file) {
    errors.push('File is required');
    return errors;
  }

  if (file.size > maxSize) {
    errors.push(`File size ${(file.size / 1024 / 1024).toFixed(2)}MB exceeds ${maxSize / 1024 / 1024}MB limit`);
  }

  // Check allowed file types
  const allowedTypes = [
    'image/jpeg', 'image/png', 'image/gif', 'image/webp',
    'application/pdf',
    'text/plain', 'text/csv',
    'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
    'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
  ];

  if (!allowedTypes.includes(file.type)) {
    errors.push(`File type ${file.type} is not supported`);
  }

  return errors;
}

async function uploadValidatedFile(companyId, objectId, file, metadata = {}) {
  // Validate file before upload
  const validationErrors = validateFile(file);
  if (validationErrors.length > 0) {
    throw new Error(`Validation failed: ${validationErrors.join(', ')}`);
  }

  const formData = new FormData();
  formData.append('file', file);

  if (metadata.description) {
    formData.append('description', metadata.description);
  }

  if (metadata.tags) {
    const tags = Array.isArray(metadata.tags) ? metadata.tags.join(',') : metadata.tags;
    formData.append('tags', tags);
  }

  const response = await fetch(
    `https://api.g2cplatform.com/v2/companies/${companyId}/objects/${objectId}/files`,
    {
      method: 'POST',
      headers: {
        'X-API-Key': process.env.G2C_API_KEY
      },
      body: formData
    }
  );

  if (!response.ok) {
    const error = await response.json();
    throw new Error(`API Error: ${error.error}`);
  }

  return response.json();
}

Batch File Upload

async function uploadMultipleFiles(companyId, objectId, files, commonMetadata = {}) {
  const results = [];

  for (let i = 0; i < files.length; i++) {
    const file = files[i];

    try {
      const metadata = {
        ...commonMetadata,
        description: `${commonMetadata.description || 'Document'} ${i + 1}/${files.length}`,
        tags: [...(commonMetadata.tags || []), `batch-${Date.now()}`]
      };

      const uploadedFile = await uploadFile(companyId, objectId, file, metadata);
      results.push({ success: true, file: uploadedFile });

      // Add small delay to avoid overwhelming the server
      await new Promise(resolve => setTimeout(resolve, 500));
    } catch (error) {
      results.push({
        success: false,
        fileName: file.name,
        error: error.message
      });
    }
  }

  const successful = results.filter(r => r.success);
  const failed = results.filter(r => !r.success);

  console.log(`✅ Uploaded ${successful.length} files successfully`);
  if (failed.length > 0) {
    console.log(`❌ Failed to upload ${failed.length} files`);
  }

  return { successful, failed };
}

// Usage with file input
const fileInput = document.getElementById('multiple-files');
const files = Array.from(fileInput.files);

const results = await uploadMultipleFiles('company-uuid', 'object-uuid', files, {
  description: 'Asset documentation',
  tags: ['documentation', 'assets']
});

File Upload with Progress Tracking

function uploadFileWithProgress(companyId, objectId, file, metadata = {}, onProgress = null) {
  return new Promise((resolve, reject) => {
    const formData = new FormData();
    formData.append('file', file);

    if (metadata.description) {
      formData.append('description', metadata.description);
    }

    if (metadata.tags) {
      const tags = Array.isArray(metadata.tags) ? metadata.tags.join(',') : metadata.tags;
      formData.append('tags', tags);
    }

    const xhr = new XMLHttpRequest();

    // Track upload progress
    xhr.upload.addEventListener('progress', (event) => {
      if (event.lengthComputable && onProgress) {
        const percentComplete = (event.loaded / event.total) * 100;
        onProgress(percentComplete, event.loaded, event.total);
      }
    });

    xhr.addEventListener('load', () => {
      if (xhr.status === 201) {
        try {
          const result = JSON.parse(xhr.responseText);
          resolve(result);
        } catch (error) {
          reject(new Error('Invalid response format'));
        }
      } else {
        try {
          const error = JSON.parse(xhr.responseText);
          reject(new Error(error.error || 'Upload failed'));
        } catch (e) {
          reject(new Error(`Upload failed with status ${xhr.status}`));
        }
      }
    });

    xhr.addEventListener('error', () => {
      reject(new Error('Network error during upload'));
    });

    xhr.open('POST', `https://api.g2cplatform.com/v2/companies/${companyId}/objects/${objectId}/files`);
    xhr.setRequestHeader('X-API-Key', process.env.G2C_API_KEY);
    xhr.send(formData);
  });
}

// Usage with progress tracking
const file = document.getElementById('file-input').files[0];

try {
  const uploadedFile = await uploadFileWithProgress(
    'company-uuid',
    'object-uuid',
    file,
    {
      description: 'Equipment warranty certificate',
      tags: ['warranty', 'certificate']
    },
    (percent, loaded, total) => {
      console.log(`Upload progress: ${percent.toFixed(1)}% (${loaded}/${total} bytes)`);
      // Update progress bar in UI
      document.getElementById('progress-bar').style.width = `${percent}%`;
    }
  );

  console.log('✅ Upload completed:', uploadedFile);
} catch (error) {
  console.error('❌ Upload failed:', error.message);
}

Use Cases

Asset Documentation

// Upload asset documentation files
class AssetDocumentManager {
  constructor(companyId, apiKey) {
    this.companyId = companyId;
    this.apiKey = apiKey;
  }

  async uploadPurchaseReceipt(objectId, receiptFile) {
    return this.uploadFile(objectId, receiptFile, {
      description: 'Purchase receipt',
      tags: ['receipt', 'purchase', 'financial']
    });
  }

  async uploadWarrantyDocument(objectId, warrantyFile) {
    return this.uploadFile(objectId, warrantyFile, {
      description: 'Warranty certificate',
      tags: ['warranty', 'certificate', 'support']
    });
  }

  async uploadManual(objectId, manualFile) {
    return this.uploadFile(objectId, manualFile, {
      description: 'User manual and documentation',
      tags: ['manual', 'documentation', 'instructions']
    });
  }

  async uploadPhoto(objectId, photoFile, photoType = 'general') {
    return this.uploadFile(objectId, photoFile, {
      description: `Asset photo - ${photoType}`,
      tags: ['photo', 'image', photoType]
    });
  }

  async uploadFile(objectId, file, metadata) {
    const formData = new FormData();
    formData.append('file', file);
    formData.append('description', metadata.description);
    formData.append('tags', metadata.tags.join(','));

    const response = await fetch(
      `https://api.g2cplatform.com/v2/companies/${this.companyId}/objects/${objectId}/files`,
      {
        method: 'POST',
        headers: { 'X-API-Key': this.apiKey },
        body: formData
      }
    );

    if (!response.ok) {
      const error = await response.json();
      throw new Error(error.error);
    }

    return response.json();
  }
}

// Usage
const docManager = new AssetDocumentManager('company-uuid', process.env.G2C_API_KEY);

// Upload various asset documents
await docManager.uploadPurchaseReceipt('laptop-001', receiptFile);
await docManager.uploadWarrantyDocument('laptop-001', warrantyFile);
await docManager.uploadManual('laptop-001', manualFile);
await docManager.uploadPhoto('laptop-001', frontPhotoFile, 'front-view');

Quality Control Documentation

// Upload inspection and quality control files
async function uploadInspectionDocuments(objectId, inspectionData) {
  const uploads = [];

  // Upload inspection report
  if (inspectionData.reportFile) {
    uploads.push(uploadFile(companyId, objectId, inspectionData.reportFile, {
      description: `Quality inspection report - ${inspectionData.date}`,
      tags: ['inspection', 'quality', 'report', inspectionData.inspectorId]
    }));
  }

  // Upload inspection photos
  if (inspectionData.photos && inspectionData.photos.length > 0) {
    inspectionData.photos.forEach((photo, index) => {
      uploads.push(uploadFile(companyId, objectId, photo, {
        description: `Inspection photo ${index + 1} - ${inspectionData.date}`,
        tags: ['inspection', 'photo', 'quality', `photo-${index + 1}`]
      }));
    });
  }

  // Upload test results
  if (inspectionData.testResults) {
    uploads.push(uploadFile(companyId, objectId, inspectionData.testResults, {
      description: `Test results - ${inspectionData.date}`,
      tags: ['testing', 'results', 'quality', 'data']
    }));
  }

  const results = await Promise.allSettled(uploads);

  const successful = results.filter(r => r.status === 'fulfilled').map(r => r.value);
  const failed = results.filter(r => r.status === 'rejected').map(r => r.reason);

  return { successful, failed };
}

Supported File Types

CategoryMIME TypesExtensions
Imagesimage/jpeg, image/png, image/gif, image/webp.jpg, .jpeg, .png, .gif, .webp
Documentsapplication/pdf.pdf
Texttext/plain, text/csv.txt, .csv
Microsoft Officeapplication/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document.doc, .docx
Spreadsheetsapplication/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.xls, .xlsx

Best Practices

  • Use descriptive filenames and descriptions
  • Apply consistent tagging for easy categorization
  • Group related files with common tags
  • Include date and version information when relevant
  • Validate file types before upload
  • Check file sizes to avoid exceeding limits
  • Scan files for malware if required
  • Use HTTPS for all file transfers
  • Compress large files before upload when possible
  • Use batch uploads with delays to avoid rate limiting
  • Implement progress tracking for large files
  • Cache file metadata to reduce API calls
  • Keep track of file checksums for integrity verification
  • Store file IDs for future reference and downloads
  • Implement file versioning strategies
  • Regular cleanup of unnecessary files

Next Steps