Docs

API Documentation

Furniture Try-On API Documentation

Base URL: https://api.ideal.house
Version: v1
Updated: 2026-03-09


πŸ“– Overview

The Furniture Try-On API allows you to virtually place furniture items into a room scene using AI. You provide a room image and a list of furniture items (each with an image and product ID), and the AI seamlessly composites the furniture into the scene. The workflow is asynchronous and involves two steps:

  1. Create a task β€” Submit your room image and furniture list, then receive a taskId.
  2. Poll for results β€” Use the taskId to query task status and retrieve the generated image.

πŸ“Œ Note: Currently, only creative mode is supported.


πŸ” Authentication

All API requests must be authenticated using an API Key.

Include your API Key in the request header:

HeaderValue
APIKEYyour_api_key_here

⚠️ Keep your API Key secure. Do not expose it in client-side code or public repositories.


πŸ’° Credits Deduction

[!WARNING] πŸͺ™ Credits are deducted based on the selected modelType upon successful task creation. If the task ultimately fails, the deducted credits will be automatically refunded to your account.
Insufficient credits will return error code 9051. πŸ“„ See Credits Deduction Reference.

Model (modelType)Credits Deducted
Base3 credits
Pro10 credits

πŸ“Œ API Endpoints


1. Create Furniture Try-On Task

Creates a new AI furniture try-on task and returns a unique taskId for polling.

Endpoint

POST /api/v1/furnitureTryOn/generate

Request Headers

HeaderRequiredDescription
APIKEYβœ… YesYour API authentication key
Content-Typeβœ… Yesapplication/json

Request Body

FieldTypeRequiredDescription
imageUrlstringβœ… YesURL of the room scene image into which furniture will be placed
furnitureListarrayβœ… YesList of furniture items to place in the scene. Maximum 6 items. See Furniture Item Object
promptstring❌ OptionalCustom text prompt to further guide the placement and styling
modelTypestring❌ OptionalModel quality type. Enum: Base, Pro. Defaults to Base

πŸ›‹οΈ Furniture Item Object

Each item in furnitureList must be an object with the following fields:

FieldTypeRequiredDescription
imageUrlstringβœ… YesURL of the furniture product image (with transparent or clean background recommended)

⚠️ furnitureList can contain a maximum of 6 items.

Example

"furnitureList": [
  {
    "imageUrl": "https://example.com/sofa.png"
  },
  {
    "imageUrl": "https://example.com/table.png"
  }
]

Model Types

ValueDescription
BaseDefault. Balanced speed and quality
ProHigher quality output, slower processing

πŸ“₯ Request Examples

cURL

# Basic request (Base model)
curl -X POST "https://api.ideal.house/api/v1/furnitureTryOn/generate" \
  -H "APIKEY: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "imageUrl": "https://example.com/living-room.jpg",
    "furnitureList": [
      {
        "imageUrl": "https://example.com/sofa.png"
      },
      {
        "imageUrl": "https://example.com/coffee-table.png"
      }
    ],
    "prompt": "modern minimalist style"
  }'

# Pro model
curl -X POST "https://api.ideal.house/api/v1/furnitureTryOn/generate" \
  -H "APIKEY: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "imageUrl": "https://example.com/living-room.jpg",
    "furnitureList": [
      {
        "imageUrl": "https://example.com/sofa.png"
      }
    ],
    "prompt": "Scandinavian interior with warm lighting",
    "modelType": "Pro"
  }'

Java (OkHttp)

import okhttp3.*;
import java.io.IOException;

public class FurnitureTryOnApiExample {

    private static final String BASE_URL = "https://api.ideal.house";
    private static final String API_KEY  = "your_api_key_here";

