Skip to main content

POST /api/inpaint-image

Performs inpainting operations on images using AI to either remove unwanted objects or add new ones based on a mask and prompt. This endpoint uses the Qwen Image Edit Inpaint model to make targeted edits.

Authentication

This endpoint requires authentication. Include your session token in the request.

Request Body

imageId
string
required
The ID of the source image to edit. Can be an original upload or a previously processed image.
maskDataUrl
string
required
Base64-encoded data URL of the mask image (PNG format). White pixels indicate areas to edit, black pixels are preserved.
prompt
string
required
Description of what to add or how to fill the masked area. For remove mode, describe how to fill the space (e.g., “clean wall”).
mode
string
default:"remove"
Edit mode: remove to remove objects or add to add objects.
replaceNewerVersions
boolean
default:"false"
If true, deletes any newer versions in the edit history before creating this edit.

Request Example

curl -X POST https://yourdomain.com/api/inpaint-image \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_SESSION_TOKEN" \
  -d '{
    "imageId": "550e8400-e29b-41d4-a716-446655440000",
    "maskDataUrl": "data:image/png;base64,iVBORw0KGgoAAAANS...",
    "prompt": "clean white wall",
    "mode": "remove",
    "replaceNewerVersions": false
  }'
Request (Remove Mode)
{
  "imageId": "550e8400-e29b-41d4-a716-446655440000",
  "maskDataUrl": "data:image/png;base64,iVBORw0KGgoAAAANS...",
  "prompt": "clean white wall",
  "mode": "remove"
}
Request (Add Mode)
{
  "imageId": "550e8400-e29b-41d4-a716-446655440000",
  "maskDataUrl": "data:image/png;base64,iVBORw0KGgoAAAANS...",
  "prompt": "modern gray sofa",
  "mode": "add"
}

Response

success
boolean
Indicates whether the inpainting completed successfully.
resultUrl
string
The URL of the edited image stored in Supabase.
newImageId
string
The ID of the newly created image generation record for this edit.
version
number
The version number of this edit in the history chain.
error
string
Error message if the request failed.
details
string
Additional error details for debugging.

Response Examples

{
  "success": true,
  "resultUrl": "https://storage.supabase.co/workspace/project/result-v2.jpg",
  "newImageId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "version": 2
}
{
  "error": "Inpainting failed",
  "details": "Failed to fetch source image: 404"
}

Status Codes

200
Success
Image edited successfully.
400
Bad Request
Missing required fields (imageId, prompt, or maskDataUrl).
404
Not Found
Source image not found in database.
500
Internal Server Error
Inpainting failed due to AI service error or internal error.

Processing Flow

  1. Validation - Verifies required fields and image existence
  2. Source Selection - Uses result image if available, otherwise original
  3. Image Preparation - Fetches source image and extracts dimensions
  4. Mask Processing - Decodes base64 mask and resizes to match source dimensions
  5. Upload to Fal.ai - Uploads both image and mask to Fal.ai storage
  6. AI Inpainting - Calls Qwen Image Edit Inpaint model
  7. Save Result - Downloads and stores the result in Supabase
  8. Create Version - Creates new image generation record as next version
  9. Update Counts - Updates project’s image counts

Edit Mode Comparison

Remove Mode

Removes objects from the masked area and fills with contextually appropriate content based on the prompt.Example: Remove furniture → prompt: “clean hardwood floor”

Add Mode

Adds new objects to the masked area based on the prompt description.Example: Add furniture → prompt: “modern gray sectional sofa”
Both modes use the same Qwen Image Edit Inpaint model. The prompt determines what appears in the masked area.

Version History

Each inpaint operation creates a new version of the image:
// Original image
{
  id: "image-1",
  version: 1,
  parentId: null,
  originalImageUrl: "original.jpg",
  resultImageUrl: "processed.jpg"
}

// First edit (remove object)
{
  id: "image-2",
  version: 2,
  parentId: "image-1",
  originalImageUrl: "original.jpg",  // Keeps reference to original
  resultImageUrl: "edited-v2.jpg",
  metadata: {
    editedFrom: "image-1",
    editMode: "remove",
    model: "qwen-image-edit-inpaint"
  }
}

// Second edit (add object)
{
  id: "image-3",
  version: 3,
  parentId: "image-1",
  originalImageUrl: "original.jpg",
  resultImageUrl: "edited-v3.jpg",
  metadata: {
    editedFrom: "image-2",
    editMode: "add",
    model: "qwen-image-edit-inpaint"
  }
}

Replace Newer Versions

When editing an older version with replaceNewerVersions: true:
  1. All versions newer than the current one are deleted
  2. The new edit becomes the latest version
  3. Version numbers continue from where they left off
Example: Editing v2 with flag enabled will delete v3, v4, etc., and create a new v3.

Mask Format

The mask must be provided as a base64-encoded PNG data URL:
// Format
"data:image/png;base64,iVBORw0KGgoAAAANS..."

// Mask rules
// - White pixels (255,255,255): Areas to edit
// - Black pixels (0,0,0): Areas to preserve
// - The mask is automatically resized to match source image dimensions

AI Model Configuration

This endpoint uses the Qwen Image Edit Inpaint model:
prompt
string
Description of what to generate in the masked area.
image_url
string
Source image URL (uploaded to Fal.ai storage).
mask_url
string
Mask image URL (uploaded to Fal.ai storage).
output_format
string
default:"jpeg"
Output format for the edited image.

Optional Parameters

The model supports additional parameters (not exposed by default):
  • num_inference_steps (default: 30) - More steps = higher quality
  • guidance_scale (default: 4) - Balance between prompt adherence and quality
  • strength (default: 0.93) - Strength of the noising process
  • seed - For reproducible results
  • negative_prompt - Terms to avoid in generation

Image Processing Details

Mask Resizing

Masks are automatically resized using Sharp:
const resizedMaskBuffer = await sharp(maskBuffer)
  .resize(imageWidth, imageHeight, { fit: 'fill' })
  .png()
  .toBuffer();

Storage Organization

Edited images follow this path structure:
workspace-{workspaceId}/
  project-{projectId}/
    results/
      {uniqueId}.jpg  // Each version has a unique file

Error Handling

Common error scenarios:
Missing mask - Both add and remove modes require a mask.
Invalid mask format - Ensure mask is a valid base64-encoded PNG data URL.
Image not found - Verify the imageId exists and belongs to your workspace.
Fetch failed - Source image must be accessible from the server.

Usage Tips

Remove furniture: Use a broad brush for the mask and prompt like “clean hardwood floor” or “empty room”.
Add furniture: Be specific in your prompt: “modern gray sectional sofa” works better than “sofa”.
Wall repairs: Mask damaged areas and prompt with “clean white wall” or “smooth painted wall”.
Sky replacement: Mask the sky and prompt with “blue sky with white clouds” or “sunset sky”.

Build docs developers (and LLMs) love