Documentatie voor de API voor textuurvervanging#
Basis-URL:
https://api.ideal.house
Versie: v1
Bijgewerkt: 2026-03-25
📖 Overzicht#
Met de API voor textuurvervanging kun je de textuur of het materiaal van een geselecteerd gebied in een afbeelding vervangen met een stijlreferentiebeeld. Je levert een bronafbeelding, een stijlreferentiebeeld dat de gewenste textuur of het materiaal bepaalt en een maskerafbeelding die het gebied voor de nieuwe textuur aangeeft. De AI verwerkt de nieuwe textuur naadloos in de oorspronkelijke scène. De werkstroom is asynchroon en bestaat uit twee stappen:
- Een taak aanmaken — Dien je bronafbeelding, stijlbeeld, masker en parameters in en ontvang een
taskId. - Resultaten regelmatig opvragen — Gebruik de
taskIdom de taakstatus op te vragen en de resultaatafbeelding op te halen.
🔐 Authenticatie#
Alle API-verzoeken moeten worden geauthenticeerd met een API Key.
Neem je API Key op in de verzoekheader:
| Verzoekheader | Waarde |
|---|---|
APIKEY | your_api_key_here |
⚠️ Houd je API Key geheim. Maak deze niet zichtbaar in clientcode of openbare opslagplaatsen.
💰 Creditafschrijving#
[!WARNING] 🪙 Bij het succesvol aanmaken van een taak worden 3 tegoedeenheden afgeschreven. Als de taak uiteindelijk mislukt, worden de afgeschreven credits automatisch terugbetaald op je account.
Onvoldoende credits leveren foutcode9051op. 📄 Zie de referentie voor creditafschrijving.
| Bewerking | Afgeschreven credits |
|---|---|
| Taak voor textuurvervanging | 3 tegoedeenheden |
🖼️ Formaat van de maskerafbeelding#
De maskerafbeelding bepaalt het gebied waar de textuur wordt vervangen.
Maskerregels:
| Kleur | Betekenis |
|---|---|
| ⬛ Zwart | Gebied voor de nieuwe textuur: het te vervangen gebied |
| ⬜ Wit | Gebied om te behouden: de achtergrond die ongewijzigd blijft |
⚠️ De maskerafbeelding moet dezelfde afmetingen hebben als de bronafbeelding (
imageUrl).
Maskervoorbeeld:
Het zwarte gebied in het masker bepaalt waar de nieuwe textuur wordt toegepast; het witte gebied is de achtergrond die behouden blijft.
📌 API-endpoints#
1. Een taak voor textuurvervanging aanmaken#
Maakt een nieuwe AI-taak voor textuurvervanging aan en retourneert een unieke taskId om de status regelmatig op te vragen.
Eindpunt
POST /api/v1/textureReplacer/generate
Verzoekheaders
| Verzoekheader | Verplicht | Beschrijving |
|---|---|---|
APIKEY | ✅ Ja | Je API-authenticatiesleutel |
Content-Type | ✅ Ja | application/json |
Verzoekinhoud
| Veld | Type | Verplicht | Beschrijving |
|---|---|---|---|
imageUrl | string | ✅ Ja | URL van de bronafbeelding: de kamer of scène waarop de textuur wordt toegepast |
styleImageUrl | string | ✅ Ja | URL van het stijlreferentiebeeld dat de gewenste textuur of het materiaal bepaalt |
maskUrl | string | ⚠️ maskUrl of maskBase64 | URL van de maskerafbeelding. Zwarte gebieden krijgen de nieuwe textuur; witte gebieden blijven behouden |
maskBase64 | string | ⚠️ maskUrl of maskBase64 | Base64-gecodeerde maskerafbeelding; PNG wordt aanbevolen. Gebruik dit als je geen gehoste URL kunt opgeven |
prompt | string | ❌ Optioneel | Aanvullende tekstinstructie om de textuurgeneratie verder te sturen |
⚠️ Geef minstens een van
maskUrlofmaskBase64op. Als beide worden opgegeven, heeftmaskUrlvoorrang.
🖼️ Afbeeldingsvereisten: Bron-, stijl- en maskerafbeeldingen moeten JPG/JPEG, PNG of WebP gebruiken. Elke afbeelding mag maximaal 20 MB groot zijn, met afmetingen van 128 × 128 px tot en met 6,000 × 6,000 px. Afbeeldingen boven de maximale pixelafmetingen worden vóór verwerking automatisch evenredig verkleind tot binnen 6,000 × 6,000 px. Afbeeldings-URLs moeten rechtstreeks bereikbaar zijn voor de API-server. Voor een Base64-masker gelden na decodering dezelfde afbeeldingslimieten en het mag geen data-URL-voorvoegsel bevatten.
📥 Verzoekvoorbeelden#
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();
📤 Antwoord#
Succesantwoord
{
"code": 0,
"message": "success",
"data": 1234567890123456789
}
| Veld | Type | Beschrijving |
|---|---|---|
code | integer | 0 geeft succes aan |
message | string | Antwoordbericht |
data | long | De unieke taak-ID voor het regelmatig opvragen van resultaten |
2. Taakresultaat ophalen#
Haalt de huidige status en uitvoer van een eerder aangemaakte taak voor textuurvervanging op.
Eindpunt
GET /api/v1/textureReplacer/result
Verzoekheaders
| Verzoekheader | Verplicht | Beschrijving |
|---|---|---|
APIKEY | ✅ Ja | Je API-authenticatiesleutel |
Queryparameters
| Queryparameter | Type | Verplicht | Beschrijving |
|---|---|---|---|
taskId | long | ✅ Ja | De taak-ID die het endpoint voor het aanmaken van taken retourneert |
📥 Verzoekvoorbeelden#
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);
📤 Antwoord#
Succesantwoord: taak voltooid
{
"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
}
}
}
Antwoord: taak in verwerking of in de wachtrij
{
"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
}
}
Antwoord: taak mislukt
{
"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
}
}
Antwoordvelden
| Veld | Type | Beschrijving |
|---|---|---|
id | long | Unieke taakidentificatie |
status | string | Huidige taakstatus; zie taakstatus |
waitNumber | integer | Aantal taken vóór deze taak in de wachtrij; 0 betekent dat de taak wordt verwerkt |
percentage | integer | Voltooiingspercentage van de taak (0–100) |
input | object | De oorspronkelijke invoerparameters van de taak |
input.imageUrl | string | URL van de bronafbeelding |
input.styleImageUrl | string | URL van het stijlreferentiebeeld |
input.maskUrl | string | URL van de maskerafbeelding, indien opgegeven via maskUrl |
input.prompt | string | Aanvullende tekstinstructie, indien opgegeven |
output | object | Generatieresultaat, alleen beschikbaar wanneer status gelijk is aan Success |
output.resultUrl | string | URL van de resultaatafbeelding met vervangen textuur |
output.width | integer | Uitvoerbreedte in pixels |
output.height | integer | Uitvoerhoogte in pixels |
📊 Taakstatus#
| Status | Beschrijving |
|---|---|
Unprocessed | De taak is aangemaakt, maar nog niet gestart |
Processing | De taak wordt momenteel verwerkt |
Success | De taak is succesvol voltooid; uitvoer is beschikbaar |
Failed | De taak is door een fout mislukt |
Vraag de status elke 3-5 seconden op. Zie de taaklimiet voor de API.
❌ Foutantwoorden#
Alle foutantwoorden hebben dezelfde JSON-structuur:
{
"code": 5002,
"message": "Invalid API Key",
"data": null
}
Foutcodereferentie#
| Code | Naam | Beschrijving | Aanbevolen actie |
|---|---|---|---|
1001 | FAILED | Verzoek mislukt: algemene fout | Controleer het veld message voor specifieke foutdetails |
1003 | INTERNAL_ERROR | Interne serverfout | Probeer het na een korte wachttijd opnieuw; neem contact op met ondersteuning als de fout blijft optreden |
1011 | PARAM_ERROR | Fout in verzoekparameters — e.g., imageUrl, styleImageUrl of het masker ontbreekt | Zorg dat alle verplichte velden zijn opgegeven |
5002 | API_KEY_INVALID | Ongeldige of ontbrekende API Key | Controleer dat de header APIKEY aanwezig is en de waarde klopt |
9010 | SCAN_TEXT_ERROR | Tekstinstructie afgekeurd bij inhoudscontrole | Pas de instructie aan om gevoelige of verboden inhoud te verwijderen |
9038 | PROHIBITED_CONTENT | De gegenereerde uitvoerafbeelding bevat verboden inhoud | Pas instructie, stijl of invoer aan en probeer opnieuw |
9051 | COINS_NOT_ENOUGH | Onvoldoende munten / credits | Vul je accountcredits aan en probeer opnieuw |
📄 Raadpleeg de foutcodereferentie voor de volledige lijst van algemene API-foutcodes.