    public static void main(String[] args) throws IOException {
        OkHttpClient client = new OkHttpClient();

        String requestBody = """
            {
                "imageUrl": "https://example.com/living-room.jpg",
                "furnitureList": [
                    {
                        "imageUrl": "https://example.com/sofa.png"
                    },
                    {
                        "imageUrl": "https://example.com/coffee-table.png"
                    }
                ],
                "prompt": "modern minimalist style",
                "modelType": "Base"
            }
            """;

        Request request = new Request.Builder()
            .url(BASE_URL + "/api/v1/furnitureTryOn/generate")
            .addHeader("APIKEY", API_KEY)
            .addHeader("Content-Type", "application/json")
            .post(RequestBody.create(requestBody, MediaType.parse("application/json")))
            .build();

        try (Response response = client.newCall(request).execute()) {
            System.out.println("Response: " + response.body().string());
        }
    }
}

Python (requests)

import requests

BASE_URL = "https://api.ideal.house"
API_KEY  = "your_api_key_here"

headers = {
    "APIKEY": API_KEY,
    "Content-Type": "application/json"
}

payload = {
    "imageUrl": "https://example.com/living-room.jpg",
    "furnitureList": [
        {
            "imageUrl": "https://example.com/sofa.png"
        },
        {
            "imageUrl": "https://example.com/coffee-table.png"
        }
    ],
    "prompt": "modern minimalist style",
    "modelType": "Base"
}

# Pro model example:
# payload = {
#     "imageUrl": "https://example.com/living-room.jpg",
#     "furnitureList": [
#         {
#             "imageUrl": "https://example.com/sofa.png"
#         }
#     ],
#     "prompt": "Scandinavian interior with warm lighting",
#     "modelType": "Pro"
# }

response = requests.post(
    f"{BASE_URL}/api/v1/furnitureTryOn/generate",
    headers=headers,
    json=payload
)

data = response.json()
task_id = data.get("data")
print(f"Task ID: {task_id}")

Node.js (axios)

const axios = require('axios');

const BASE_URL = 'https://api.ideal.house';
const API_KEY  = 'your_api_key_here';

async function createFurnitureTryOnTask() {
  try {
    const response = await axios.post(
      `${BASE_URL}/api/v1/furnitureTryOn/generate`,
      {
        imageUrl: 'https://example.com/living-room.jpg',
        furnitureList: [
          {
            imageUrl: 'https://example.com/sofa.png'
          },
          {
            imageUrl: 'https://example.com/coffee-table.png'
          }
        ],
        prompt: 'modern minimalist style',
        modelType: 'Base'

        // Pro model:
        // modelType: 'Pro'
      },
      {
        headers: {
          'APIKEY': API_KEY,
          'Content-Type': 'application/json'
        }
      }
    );

    const taskId = response.data.data;
    console.log('Task ID:', taskId);
    return taskId;
  } catch (error) {
    console.error('Error:', error.response?.data || error.message);
  }
}

createFurnitureTryOnTask();

πŸ“€ Response

Success Response

{
  "code": 0,
  "message": "success",
  "data": 1234567890123456789
}
FieldTypeDescription
codeinteger0 indicates success
messagestringResponse message
datalongThe unique task ID for polling results

2. Get Task Result

Retrieves the current status and output of a previously created furniture try-on task.

Endpoint

GET /api/v1/furnitureTryOn/result

Request Headers

HeaderRequiredDescription
APIKEYβœ… YesYour API authentication key

Query Parameters

ParameterTypeRequiredDescription
taskIdlongβœ… YesThe task ID returned from the create task endpoint

πŸ“₯ Request Examples

cURL

curl -X GET "https://api.ideal.house/api/v1/furnitureTryOn/result?taskId=1234567890123456789" \
  -H "APIKEY: your_api_key_here"

Java (OkHttp)

import okhttp3.*;
import java.io.IOException;

public class FurnitureTryOnResultExample {

    private static final String BASE_URL = "https://api.ideal.house";
    private static final String API_KEY  = "your_api_key_here";

