Ideal House
Zum Hauptinhalt springen

Dokumentation zur API zum Ersetzen von Texturen#

Basis-URL: https://api.ideal.house
Version: v1
Aktualisiert: 2026-03-25


📖 Übersicht#

Die API zum Ersetzen von Texturen ersetzt Texturen oder Materialien in einem ausgewählten Bildbereich anhand eines Stilreferenzbilds. Sie stellen ein Ausgangsbild, ein Stilreferenzbild für die gewünschte Textur beziehungsweise das Material und ein Maskenbild bereit, das den Bereich für die neue Textur vorgibt. Die KI fügt die Textur nahtlos in die ursprüngliche Szene ein. Der Workflow ist asynchron und umfasst zwei Schritte:

  1. Task erstellen — Übermitteln Sie Ihr Ausgangsbild, Stil-Bild, Maske und Parameter und erhalten Sie einen taskId.
  2. Ergebnisse regelmäßig abfragen — Verwenden Sie die taskId, um den Aufgabenstatus abzufragen und das Ergebnisbild abzurufen.

🔐 Authentifizierung#

Alle API Anfragen müssen mit einem API Key authentifiziert werden.

Fügen Sie Ihren API Key in den Anforderungsheader ein:

KopfzeileWert
APIKEYyour_api_key_here

⚠️ Bewahren Sie Ihren API Key sicher auf. Geben Sie ihn nicht in Client-seitigem Code oder öffentlichen Repositorien frei.


💰 Guthabenverbrauch#

[!WARNING] 🪙 3 Credits werden nach erfolgreicher Task-Erstellung abgezogen. Wenn der Task letztlich fehlschlägt, werden die abgebuchten Credits automatisch erstattet auf Ihr Konto.
Unzureichende Guthabeneinheiten geben Fehlercode 9051 zurück. 📄 Siehe Referenz zum Guthabenverbrauch.

OperationAbgezogene Guthabeneinheiten
Aufgabe zum Ersetzen von Texturen3 Guthabeneinheiten

🖼️ Format des Maskenbilds#

Das Maskenbild definiert den Bereich, auf den die Ersetzung der Textur angewendet werden soll.

Maskenregeln:

FarbeBedeutung
SchwarzBereich, auf den die neue Textur angewendet werden soll (zu ersetzender Bereich)
WeißBereich, der erhalten werden soll (Hintergrund bleibt unverändert)

⚠️ Das Maskenbild muss die gleichen Abmessungen wie das Ausgangsbild (imageUrl) aufweisen.

Maske-Beispiel:

Maske-Beispiel

Der schwarze Bereich in der Maske definiert, wo die neue Textur angewendet wird; der weiße Bereich ist der zu erhaltende Hintergrund.


📌 API Endpunkte#


1. Aufgabe zum Ersetzen von Texturen erstellen#

Erstellt einen neuen AI-Texturersetzungs-Task und gibt eine eindeutige taskId für Abfragen zurück.

Endpunkt

Klartext
POST /api/v1/textureReplacer/generate

Anforderungsheader

KopfzeileErforderlichBeschreibung
APIKEY✅ JaIhr API Authentifizierungsschlüssel
Content-Type✅ Jaapplication/json

Anforderungskörper

FeldTypErforderlichBeschreibung
imageUrlstring✅ ErforderlichURL des Ausgangsbilds (der Raum/der Szene, auf die die Textur angewendet werden soll)
styleImageUrlstring✅ ErforderlichURL des Stilreferenz-Bilds, das die Zieltextur oder das -material definiert
maskUrlstring⚠️ Entweder maskUrl oder maskBase64URL des Maskenbilds. Schwarze Bereiche erhalten die neue Textur; weiße Bereiche werden erhalten
maskBase64string⚠️ Entweder maskUrl oder maskBase64Base64-kodiertes Maskenbild (PNG-Format empfohlen). Wird verwendet, wenn Sie kein gehostetes URL bereitstellen können
promptstring❌ OptionalZusätzlicher Freitext-Prompt zur weiteren Steuerung der Texturgenerierung

⚠️ Es muss mindestens eines von maskUrl oder maskBase64 angegeben werden. Bei Angabe beider hat maskUrl Vorrang.

🖼️ Anforderungen an Bilder: Die Quelldaten-, Stil- und Maskenbilder müssen JPG/JPEG, PNG oder WebP verwenden. Jedes Bild darf höchstens 20 MB groß sein und muss Abmessungen von 128 × 128 px bis zu 6,000 × 6,000 px (einschließlich) haben. Bilder, die die maximalen Pixelabmessungen überschreiten, werden vor der Verarbeitung automatisch proportional verkleinert, um innerhalb von 6,000 × 6,000 px zu passen. Bild-URLs müssen vom API-Server direkt erreichbar sein. Eine Base64-Maske unterliegt denselben Grenzen für dekodierte Bilder und darf kein data-URL-Präfix enthalten.


