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:
- Task erstellen — Übermitteln Sie Ihr Ausgangsbild, Stil-Bild, Maske und Parameter und erhalten Sie einen
taskId. - 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:
| Kopfzeile | Wert |
|---|---|
APIKEY | your_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 Fehlercode9051zurück. 📄 Siehe Referenz zum Guthabenverbrauch.
| Operation | Abgezogene Guthabeneinheiten |
|---|---|
| Aufgabe zum Ersetzen von Texturen | 3 Guthabeneinheiten |
🖼️ Format des Maskenbilds#
Das Maskenbild definiert den Bereich, auf den die Ersetzung der Textur angewendet werden soll.
Maskenregeln:
| Farbe | Bedeutung |
|---|---|
| ⬛ Schwarz | Bereich, 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:
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
POST /api/v1/textureReplacer/generate
Anforderungsheader
| Kopfzeile | Erforderlich | Beschreibung |
|---|---|---|
APIKEY | ✅ Ja | Ihr API Authentifizierungsschlüssel |
Content-Type | ✅ Ja | application/json |
Anforderungskörper
| Feld | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
imageUrl | string | ✅ Erforderlich | URL des Ausgangsbilds (der Raum/der Szene, auf die die Textur angewendet werden soll) |
styleImageUrl | string | ✅ Erforderlich | URL des Stilreferenz-Bilds, das die Zieltextur oder das -material definiert |
maskUrl | string | ⚠️ Entweder maskUrl oder maskBase64 | URL des Maskenbilds. Schwarze Bereiche erhalten die neue Textur; weiße Bereiche werden erhalten |
maskBase64 | string | ⚠️ Entweder maskUrl oder maskBase64 | Base64-kodiertes Maskenbild (PNG-Format empfohlen). Wird verwendet, wenn Sie kein gehostetes URL bereitstellen können |
prompt | string | ❌ Optional | Zusätzlicher Freitext-Prompt zur weiteren Steuerung der Texturgenerierung |
⚠️ Es muss mindestens eines von
maskUrlodermaskBase64angegeben werden. Bei Angabe beider hatmaskUrlVorrang.
🖼️ 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
# 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();
📤 Antwort#
Erfolgreiche Antwort
{
"code": 0,
"message": "success",
"data": 1234567890123456789
}
| Feld | Typ | Beschreibung |
|---|---|---|
code | integer | 0 zeigt Erfolg an |
message | string | Antwortnachricht |
data | long | Die eindeutige Aufgaben-ID für die Ergebnisabfrage |
2. Aufgabenergebnis abrufen#
Ruft den aktuellen Status und Ausgabe eines zuvor erstellten Texturersetzungs-Tasks ab.
Endpunkt
GET /api/v1/textureReplacer/result
Anforderungsheader
| Kopfzeile | Erforderlich | Beschreibung |
|---|---|---|
APIKEY | ✅ Ja | Ihr API Authentifizierungsschlüssel |
Abfrageparameter
| Parameter | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
taskId | long | ✅ Ja | Die vom Erstellungsendpunkt zurückgegebene Aufgaben-ID |
📥 Anfragebeispiele#
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);
📤 Antwort#
Erfolgreiche Antwort (Aufgabe abgeschlossen)
{
"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)
{
"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)
{
"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
| Feld | Typ | Beschreibung |
|---|---|---|
id | long | Task-eindeutige Kennung |
status | string | Aktueller Aufgabenstatus (siehe Aufgabenstatus) |
waitNumber | integer | Anzahl der vorausgehenden Aufgaben in der Warteschlange (0 bedeutet aktuell in Bearbeitung) |
percentage | integer | Task-Abschlussprozentsatz (0–100) |
input | object | Die ursprünglichen Eingabeparameter des Tasks |
input.imageUrl | string | Ausgangsbild-URL |
input.styleImageUrl | string | Stilreferenz-Bild-URL |
input.maskUrl | string | Maskenbild-URL (falls über maskUrl bereitgestellt) |
input.prompt | string | Zusätzlicher Freitext-Prompt (falls angegeben) |
output | object | Generierungsergebnis (nur verfügbar, wenn status Success ist) |
output.resultUrl | string | URL zum texturersetzten Ergebnisbild |
output.width | integer | Ausgabebreite in Pixeln |
output.height | integer | Ausgabehöhe in Pixeln |
📊 Aufgabenstatus#
| Status | Beschreibung |
|---|---|
Unprocessed | Task wurde erstellt, aber noch nicht gestartet |
Processing | Task wird gerade verarbeitet |
Success | Task erfolgreich abgeschlossen — Ausgabe verfügbar |
Failed | Task aufgrund eines Fehlers fehlgeschlagen |
Alle 3-5 Sekunden abfragen. Siehe API Aufgabenlimit.
❌ Fehlerantworten#
Alle Fehlerantworten haben dieselbe JSON-Struktur:
{
"code": 5002,
"message": "Invalid API Key",
"data": null
}
Fehlercode-Referenz#
| Code | Name | Beschreibung | Empfohlene Maßnahme |
|---|---|---|---|
1001 | FAILED | Anfrage fehlgeschlagen (allgemeiner Fehler) | Überprüfen Sie das message-Feld auf spezifische Fehlerdetails |
1003 | INTERNAL_ERROR | Interner Serverfehler | Nach kurzer Verzögerung erneut versuchen; bei anhaltendem Fehler Support kontaktieren |
1011 | PARAM_ERROR | Fehler in den Anfrag-Parametern — zum Beispiel imageUrl, styleImageUrl oder Maske fehlen | Stellen Sie sicher, dass alle erforderlichen Felder angegeben sind |
5002 | API_KEY_INVALID | Ungültiger oder fehlender API Key | Stellen Sie sicher, dass der APIKEY-Header vorhanden ist und der Wert korrekt ist |
9010 | SCAN_TEXT_ERROR | Freitext-Prompt hat Inhaltsprüfung nicht bestanden | Ändern Sie den Prompt, um sensible oder verbotene Inhalte zu entfernen |
9038 | PROHIBITED_CONTENT | Generiertes Ausgangsbild enthält verbotene Inhalte | Passen Sie Prompt/Stil/Eingaben an und wiederholen |
9051 | COINS_NOT_ENOUGH | Unzureichende Coins / Credits | Laden Sie die Credits Ihres Kontos auf und wiederholen |
📄 Für die vollständige Liste gemeinsamer API Fehlercodes beachten Sie die Fehlercode-Referenz.