    public static void main(String[] args) throws IOException {
        OkHttpClient client = new OkHttpClient();
        long taskId = 1234567890123456789L;

        Request request = new Request.Builder()
            .url(BASE_URL + "/api/v1/furnitureTryOn/result?taskId=" + taskId)
            .addHeader("APIKEY", API_KEY)
            .get()
            .build();

        try (Response response = client.newCall(request).execute()) {
            System.out.println("Response: " + response.body().string());
        }
    }
}

Python (requests)

import requests
import time

BASE_URL = "https://api.ideal.house"
API_KEY  = "your_api_key_here"

headers = {
    "APIKEY": API_KEY
}

task_id = 1234567890123456789

# Poll until task is complete
while True:
    response = requests.get(
        f"{BASE_URL}/api/v1/furnitureTryOn/result",
        headers=headers,
        params={"taskId": task_id}
    )

    data = response.json()
    result = data.get("data", {})
    status = result.get("status")

    print(f"Status: {status}, Progress: {result.get('percentage')}%, Queue: {result.get('waitNumber')}")

    if status in ("Success", "Failed"):
        break

    time.sleep(3)  # Poll every 3 seconds

if status == "Success":
    output = result["output"]
    print("Result URL:", output["resultUrl"])
    print("Matched Items:", output.get("items", []))
else:
    print("Task ended with status:", status)

Node.js (axios)

const axios = require('axios');

const BASE_URL = 'https://api.ideal.house';
const API_KEY  = 'your_api_key_here';

async function pollResult(taskId) {
  const headers = { 'APIKEY': API_KEY };

  while (true) {
    const response = await axios.get(
      `${BASE_URL}/api/v1/furnitureTryOn/result`,
      {
        headers,
        params: { taskId }
      }
    );

    const result = response.data.data;
    const { status, percentage, waitNumber } = result;

    console.log(`Status: ${status} | Progress: ${percentage}% | Queue: ${waitNumber}`);

    if (['Success', 'Failed'].includes(status)) {
      if (status === 'Success') {
        console.log('Result URL:', result.output.resultUrl);
        console.log('Matched Items:', result.output.items);
      } else {
        console.log('Task ended with status:', status);
      }
      break;
    }

    // Wait 3 seconds before next poll
    await new Promise(resolve => setTimeout(resolve, 3000));
  }
}

pollResult(1234567890123456789n);

πŸ“€ Response

Success Response (Task Completed)

{
  "code": 0,
  "message": "success",
  "data": {
    "id": 1234567890123456789,
    "status": "Success",
    "waitNumber": 0,
    "percentage": 100,
    "input": {
      "imageUrl": "https://example.com/living-room.jpg",
      "furnitureList": [
        {
          "imageUrl": "https://example.com/sofa.png"
        },
        {
          "imageUrl": "https://example.com/coffee-table.png"
        }
      ],
      "prompt": "modern minimalist style",
      "modelType": "Base"
    },
    "output": {
      "resultUrl": "https://cdn.ideal.house/output/furniture_try_on_result.jpg",
      "width": 1024,
      "height": 1024
    }
  }
}

Response (Task Processing / In Queue)

{
  "code": 0,
  "message": "success",
  "data": {
    "id": 1234567890123456789,
    "status": "Processing",
    "waitNumber": 1,
    "percentage": 45,
    "input": {
      "imageUrl": "https://example.com/living-room.jpg",
      "furnitureList": [
        {
          "imageUrl": "https://example.com/sofa.png"
        }
      ],
      "prompt": "modern minimalist style",
      "modelType": "Base"
    },
    "output": null
  }
}

Response (Task Failed)

{
  "code": 0,
  "message": "success",
  "data": {
    "id": 1234567890123456789,
    "status": "Failed",
    "waitNumber": 0,
    "percentage": 0,
    "input": {
      "imageUrl": "https://example.com/living-room.jpg",
      "furnitureList": [
        {
          "imageUrl": "https://example.com/sofa.png"
        }
      ],
      "modelType": "Base"
    },
    "output": null
  }
}

