Docs

API Documentation

Texture Replacer API Documentation

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


๐Ÿ“– Overview

The Texture Replacer API allows you to replace the texture or material of a selected area in an image using a style reference image. You provide a source image, a style reference image that defines the target texture/material, and a mask image that specifies the area to apply the new texture. The AI seamlessly blends the new texture into the original scene. The workflow is asynchronous and involves two steps:

  1. Create a task โ€” Submit your source image, style image, mask, and parameters, then receive a taskId.
  2. Poll for results โ€” Use the taskId to query task status and retrieve the result image.

๐Ÿ” 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] ๐Ÿช™ 3 credits are deducted 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.

OperationCredits Deducted
Texture Replacer task3 credits

๐Ÿ–ผ๏ธ Mask Image Format

The mask image defines the area where the texture replacement will be applied.

Mask Rules:

ColorMeaning
โฌ› BlackArea to apply the new texture (region to replace)
โฌœ WhiteArea to preserve (background to keep unchanged)

โš ๏ธ The mask image must match the same dimensions as the source image (imageUrl).

Mask Example:

Mask Example

The black area in the mask defines where the new texture will be applied; the white area is the background to preserve.


๐Ÿ“Œ API Endpoints


1. Create Texture Replacer Task

Creates a new AI texture replacement task and returns a unique taskId for polling.

Endpoint

POST /api/v1/textureReplacer/generate

Request Headers

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

Request Body

FieldTypeRequiredDescription
imageUrlstringโœ… YesURL of the source image (the room/scene to apply texture to)
styleImageUrlstringโœ… YesURL of the style reference image that defines the target texture or material
maskUrlstringโš ๏ธ Either maskUrl or maskBase64URL of the mask image. Black areas will receive the new texture; white areas will be preserved
maskBase64stringโš ๏ธ Either maskUrl or maskBase64Base64-encoded mask image (PNG format recommended). Used when you cannot provide a hosted URL
promptstringโŒ OptionalAdditional text prompt to further guide the texture generation

โš ๏ธ At least one of maskUrl or maskBase64 must be provided. If both are given, maskUrl takes precedence.


๐Ÿ“ฅ Request Examples

cURL

# Using maskUrl
curl -X POST "https://api.ideal.house/api/v1/textureReplacer/generate" \
  -H "APIKEY: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "imageUrl": "https://example.com/room.jpg",
    "styleImageUrl": "https://example.com/marble-texture.jpg",
    "maskUrl": "https://example.com/mask.png"
  }'

# Using maskBase64 with optional prompt
curl -X POST "https://api.ideal.house/api/v1/textureReplacer/generate" \
  -H "APIKEY: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "imageUrl": "https://example.com/room.jpg",
    "styleImageUrl": "https://example.com/wood-texture.jpg",
    "maskBase64": "iVBORw0KGgoAAAANSUhEUgAA...",
    "prompt": "natural oak wood grain texture"
  }'

Java (OkHttp)

import okhttp3.*;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Base64;

public class TextureReplacerApiExample {

    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();

        // Option 1: Use maskUrl
        String requestBody = """
                {
                    "imageUrl": "https://example.com/room.jpg",
                    "styleImageUrl": "https://example.com/marble-texture.jpg",
                    "maskUrl": "https://example.com/mask.png"
                }
                """;

        // Option 2: Use maskBase64 (encode local mask file)
        // byte[] maskBytes = Files.readAllBytes(Path.of("/path/to/mask.png"));
        // String maskBase64 = Base64.getEncoder().encodeToString(maskBytes);
        // String requestBody = """
        //     {
        //         "imageUrl": "https://example.com/room.jpg",
        //         "styleImageUrl": "https://example.com/marble-texture.jpg",
        //         "maskBase64": "%s",
        //         "prompt": "natural oak wood grain texture"
        //     }
        //     """.formatted(maskBase64);

