Documentazione API di generazione di planimetrie#
URL di base:
https://api.ideal.house
Versione: v1
Aggiornato: 2026-08-09
📖 Panoramica#
API di generazione di planimetrie crea una planimetria concettuale residenziale generata dall'intelligenza artificiale, in bianco e nero, vista dall'alto e in stile CAD, a partire da requisiti strutturati delle stanze e, facoltativamente, da un prompt personalizzato o un'immagine di riferimento.
L'output è destinato all'esplorazione preliminare della disposizione degli spazi. Non è un disegno esecutivo e le dimensioni, la geometria, il posizionamento degli impianti e la conformità normativa generati devono essere esaminati da un professionista qualificato.
Il flusso di lavoro è asincrono:
- Crea un'attività — Invia i parametri della planimetria e ricevi un
taskId. - Interroga periodicamente i risultati — Interroga l'endpoint dei risultati con il
taskIdfinché l'attività non raggiunge uno stato finale.
🔐 Autenticazione#
Tutte le richieste API pubbliche devono includere una chiave API.
| Intestazione | Obbligatoria | Valore |
|---|---|---|
APIKEY | ✅ Sì | La tua chiave API |
Content-Type | ✅ Sì per POST | application/json |
[!WARNING] Conserva la chiave API in sicurezza. Non esporla nel codice lato client o in repository pubblici.
💰 Detrazione dei crediti#
I crediti vengono detratti dopo la creazione riuscita di un'attività di generazione. Se alla fine l'attività non riesce, i crediti detratti vengono rimborsati automaticamente. Un saldo insufficiente restituisce il codice di errore 9051.
Modello (modelType) | Dimensioni dell'output | Crediti |
|---|---|---|
Base | 1536 × 1024 | 10 |
Pro | 2496 × 1664 | 20 |
Flash non è supportato da API di generazione di planimetrie.
Consulta il Riferimento delle detrazioni dei crediti per il comportamento comune della fatturazione.
📌 Endpoint API#
1. Crea un'attività di generazione di una planimetria#
Crea un'attività di generazione di una planimetria e restituisce un identificatore univoco dell'attività.
Endpoint
POST /api/v1/floorPlan/generate
Intestazioni della richiesta
| Intestazione | Obbligatoria | Descrizione |
|---|---|---|
APIKEY | ✅ Sì | Chiave di autenticazione API |
Content-Type | ✅ Sì | Deve essere application/json |
Corpo della richiesta#
| Campo | Tipo | Obbligatorio | Descrizione | Valore predefinito |
|---|---|---|---|---|
bedrooms | integer | ❌ No | Numero di camere da letto da 0 a 5 | 2 |
bathrooms | number | ❌ No | Numero totale di bagni da 0.5 a 4, con incrementi di 0.5 | 1.5 |
totalArea | string | ✅ Sì | Superficie totale desiderata positiva con unità m² o ft², ad esempio 220 m² o 1386 ft² | — |
bedroomAreaRanges | array<object> | ❌ No | Indicazioni facoltative sulle dimensioni delle camere da letto. Vedi Intervalli di superficie delle camere da letto | Derivati da totalArea quando omessi |
bathroomDetails | object | ❌ No | Preferenze soltanto per i bagni completi. Vedi Dettagli dei bagni | — |
kitchenDetails | object | ❌ No | Configurazione facoltativa della cucina. Vedi Dettagli della cucina | — |
keyRooms | array<string> | ❌ No | Stanze o spazi aggiuntivi. Vedi Stanze principali | [] |
prompt | string | ❌ No | Priorità aggiuntive per la disposizione. Non può prevalere sui conteggi strutturati o sui vincoli visivi obbligatori | "" |
refImageUrl | string | ❌ No | URL di un'immagine di riferimento accessibile pubblicamente | "" |
modelType | string | ❌ No | Enumerazione: Base, Pro | Base |
[!IMPORTANT] API pubblica attualmente convalida
bedroomsnell'intervallo0–5ebathroomsnell'intervallo0.5–4. I valori disponibili nell'interfaccia di un altro client non ampliano questi limiti del server.
Regole generali delle richieste#
- Tutti i valori delle enumerazioni distinguono maiuscole e minuscole e devono usare i valori inglesi mostrati in questo documento.
totalAreaè una superficie totale desiderata usata per orientare scala e proporzioni; non viene trattata come una dimensione esecutiva esatta.- Il prompt personalizzato effettivo è limitato ai primi 800 caratteri durante l'assemblaggio del prompt strutturato per l'immagine.
- I campi strutturati hanno la precedenza sulle istruzioni contrastanti in
prompt. - Un'attività riuscita genera esattamente un'immagine.
📐 Superficie totale#
totalArea contiene un solo valore numerico positivo seguito da un'unità di superficie.
| Unità | Esempio |
|---|---|
m² | 220 m² |
ft² | 1386 ft² |
Si consiglia uno spazio prima dell'unità. Sono accettati valori decimali purché positivi.
Esempi validi:
{
"totalArea": "200 m²"
}
{
"totalArea": "1850 ft²"
}
🛏️ Intervalli di superficie delle camere da letto#
bedroomAreaRanges fornisce indicazioni relative sulle dimensioni delle camere da letto. Non richiede etichette numeriche delle superfici nell'immagine generata.
Ogni elemento ha la seguente struttura:
| Campo | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
name | string | ❌ No | Identità della camera da letto, ad esempio Room 1 (Master) o Room 2 |
minArea | string | ❌ No | Superficie minima positiva |
maxArea | string | ❌ No | Superficie massima positiva; non può essere inferiore a minArea |
unit | string | ❌ No | Enumerazione: m², ft²; usa la stessa unità di totalArea |
Esempio di intervallo esplicito
{
"bedroomAreaRanges": [
{
"name": "Room 1 (Master)",
"minArea": "30",
"maxArea": "40",
"unit": "m²"
},
{
"name": "Room 2",
"minArea": "20",
"maxArea": "30",
"unit": "m²"
}
]
}
Regole quando viene fornito un array non vuoto:
- La sua lunghezza deve essere uguale a
bedrooms. - Ogni
minAreaemaxAreafornito deve essere una stringa numerica positiva. - Quando vengono forniti entrambi i valori,
minArea <= maxArea. unit, quando fornito, deve esserem²oft².- I nomi vengono conservati. Gli elementi vuoti o nulli non forniscono indicazioni sulle dimensioni.
Intervalli automatici quando omessi#
Il campo può essere omesso o inviato come array vuoto. Quando nessun elemento contiene un minArea o maxArea effettivo, la procedura di generazione strutturata ricava intervalli interni per le camere da letto da totalArea e bedrooms:
- La quota di superficie per le camere da letto parte dal 20% della superficie totale per una camera.
- La quota aumenta di 7.5 punti percentuali per ogni camera da letto aggiuntiva, fino a un massimo del 50%.
- La prima camera da letto riceve un peso dimensionale di
1.3; ogni altra camera riceve un peso di1.0. - Ogni valore desiderato diventa un intervallo approssimativo di
±10%, arrotondato a unità intere di superficie. - L'unità viene ereditata da
totalArea. - I nomi esistenti delle stanze non vuoti vengono conservati; altrimenti il server usa
Room 1,Room 2e così via.
Per 200 m² e 4 camere da letto, le indicazioni attualmente ricavate sono approssimativamente:
[
{ "name": "Room 1", "minArea": "23", "maxArea": "28", "unit": "m²" },
{ "name": "Room 2", "minArea": "18", "maxArea": "22", "unit": "m²" },
{ "name": "Room 3", "minArea": "18", "maxArea": "22", "unit": "m²" },
{ "name": "Room 4", "minArea": "18", "maxArea": "22", "unit": "m²" }
]
Questi valori sono indicazioni proporzionali interne, non superfici finali garantite delle stanze. Gli intervalli espliciti validi hanno sempre la precedenza su quelli automatici.
Quando bedrooms è 0, ometti bedroomAreaRanges oppure invia [].
🛁 Dettagli dei bagni#
bathrooms rappresenta il numero totale di bagni:
- La sua parte intera è il numero di bagni completi.
- Una frazione
.5aggiunge un bagno di servizio. - Per ogni bagno completo viene richiesta la presenza di un WC, un mobile lavabo/lavandino e una doccia o zona umida.
- Un bagno di servizio contiene soltanto un WC e un mobile lavabo/lavandino, senza doccia né vasca.
bathroomDetails configura soltanto i bagni completi:
{
"bathroomDetails": {
"fullBathroomOptions": [
{
"name": "Bathroom 1",
"wetDrySeparation": "yes",
"bathtub": "required"
},
{
"name": "Bathroom 2",
"wetDrySeparation": "no",
"bathtub": "optional"
}
]
}
}
| Campo | Tipo | Valori consentiti | Descrizione |
|---|---|---|---|
name | string | Bathroom 1, Bathroom 2, ecc. | Identità visualizzata facoltativa |
wetDrySeparation | string / null | yes, no, null | Se mostrare una zona umida separata |
bathtub | string / null | no, optional, required, null | Preferenza per la vasca da bagno |
Regole:
fullBathroomOptions.lengthnon può superarefloor(bathrooms).- L'array può contenere soltanto i bagni completi per i quali sono state selezionate preferenze.
- Un valore
nullsignifica non specificato. - Una vasca obbligatoria si aggiunge alla dotazione standard del bagno completo; non sostituisce il WC o la doccia.
- La separazione tra zona umida e asciutta è una partizione interna a un bagno già conteggiato, non un bagno aggiuntivo.
🍳 Dettagli della cucina#
Tutti i campi figli di kitchenDetails sono facoltativi. Ometti l'intero oggetto quando non viene selezionata alcuna preferenza per la cucina.
{
"kitchenDetails": {
"type": "open",
"size": "standard",
"layout": "U",
"islandType": "preparation",
"storage": "maximum",
"features": ["breakfast nook", "pantry"]
}
}
| Campo | Tipo | Valori consentiti |
|---|---|---|
type | string | open, semi-open, closed |
size | string | small, standard, large, extra large |
layout | string | I, L, U, gallery |
islandType | string | no, preparation, cooking, entertainment |
storage | string | minimal, standard, maximum |
features | array<string> | eating bar, breakfast nook, pantry |
Una configurazione parziale è valida. Ad esempio:
{
"kitchenDetails": {
"type": "semi-open"
}
}
🚪 Stanze principali#
keyRooms accetta un array di questi valori esatti:
| Valore | Descrizione |
|---|---|
walk-in closet | Cabina armadio dedicata collegata alla zona notte |
laundry room | Spazio lavanderia dedicato |
storage room | Ripostiglio generico |
utility room | Locale tecnico o di servizio |
home office | Ufficio o studio dedicato |
garage | Autorimessa con apertura esterna per veicoli e accesso interno alla casa |
pantry | Dispensa adiacente alla cucina |
combined living-dining | Un'unica zona condivisa per soggiorno e pranzo |
balcony | Balcone esterno collegato alla zona giorno o a una camera principale |
Il valore Web precedente balcon viene accettato e normalizzato in balcony.
Regole:
- I valori vuoti vengono ignorati e quelli duplicati rimossi.
- Le stanze principali selezionate vengono richieste una sola volta.
- Gli spazi facoltativi non selezionati sono esclusi dall'insieme di ambienti previsto dalla generazione.
- Se
pantrycompare sia inkitchenDetails.featuressia inkeyRooms, viene richiesta una sola dispensa.
Esempio:
{
"keyRooms": [
"garage",
"home office",
"combined living-dining"
]
}
🖼️ Immagine di riferimento#
refImageUrl è facoltativo e deve essere direttamente accessibile dal server API.
Requisiti:
- Formato: JPG/JPEG, PNG o WebP.
- Dimensione massima del file: 20 MB.
- Dimensioni minime: 128 × 128 px.
- Dimensioni massime: 6,000 × 6,000 px. Le immagini più grandi vengono ridimensionate proporzionalmente prima dell'elaborazione.
L'immagine di riferimento orienta disposizione, adiacenze, proporzioni o stile visivo. Non prevale sui conteggi strutturati delle stanze né su altri vincoli obbligatori.
🤖 Tipi di modello#
| Valore | Descrizione |
|---|---|
Base | Predefinito. Qualità di generazione equilibrata, output 1536 × 1024 |
Pro | Output a risoluzione maggiore di 2496 × 1664, con tempo di generazione previsto più lungo |
Sono supportati soltanto Base e Pro.
Campi esclusi dal contratto funzionale pubblico#
I client API pubblici non devono fare affidamento sui seguenti campi:
| Campo | Note |
|---|---|
imageNumbers | Il generatore attuale restituisce sempre un'immagine; questo campo non è necessario |
extData | Metadati interni Web per il monitoraggio dei gruppi di attività; i client pubblici devono ometterli |
isApiCall | Determinato dall'endpoint API, non dal corpo della richiesta |
genByMember | Metadati interni di generazione, non un campo della richiesta di planimetria |
Campi precedenti rimossi che non devono essere inviati:
floorplanSetting
roomCounts
grossArea
totalAreaValue
totalAreaUnit
totalAreaType
fullBathrooms
halfBathrooms
halfBathroomRequirement
kitchenType
diningRooms
livingRooms
extras
referenceImage
hasDetailOptions
📥 Esempi di creazione di attività#
Richiesta minima con intervalli automatici per le camere da letto#
curl -X POST "https://api.ideal.house/api/v1/floorPlan/generate" \
-H "APIKEY: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"bedrooms": 4,
"bathrooms": 2,
"totalArea": "200 m²",
"modelType": "Pro",
"prompt": "Upper floor of a two-story Saudi Arabian villa with a master bedroom, family living area, staircase landing, and balcony"
}'
Richiesta completa#
cURL
curl -X POST "https://api.ideal.house/api/v1/floorPlan/generate" \
-H "APIKEY: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"bedrooms": 3,
"bathrooms": 2.5,
"totalArea": "220 m²",
"bedroomAreaRanges": [
{"name": "Room 1 (Master)", "minArea": "30", "maxArea": "40", "unit": "m²"},
{"name": "Room 2", "minArea": "20", "maxArea": "30", "unit": "m²"},
{"name": "Room 3", "minArea": "20", "maxArea": "30", "unit": "m²"}
],
"bathroomDetails": {
"fullBathroomOptions": [
{"name": "Bathroom 1", "wetDrySeparation": "yes", "bathtub": "required"},
{"name": "Bathroom 2", "wetDrySeparation": "no", "bathtub": "optional"}
]
},
"kitchenDetails": {
"type": "open",
"size": "standard",
"layout": "U",
"islandType": "preparation",
"storage": "maximum",
"features": ["breakfast nook", "pantry"]
},
"keyRooms": ["garage", "home office", "combined living-dining"],
"prompt": "Bright modern home with good natural lighting",
"refImageUrl": "https://example.com/reference-plan.png",
"modelType": "Pro"
}'
Java (OkHttp)
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class FloorPlanApiExample {
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 Exception {
OkHttpClient client = new OkHttpClient();
String json = """
{
"bedrooms": 4,
"bathrooms": 2,
"totalArea": "200 m²",
"keyRooms": ["walk-in closet", "balcony"],
"prompt": "Upper floor with a master bedroom and family living area",
"modelType": "Pro"
}
""";
Request request = new Request.Builder()
.url(BASE_URL + "/api/v1/floorPlan/generate")
.addHeader("APIKEY", API_KEY)
.addHeader("Content-Type", "application/json")
.post(RequestBody.create(json, MediaType.parse("application/json")))
.build();
try (Response response = client.newCall(request).execute()) {
System.out.println(response.body().string());
}
}
}
Python (requests)
import requests
BASE_URL = "https://api.ideal.house"
API_KEY = "your_api_key_here"
payload = {
"bedrooms": 4,
"bathrooms": 2,
"totalArea": "200 m²",
"keyRooms": ["walk-in closet", "balcony"],
"prompt": "Upper floor with a master bedroom and family living area",
"modelType": "Pro",
}
response = requests.post(
f"{BASE_URL}/api/v1/floorPlan/generate",
headers={"APIKEY": API_KEY, "Content-Type": "application/json"},
json=payload,
)
response.raise_for_status()
print("Task ID:", response.json()["data"])
Node.js (axios)
const axios = require('axios');
const BASE_URL = 'https://api.ideal.house';
const API_KEY = 'your_api_key_here';
async function createFloorPlanTask() {
const response = await axios.post(
`${BASE_URL}/api/v1/floorPlan/generate`,
{
bedrooms: 4,
bathrooms: 2,
totalArea: '200 m²',
keyRooms: ['walk-in closet', 'balcony'],
prompt: 'Upper floor with a master bedroom and family living area',
modelType: 'Pro'
},
{
headers: {
APIKEY: API_KEY,
'Content-Type': 'application/json'
}
}
);
console.log('Task ID:', response.data.data);
return response.data.data;
}
createFloorPlanTask();
Risposta di creazione riuscita dell'attività#
{
"code": 0,
"message": "success",
"data": 1234567890123456789
}
| Campo | Tipo | Descrizione |
|---|---|---|
code | integer | 0 indica che l'attività è stata creata correttamente |
message | string | Messaggio della risposta |
data | long | Identificatore dell'attività usato per interrogare periodicamente l'endpoint dei risultati |
2. Ottieni il risultato dell'attività#
Restituisce l'avanzamento dell'attività e l'immagine generata quando disponibile.
Endpoint
GET /api/v1/floorPlan/result?taskId={taskId}
Intestazioni della richiesta
| Intestazione | Obbligatoria | Descrizione |
|---|---|---|
APIKEY | ✅ Sì | Chiave di autenticazione API |
Parametri di interrogazione
| Parametro | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
taskId | long | ✅ Sì | Identificatore dell'attività restituito dall'endpoint di creazione |
Esempi di richiesta del risultato#
cURL
curl -X GET "https://api.ideal.house/api/v1/floorPlan/result?taskId=1234567890123456789" \
-H "APIKEY: your_api_key_here"
Interrogazione periodica con Python
import time
import requests
BASE_URL = "https://api.ideal.house"
API_KEY = "your_api_key_here"
task_id = 1234567890123456789
while True:
response = requests.get(
f"{BASE_URL}/api/v1/floorPlan/result",
headers={"APIKEY": API_KEY},
params={"taskId": task_id},
)
response.raise_for_status()
task = response.json()["data"]
print(task["status"], task["percentage"], task["waitNumber"])
if task["status"] in ("Success", "Failed", "Termination"):
break
time.sleep(3)
if task["status"] == "Success":
print("Result URL:", task["output"]["resultUrl"])
Interrogazione periodica con Node.js
const axios = require('axios');
const BASE_URL = 'https://api.ideal.house';
const API_KEY = 'your_api_key_here';
async function pollFloorPlanResult(taskId) {
while (true) {
const response = await axios.get(
`${BASE_URL}/api/v1/floorPlan/result`,
{
headers: { APIKEY: API_KEY },
params: { taskId }
}
);
const task = response.data.data;
console.log(task.status, task.percentage, task.waitNumber);
if (['Success', 'Failed', 'Termination'].includes(task.status)) {
if (task.status === 'Success') {
console.log('Result URL:', task.output.resultUrl);
}
return task;
}
await new Promise(resolve => setTimeout(resolve, 3000));
}
}
pollFloorPlanResult('1234567890123456789');
Risposta per attività completata#
{
"code": 0,
"message": "success",
"data": {
"id": 1234567890123456789,
"status": "Success",
"waitNumber": 0,
"percentage": 100,
"input": {
"bedrooms": 4,
"bathrooms": 2,
"totalArea": "200 m²",
"bedroomAreaRanges": [
{"name": "Room 1", "minArea": "23", "maxArea": "28", "unit": "m²"},
{"name": "Room 2", "minArea": "18", "maxArea": "22", "unit": "m²"},
{"name": "Room 3", "minArea": "18", "maxArea": "22", "unit": "m²"},
{"name": "Room 4", "minArea": "18", "maxArea": "22", "unit": "m²"}
],
"keyRooms": ["walk-in closet", "balcony"],
"prompt": "Upper floor with a master bedroom and family living area",
"modelType": "Pro"
},
"output": {
"resultUrl": "https://cdn.ideal.house/output/floor-plan.jpg",
"width": 2496,
"height": 1664
}
}
}
Risposta durante l'elaborazione#
{
"code": 0,
"message": "success",
"data": {
"id": 1234567890123456789,
"status": "Processing",
"waitNumber": 1,
"percentage": 45,
"input": {
"bedrooms": 4,
"bathrooms": 2,
"totalArea": "200 m²",
"modelType": "Pro"
},
"output": null
}
}
Risposta per attività non riuscita#
{
"code": 0,
"message": "success",
"data": {
"id": 1234567890123456789,
"status": "Failed",
"waitNumber": 0,
"percentage": 0,
"input": {
"bedrooms": 4,
"bathrooms": 2,
"totalArea": "200 m²",
"modelType": "Pro"
},
"output": null
}
}
Campi del risultato#
| Campo | Tipo | Descrizione |
|---|---|---|
id | long | Identificatore dell'attività |
status | string | Stato corrente dell'attività |
waitNumber | integer | Numero di attività precedenti in coda; 0 significa che non ci sono attività in coda prima di questa |
percentage | integer | Percentuale approssimativa di completamento da 0 a 100 |
input | object | Input normalizzato dell'attività, compresi gli intervalli delle camere da letto ricavati automaticamente quando applicabile |
output | object / null | Output generato quando l'attività riesce; altrimenti solitamente null |
output.resultUrl | string | URL firmata dell'immagine della planimetria generata |
output.width | integer | Larghezza dell'output in pixel |
output.height | integer | Altezza dell'output in pixel |
📊 Stato dell'attività#
| Stato | Descrizione |
|---|---|
Unprocessed | L'attività è stata creata ma non è iniziata |
Processing | L'attività è in elaborazione |
Success | L'attività è completata e output.resultUrl è disponibile |
Failed | L'attività non è riuscita |
Termination | L'attività è stata interrotta o terminata |
Interroga lo stato ogni 3–5 secondi. Consulta i Limiti delle attività API.
❌ Risposte di errore#
Tutte le risposte di errore usano la struttura comune delle risposte:
{
"code": 1011,
"message": "bedroomAreaRanges size must match bedrooms",
"data": null
}
| Codice | Nome | Descrizione | Azione suggerita |
|---|---|---|---|
1001 | FAILED | Errore generico della richiesta | Controlla il campo message |
1003 | INTERNAL_ERROR | Errore interno del server | Riprova più tardi; contatta l'assistenza se il problema persiste |
1011 | PARAM_ERROR | Parametro della richiesta non valido | Verifica conteggi, unità, valori delle enumerazioni e array annidati |
5002 | API_KEY_INVALID | Chiave API non valida o mancante | Verifica l'intestazione APIKEY |
9010 | SCAN_TEXT_ERROR | Il prompt non ha superato la verifica dei contenuti | Modifica il prompt |
9038 | PROHIBITED_CONTENT | L'output generato contiene contenuti vietati | Modifica gli input e riprova |
9051 | COINS_NOT_ENOUGH | Crediti insufficienti | Aggiungi crediti e riprova |
Consulta il Riferimento dei codici di errore per l'elenco completo degli errori comuni.
🔄 Note sull'integrazione Web#
L'applicazione Web autenticata e API pubblica usano endpoint e metodi di autenticazione differenti:
| Applicazione chiamante | Endpoint | Autenticazione |
|---|---|---|
| Applicazione Web | POST /floorPlan/generate | Intestazione token di accesso |
| API pubblica | POST /api/v1/floorPlan/generate | Intestazione APIKEY |
Le strutture dei campi funzionali sono allineate, ma i client API pubblici devono seguire i limiti del server e il contratto pubblico di questo documento. In particolare:
- I client Web possono includere
imageNumbersedextDatainterni; i client pubblici non ne hanno bisogno. - API pubblica determina i metadati delle chiamate API dall'endpoint e dalle credenziali. Campi della richiesta come
isApiCallegenByMembernon sono necessari. balconè accettato per compatibilità e normalizzato inbalcony; le nuove integrazioni devono inviarebalcony.- I limiti attuali del server pubblico restano
0–5camere da letto e0.5–4bagni, anche se un'altra interfaccia offre temporaneamente selettori più ampi.