MakePhotos Docs
Guides

Upload Strategies

Choose the right upload method for your MakePhotos integration — URL, signed upload, or direct upload.

Upload Strategies

MakePhotos accepts images via URL or upload. Choose the right strategy for your use case.

Option 1: Public URL (simplest)

If your images are already hosted publicly, just pass the URL directly:

const result = await client.generate.create({
  imageUrl: 'https://your-cdn.com/products/shoe.jpg',
  type: 'product',
  style: 'studio',
});

No upload step needed. The MakePhotos server fetches the image directly.

Best for: Images already on a CDN, S3, or your own server.

The SDK handles the signed upload flow automatically:

import { readFileSync } from 'fs';

const uploaded = await client.upload.create({
  file: readFileSync('./product.jpg'),
  filename: 'product.jpg',
});

const result = await client.generate.create({
  imageUrl: uploaded.imageUrl,
  type: 'product',
  style: 'studio',
});

Under the hood, the SDK:

  1. Calls GET /api/v1/upload/signed to get Cloudinary upload credentials
  2. Uploads the file directly to Cloudinary (no file size limit)
  3. Returns the Cloudinary URL

Best for: Local files, server-side processing pipelines, any file size.

Option 3: Direct upload API (small files only)

For quick one-off uploads under 4.5MB:

curl -X POST "https://makephotos.ai/api/v1/upload?key=mk_live_..." \
  -F "file=@./small-product.jpg"

Best for: Quick testing, small thumbnails, simple integrations.

Limitation: 4.5MB max due to Vercel serverless body limits. Use signed upload for larger files.

Option 4: Signed upload (manual)

If you're not using the SDK and need to upload large files:

# Step 1: Get signed params
PARAMS=$(curl -s "https://makephotos.ai/api/v1/upload/signed?key=mk_live_...")

# Step 2: Upload to Cloudinary
curl -X POST "https://api.cloudinary.com/v1_1/dy2queuww/image/upload" \
  -F "file=@./large-product.jpg" \
  -F "api_key=$(echo $PARAMS | jq -r '.api_key')" \
  -F "timestamp=$(echo $PARAMS | jq -r '.timestamp')" \
  -F "signature=$(echo $PARAMS | jq -r '.signature')" \
  -F "folder=$(echo $PARAMS | jq -r '.folder')"

Best for: Non-Node.js environments, custom integrations, large files without the SDK.

Comparison

MethodSize limitRequestsComplexitySDK support
Public URLN/A0NoneN/A
SDK uploadNone2 (hidden)LowBuilt-in
Direct upload API~4.5MB1LowN/A
Manual signed uploadNone2MediumN/A

Supported formats

All methods support JPEG, PNG, WebP, and other common image formats supported by Cloudinary.

No credit cost

Uploading images is always free — credits are only consumed during generation and background removal.

On this page