        Request request = new Request.Builder()
                .url(BASE_URL + "/api/v1/textureReplacer/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
import base64

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

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

# Option 1: Use maskUrl
payload = {
    "imageUrl": "https://example.com/room.jpg",
    "styleImageUrl": "https://example.com/marble-texture.jpg",
    "maskUrl": "https://example.com/mask.png"
}

# Option 2: Use maskBase64 with optional prompt
# with open("/path/to/mask.png", "rb") as f:
#     mask_base64 = base64.b64encode(f.read()).decode("utf-8")
# payload = {
#     "imageUrl": "https://example.com/room.jpg",
#     "styleImageUrl": "https://example.com/wood-texture.jpg",
#     "maskBase64": mask_base64,
#     "prompt": "natural oak wood grain texture"
# }

response = requests.post(
    f"{BASE_URL}/api/v1/textureReplacer/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 fs = require('fs');

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

async function createTextureReplacerTask() {
  try {
    // Option 1: Use maskUrl
    const payload = {
      imageUrl: 'https://example.com/room.jpg',
      styleImageUrl: 'https://example.com/marble-texture.jpg',
      maskUrl: 'https://example.com/mask.png'
    };

    // Option 2: Use maskBase64 with optional prompt
    // const maskBuffer = fs.readFileSync('/path/to/mask.png');
    // const maskBase64 = maskBuffer.toString('base64');
    // const payload = {
    //   imageUrl: 'https://example.com/room.jpg',
    //   styleImageUrl: 'https://example.com/wood-texture.jpg',
    //   maskBase64: maskBase64,
    //   prompt: 'natural oak wood grain texture'
    // };

    const response = await axios.post(
      `${BASE_URL}/api/v1/textureReplacer/generate`,
      payload,
      {
        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);
  }
}

createTextureReplacerTask();

๐Ÿ“ค 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 texture replacer task.

Endpoint

GET /api/v1/textureReplacer/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/textureReplacer/result?taskId=1234567890123456789" \
  -H "APIKEY: your_api_key_here"

Java (OkHttp)

import okhttp3.*;

import java.io.IOException;

public class TextureReplacerResultExample {

    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/textureReplacer/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/textureReplacer/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":
    print("Result URL:", result["output"]["resultUrl"])
else:
    print("Task failed")

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/textureReplacer/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('Size:', result.output.width, 'x', result.output.height);
      } else {
        console.log('Task failed');
      }
      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/room.jpg",
      "styleImageUrl": "https://example.com/marble-texture.jpg",
      "maskUrl": "https://example.com/mask.png",
      "prompt": "natural marble texture with grey veining"
    },
    "output": {
      "resultUrl": "https://cdn.ideal.house/output/texture_replacer_result.jpg",
      "width": 1024,
      "height": 1024
    }
  }
}

Response (Task Processing / In Queue)

{
  "code": 0,
  "message": "success",
  "data": {
    "id": 1234567890123456789,
    "status": "Processing",
    "waitNumber": 1,
    "percentage": 50,
    "input": {
      "imageUrl": "https://example.com/room.jpg",
      "styleImageUrl": "https://example.com/marble-texture.jpg",
      "maskUrl": "https://example.com/mask.png"
    },
    "output": null
  }
}

Response (Task Failed)

{
  "code": 0,
  "message": "success",
  "data": {
    "id": 1234567890123456789,
    "status": "Failed",
    "waitNumber": 0,
    "percentage": 0,
    "input": {
      "imageUrl": "https://example.com/room.jpg",
      "styleImageUrl": "https://example.com/marble-texture.jpg",
      "maskUrl": "https://example.com/mask.png"
    },
    "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.imageUrlstringSource image URL
input.styleImageUrlstringStyle reference image URL
input.maskUrlstringMask image URL (if provided via maskUrl)
input.promptstringAdditional text prompt (if provided)
outputobjectGeneration result (only available when status is Success)
output.resultUrlstringURL to the texture-replaced result image
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, styleImageUrl, or mask missingEnsure all required fields are provided
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:                                               โ”‚
โ”‚    - Source image URL (imageUrl) [required]             โ”‚
โ”‚    - Style reference image URL (styleImageUrl) [required]โ”‚
โ”‚    - Mask image: black = apply texture, white = keep    โ”‚
โ”‚      โ†’ Provide as maskUrl or maskBase64 [required]      โ”‚
โ”‚    - prompt: optional text guidance                     โ”‚
โ”‚                                                         โ”‚
โ”‚  1. POST /api/v1/textureReplacer/generate               โ”‚
โ”‚     โ†’ Receive taskId (3 credits deducted)               โ”‚
โ”‚                                                         โ”‚
โ”‚  2. Wait 3โ€“5 seconds                                    โ”‚
โ”‚                                                         โ”‚
โ”‚  3. GET /api/v1/textureReplacer/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: texture-replaced image  โ”‚   โ”‚
โ”‚     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ”‚                                                         โ”‚
โ”‚     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚     โ”‚ status == "Failed"                            โ”‚   โ”‚
โ”‚     โ”‚   โ†’ Handle error accordingly                  โ”‚   โ”‚
โ”‚     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ”‚                                                         โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

ยฉ Ideal House AI โ€” All rights reserved.