Response Fields

FieldTypeDescription
idlongTask unique identifier
statusstringCurrent task status (see Task Status)
waitNumberintegerNumber of tasks ahead in the queue (0 means currently processing)
percentageintegerTask completion percentage (0–100)
inputobjectThe original input parameters of the task
input.imageUrlstringRoom scene image URL
input.furnitureListarrayList of furniture items submitted (max 6 items)
input.furnitureList[].imageUrlstringFurniture product image URL
input.promptstringCustom text prompt (if provided)
input.modelTypestringModel type used
outputobjectGeneration result (only available when status is Success)
output.resultUrlstringURL to the generated room image with furniture placed
output.widthintegerOutput width in pixels
output.heightintegerOutput height in pixels

πŸ“Š Task Status

StatusDescription
UnprocessedTask has been created but not yet started
ProcessingTask is currently being processed
SuccessTask completed successfully β€” output is available
FailedTask failed due to an error

πŸ’‘ Polling Recommendation: Poll the result endpoint every 3–5 seconds. Avoid polling too frequently to prevent rate limiting.


❌ Error Responses

All error responses share the same JSON structure:

{
  "code": 5002,
  "message": "Invalid API Key",
  "data": null
}

Error Code Reference

CodeNameDescriptionSuggested Action
1001FAILEDRequest failed (generic error)Check the message field for specific error details
1003INTERNAL_ERRORInternal server errorRetry after a short delay; contact support if it persists
1011PARAM_ERRORRequest parameter error β€” e.g., imageUrl or furnitureList missing, or furnitureList exceeds 6 itemsEnsure both imageUrl and furnitureList are provided, non-empty, and contain no more than 6 items
5002API_KEY_INVALIDInvalid or missing API KeyEnsure the APIKEY header is present and the value is correct
9010SCAN_TEXT_ERRORText prompt failed content reviewModify the prompt to remove any sensitive or prohibited content
9038PROHIBITED_CONTENTGenerated output image contains prohibited contentAdjust prompt/style/inputs and retry
9051COINS_NOT_ENOUGHInsufficient coins / creditsTop up your account credits and retry

πŸ“„ For the complete list of common API error codes, refer to the Error Code Reference.


β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                                                         β”‚
β”‚  Prepare:                                               β”‚
β”‚    - Room scene image URL (imageUrl) [required]         β”‚
β”‚    - Furniture list with imageUrl (max 6 items) [req'd] β”‚
β”‚    - Optional: prompt, modelType                        β”‚
β”‚                                                         β”‚
β”‚  1. POST /api/v1/furnitureTryOn/generate                β”‚
β”‚     β†’ Receive taskId                                    β”‚
β”‚                                                         β”‚
β”‚  2. Wait 3–5 seconds                                    β”‚
β”‚                                                         β”‚
β”‚  3. GET /api/v1/furnitureTryOn/result?taskId={taskId}   β”‚
β”‚     β†’ Check status field                               β”‚
β”‚                                                         β”‚
β”‚     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚     β”‚ status == "Unprocessed" or "Processing"       β”‚   β”‚
β”‚     β”‚   β†’ waitNumber: position in queue             β”‚   β”‚
β”‚     β”‚   β†’ percentage: current progress              β”‚   β”‚
β”‚     β”‚   β†’ Repeat step 2 & 3                         β”‚   β”‚
β”‚     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                                         β”‚
β”‚     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚     β”‚ status == "Success"                           β”‚   β”‚
β”‚     β”‚   β†’ output.resultUrl: result image            β”‚   β”‚
β”‚     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                                         β”‚
β”‚     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚     β”‚ status == "Failed"                            β”‚   β”‚
β”‚     β”‚   β†’ Handle error accordingly                  β”‚   β”‚
β”‚     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Β© Ideal House AI β€” All rights reserved.