📥 Anfragebeispiele#

cURL
bash
# 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)
java
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)
python
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)
javascript
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();

📤 Antwort#

Erfolgreiche Antwort

json
{
  "code": 0,
  "message": "success",
  "data": 1234567890123456789
}
FeldTypBeschreibung
codeinteger0 zeigt Erfolg an
messagestringAntwortnachricht
datalongDie eindeutige Aufgaben-ID für die Ergebnisabfrage

2. Aufgabenergebnis abrufen#

Ruft den aktuellen Status und Ausgabe eines zuvor erstellten Texturersetzungs-Tasks ab.

Endpunkt

Klartext
GET /api/v1/textureReplacer/result

Anforderungsheader

KopfzeileErforderlichBeschreibung
APIKEY✅ JaIhr API Authentifizierungsschlüssel

Abfrageparameter

ParameterTypErforderlichBeschreibung
taskIdlong✅ JaDie vom Erstellungsendpunkt zurückgegebene Aufgaben-ID

📥 Anfragebeispiele#

cURL
bash
curl -X GET "https://api.ideal.house/api/v1/textureReplacer/result?taskId=1234567890123456789" \
  -H "APIKEY: your_api_key_here"
Java (OkHttp)
java
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)
python
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)
javascript
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);

📤 Antwort#

Erfolgreiche Antwort (Aufgabe abgeschlossen)

json
{
  "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
    }
  }
}

Antwort (Aufgabe in Bearbeitung / in Warteschlange)

json
{
  "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
  }
}

Antwort (Aufgabe fehlgeschlagen)

json
{
  "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
  }
}

Antwortfelder

FeldTypBeschreibung
idlongTask-eindeutige Kennung
statusstringAktueller Aufgabenstatus (siehe Aufgabenstatus)
waitNumberintegerAnzahl der vorausgehenden Aufgaben in der Warteschlange (0 bedeutet aktuell in Bearbeitung)
percentageintegerTask-Abschlussprozentsatz (0–100)
inputobjectDie ursprünglichen Eingabeparameter des Tasks
input.imageUrlstringAusgangsbild-URL
input.styleImageUrlstringStilreferenz-Bild-URL
input.maskUrlstringMaskenbild-URL (falls über maskUrl bereitgestellt)
input.promptstringZusätzlicher Freitext-Prompt (falls angegeben)
outputobjectGenerierungsergebnis (nur verfügbar, wenn status Success ist)
output.resultUrlstringURL zum texturersetzten Ergebnisbild
output.widthintegerAusgabebreite in Pixeln
output.heightintegerAusgabehöhe in Pixeln

📊 Aufgabenstatus#

StatusBeschreibung
UnprocessedTask wurde erstellt, aber noch nicht gestartet
ProcessingTask wird gerade verarbeitet
SuccessTask erfolgreich abgeschlossen — Ausgabe verfügbar
FailedTask aufgrund eines Fehlers fehlgeschlagen

Alle 3-5 Sekunden abfragen. Siehe API Aufgabenlimit.


❌ Fehlerantworten#

Alle Fehlerantworten haben dieselbe JSON-Struktur:

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

Fehlercode-Referenz#

CodeNameBeschreibungEmpfohlene Maßnahme
1001FAILEDAnfrage fehlgeschlagen (allgemeiner Fehler)Überprüfen Sie das message-Feld auf spezifische Fehlerdetails
1003INTERNAL_ERRORInterner ServerfehlerNach kurzer Verzögerung erneut versuchen; bei anhaltendem Fehler Support kontaktieren
1011PARAM_ERRORFehler in den Anfrag-Parametern — zum Beispiel imageUrl, styleImageUrl oder Maske fehlenStellen Sie sicher, dass alle erforderlichen Felder angegeben sind
5002API_KEY_INVALIDUngültiger oder fehlender API KeyStellen Sie sicher, dass der APIKEY-Header vorhanden ist und der Wert korrekt ist
9010SCAN_TEXT_ERRORFreitext-Prompt hat Inhaltsprüfung nicht bestandenÄndern Sie den Prompt, um sensible oder verbotene Inhalte zu entfernen
9038PROHIBITED_CONTENTGeneriertes Ausgangsbild enthält verbotene InhaltePassen Sie Prompt/Stil/Eingaben an und wiederholen
9051COINS_NOT_ENOUGHUnzureichende Coins / CreditsLaden Sie die Credits Ihres Kontos auf und wiederholen

📄 Für die vollständige Liste gemeinsamer API Fehlercodes beachten Sie die Fehlercode-Referenz.