Photo Upload Guide

Learn how to upload interior and exterior photos for AI enhancement.

Overview

Photo uploads use a two-step process: first upload files to get signed URLs, then create your order with those file references. This approach supports files up to 50MB and bypasses serverless limits.

Service Type Requirements

  • exterior: No photos needed - uses public imagery sources automatically
  • interior: Must upload interior photos
  • both: Must upload interior photos; exterior uses public imagery sources

Supported Formats

  • File Types: JPEG (.jpg/.jpeg), PNG, WebP, HEIC (auto-converted)
  • Max File Size: 50MB per photo
  • Recommended Resolution: 2000x1500 pixels or higher
  • Best Practice: Keep individual photos under 5MB for optimal performance

Two-Step Upload Process

Upload interior photos with the same enhancements applied to all:

// Step 1: Create upload session
const sessionResponse = await fetch('https://www.quickhome.ai/api/v1/uploads/sessions', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    serviceType: 'interior',
    files: [
      { role: 'interior', filename: 'living-room.jpg', mimeType: 'image/jpeg' },
      { role: 'interior', filename: 'kitchen.jpg', mimeType: 'image/jpeg' },
      { role: 'interior', filename: 'bedroom.jpg', mimeType: 'image/jpeg' }
    ]
  })
});

const { uploadSessionId, files } = await sessionResponse.json();

// Step 2: Upload each file to storage
for (let i = 0; i < files.length; i++) {
  const file = files[i];
  const fileBlob = [livingRoomFile, kitchenFile, bedroomFile][i];
  
  await fetch(file.uploadUrl, {
    method: 'PUT',
    body: fileBlob,
    headers: { 'Content-Type': file.mimeType }
  });
}

// Step 3: Create order with file references
const orderResponse = await fetch('https://www.quickhome.ai/api/v1/orders', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    address: '266 Dana Point Ave, Ventura, CA 93004, USA',
    serviceType: 'interior',
    uploadSessionId: uploadSessionId,
    interiorPhotos: files.map(f => ({
      filePath: f.storagePath,
      fileName: f.filename,
      index: f.index
    })),
    interiorEnhancements: ['virtual_staging', 'hdr_enhancement']
  })
});

const result = await orderResponse.json();
console.log('Order created:', result.jobId);

Per-Image Enhancement Control

For advanced use cases, specify different enhancements for each photo using photoConfigs:

// Step 1: Create upload session
const sessionResponse = await fetch('https://www.quickhome.ai/api/v1/uploads/sessions', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    serviceType: 'interior',
    files: [
      { role: 'interior', filename: 'empty-living-room.jpg', mimeType: 'image/jpeg' },
      { role: 'interior', filename: 'messy-kitchen.jpg', mimeType: 'image/jpeg' },
      { role: 'interior', filename: 'furnished-bedroom.jpg', mimeType: 'image/jpeg' }
    ]
  })
});

const { uploadSessionId, files } = await sessionResponse.json();

// Step 2: Upload files
await fetch(files[0].uploadUrl, { method: 'PUT', body: emptyLivingRoom });
await fetch(files[1].uploadUrl, { method: 'PUT', body: messyKitchen });
await fetch(files[2].uploadUrl, { method: 'PUT', body: furnishedBedroom });

// Step 3: Create order with per-image enhancements
const photoConfigs = [
  { photoIndex: 0, photoType: 'interior', enhancements: ['virtual_staging'] },
  { photoIndex: 1, photoType: 'interior', enhancements: ['declutter', 'hdr_enhancement'] },
  { photoIndex: 2, photoType: 'interior', enhancements: ['furniture_removal'] }
];

const response = await fetch('https://www.quickhome.ai/api/v1/orders', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    address: '266 Dana Point Ave, Ventura, CA 93004, USA',
    serviceType: 'interior',
    uploadSessionId: uploadSessionId,
    interiorPhotos: files.map(f => ({
      filePath: f.storagePath,
      fileName: f.filename,
      index: f.index
    })),
    photoConfigs: photoConfigs
  })
});

Exterior Photo Upload (Optional)

By default, exterior photos are fetched from public imagery sources. However, you can optionally upload your own professional exterior photos:

// Step 1: Create upload session
const sessionResponse = await fetch('https://www.quickhome.ai/api/v1/uploads/sessions', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    serviceType: 'exterior',
    files: [
      { role: 'exterior', filename: 'front-view.jpg', mimeType: 'image/jpeg' },
      { role: 'exterior', filename: 'side-view.jpg', mimeType: 'image/jpeg' }
    ]
  })
});

const { uploadSessionId, files } = await sessionResponse.json();

// Step 2: Upload files
await fetch(files[0].uploadUrl, { method: 'PUT', body: frontViewFile });
await fetch(files[1].uploadUrl, { method: 'PUT', body: sideViewFile });

// Step 3: Create order
const response = await fetch('https://www.quickhome.ai/api/v1/orders', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    address: '266 Dana Point Ave, Ventura, CA 93004, USA',
    serviceType: 'exterior',
    uploadSessionId: uploadSessionId,
    exteriorPhotos: files.map(f => ({
      filePath: f.storagePath,
      fileName: f.filename,
      index: f.index
    })),
    exteriorEnhancements: ['sky_enhancement', 'grass_enhancement']
  })
});

Browser Upload Example

Example HTML for uploading photos from a browser:

<form id="orderForm">
  <input type="text" id="address" placeholder="Property Address" required />
  
  <select id="serviceType">
    <option value="interior">Interior</option>
    <option value="exterior">Exterior</option>
    <option value="both">Both</option>
  </select>
  
  <input type="file" id="photos" multiple accept="image/jpeg,image/png,image/webp,image/heic" />
  
  <button type="submit">Create Order</button>
</form>

<script>
document.getElementById('orderForm').addEventListener('submit', async (e) => {
  e.preventDefault();
  
  const address = document.getElementById('address').value;
  const serviceType = document.getElementById('serviceType').value;
  const files = Array.from(document.getElementById('photos').files);
  
  // Step 1: Create upload session
  const sessionResponse = await fetch('https://www.quickhome.ai/api/v1/uploads/sessions', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      serviceType: serviceType,
      files: files.map(f => ({
        role: 'interior',
        filename: f.name,
        mimeType: f.type
      }))
    })
  });
  
  const { uploadSessionId, files: uploadFiles } = await sessionResponse.json();
  
  // Step 2: Upload each file
  for (let i = 0; i < files.length; i++) {
    await fetch(uploadFiles[i].uploadUrl, {
      method: 'PUT',
      body: files[i],
      headers: { 'Content-Type': files[i].type }
    });
  }
  
  // Step 3: Create order
  const orderResponse = await fetch('https://www.quickhome.ai/api/v1/orders', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      address: address,
      serviceType: serviceType,
      uploadSessionId: uploadSessionId,
      interiorPhotos: uploadFiles.map(f => ({
        filePath: f.storagePath,
        fileName: f.filename,
        index: f.index
      })),
      interiorEnhancements: ['virtual_staging']
    })
  });
  
  const result = await orderResponse.json();
  console.log('Order created:', result.jobId);
});
</script>

Best Practices

  • • Use high-resolution photos (2000x1500px or higher) for best results
  • • Ensure photos are well-lit and in focus
  • • Upload photos in the correct orientation
  • • For virtual staging, provide empty room photos
  • • For decluttering, capture the full room including clutter
  • • Test with a single photo before batch processing

Next Steps

Quick Home AI | Professional Property Photos