Ideal House
Passa al contenuto

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:

  1. Crea un'attività — Invia i parametri della planimetria e ricevi un taskId.
  2. Interroga periodicamente i risultati — Interroga l'endpoint dei risultati con il taskId finché l'attività non raggiunge uno stato finale.

🔐 Autenticazione#

Tutte le richieste API pubbliche devono includere una chiave API.

IntestazioneObbligatoriaValore
APIKEY✅ SìLa tua chiave API
Content-Type✅ Sì per POSTapplication/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'outputCrediti
Base1536 × 102410
Pro2496 × 166420

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

http
POST /api/v1/floorPlan/generate

Intestazioni della richiesta

IntestazioneObbligatoriaDescrizione
APIKEY✅ SìChiave di autenticazione API
Content-Type✅ SìDeve essere application/json

Corpo della richiesta#

CampoTipoObbligatorioDescrizioneValore predefinito
bedroomsinteger❌ NoNumero di camere da letto da 0 a 52
bathroomsnumber❌ NoNumero totale di bagni da 0.5 a 4, con incrementi di 0.51.5
totalAreastring✅ SìSuperficie totale desiderata positiva con unità o ft², ad esempio 220 m² o 1386 ft²
bedroomAreaRangesarray<object>❌ NoIndicazioni facoltative sulle dimensioni delle camere da letto. Vedi Intervalli di superficie delle camere da lettoDerivati da totalArea quando omessi
bathroomDetailsobject❌ NoPreferenze soltanto per i bagni completi. Vedi Dettagli dei bagni
kitchenDetailsobject❌ NoConfigurazione facoltativa della cucina. Vedi Dettagli della cucina
keyRoomsarray<string>❌ NoStanze o spazi aggiuntivi. Vedi Stanze principali[]
promptstring❌ NoPriorità aggiuntive per la disposizione. Non può prevalere sui conteggi strutturati o sui vincoli visivi obbligatori""
refImageUrlstring❌ NoURL di un'immagine di riferimento accessibile pubblicamente""
modelTypestring❌ NoEnumerazione: Base, ProBase

[!IMPORTANT] API pubblica attualmente convalida bedrooms nell'intervallo 0–5 e bathrooms nell'intervallo 0.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
220 m²
ft²1386 ft²

Si consiglia uno spazio prima dell'unità. Sono accettati valori decimali purché positivi.

Esempi validi:

json
{
  "totalArea": "200 m²"
}
json
{
  "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:

CampoTipoObbligatorioDescrizione
namestring❌ NoIdentità della camera da letto, ad esempio Room 1 (Master) o Room 2
minAreastring❌ NoSuperficie minima positiva
maxAreastring❌ NoSuperficie massima positiva; non può essere inferiore a minArea
unitstring❌ NoEnumerazione: , ft²; usa la stessa unità di totalArea

Esempio di intervallo esplicito

json
{
  "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 minArea e maxArea fornito deve essere una stringa numerica positiva.
  • Quando vengono forniti entrambi i valori, minArea <= maxArea.
  • unit, quando fornito, deve essere o ft².
  • 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 di 1.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 2 e così via.

Per 200 m² e 4 camere da letto, le indicazioni attualmente ricavate sono approssimativamente:

json
[
  { "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 .5 aggiunge 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:

json
{
  "bathroomDetails": {
    "fullBathroomOptions": [
      {
        "name": "Bathroom 1",
        "wetDrySeparation": "yes",
        "bathtub": "required"
      },
      {
        "name": "Bathroom 2",
        "wetDrySeparation": "no",
        "bathtub": "optional"
      }
    ]
  }
}
CampoTipoValori consentitiDescrizione
namestringBathroom 1, Bathroom 2, ecc.Identità visualizzata facoltativa
wetDrySeparationstring / nullyes, no, nullSe mostrare una zona umida separata
bathtubstring / nullno, optional, required, nullPreferenza per la vasca da bagno

Regole:

  • fullBathroomOptions.length non può superare floor(bathrooms).
  • L'array può contenere soltanto i bagni completi per i quali sono state selezionate preferenze.
  • Un valore null significa 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.

json
{
  "kitchenDetails": {
    "type": "open",
    "size": "standard",
    "layout": "U",
    "islandType": "preparation",
    "storage": "maximum",
    "features": ["breakfast nook", "pantry"]
  }
}
CampoTipoValori consentiti
typestringopen, semi-open, closed
sizestringsmall, standard, large, extra large
layoutstringI, L, U, gallery
islandTypestringno, preparation, cooking, entertainment
storagestringminimal, standard, maximum
featuresarray<string>eating bar, breakfast nook, pantry

Una configurazione parziale è valida. Ad esempio:

json
{
  "kitchenDetails": {
    "type": "semi-open"
  }
}

🚪 Stanze principali#

keyRooms accetta un array di questi valori esatti:

ValoreDescrizione
walk-in closetCabina armadio dedicata collegata alla zona notte
laundry roomSpazio lavanderia dedicato
storage roomRipostiglio generico
utility roomLocale tecnico o di servizio
home officeUfficio o studio dedicato
garageAutorimessa con apertura esterna per veicoli e accesso interno alla casa
pantryDispensa adiacente alla cucina
combined living-diningUn'unica zona condivisa per soggiorno e pranzo
balconyBalcone 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 pantry compare sia in kitchenDetails.features sia in keyRooms, viene richiesta una sola dispensa.

Esempio:

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

ValoreDescrizione
BasePredefinito. Qualità di generazione equilibrata, output 1536 × 1024
ProOutput 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:

CampoNote
imageNumbersIl generatore attuale restituisce sempre un'immagine; questo campo non è necessario
extDataMetadati interni Web per il monitoraggio dei gruppi di attività; i client pubblici devono ometterli
isApiCallDeterminato dall'endpoint API, non dal corpo della richiesta
genByMemberMetadati interni di generazione, non un campo della richiesta di planimetria

Campi precedenti rimossi che non devono essere inviati:

text
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#

bash
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
bash
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)
java
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)
python
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)
javascript
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à#

json
{
  "code": 0,
  "message": "success",
  "data": 1234567890123456789
}
CampoTipoDescrizione
codeinteger0 indica che l'attività è stata creata correttamente
messagestringMessaggio della risposta
datalongIdentificatore 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

http
GET /api/v1/floorPlan/result?taskId={taskId}

Intestazioni della richiesta

IntestazioneObbligatoriaDescrizione
APIKEY✅ SìChiave di autenticazione API

Parametri di interrogazione

ParametroTipoObbligatorioDescrizione
taskIdlong✅ SìIdentificatore dell'attività restituito dall'endpoint di creazione

Esempi di richiesta del risultato#

cURL
bash
curl -X GET "https://api.ideal.house/api/v1/floorPlan/result?taskId=1234567890123456789" \
  -H "APIKEY: your_api_key_here"
Interrogazione periodica con Python
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
javascript
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#

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

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

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

CampoTipoDescrizione
idlongIdentificatore dell'attività
statusstringStato corrente dell'attività
waitNumberintegerNumero di attività precedenti in coda; 0 significa che non ci sono attività in coda prima di questa
percentageintegerPercentuale approssimativa di completamento da 0 a 100
inputobjectInput normalizzato dell'attività, compresi gli intervalli delle camere da letto ricavati automaticamente quando applicabile
outputobject / nullOutput generato quando l'attività riesce; altrimenti solitamente null
output.resultUrlstringURL firmata dell'immagine della planimetria generata
output.widthintegerLarghezza dell'output in pixel
output.heightintegerAltezza dell'output in pixel

📊 Stato dell'attività#

StatoDescrizione
UnprocessedL'attività è stata creata ma non è iniziata
ProcessingL'attività è in elaborazione
SuccessL'attività è completata e output.resultUrl è disponibile
FailedL'attività non è riuscita
TerminationL'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:

json
{
  "code": 1011,
  "message": "bedroomAreaRanges size must match bedrooms",
  "data": null
}
CodiceNomeDescrizioneAzione suggerita
1001FAILEDErrore generico della richiestaControlla il campo message
1003INTERNAL_ERRORErrore interno del serverRiprova più tardi; contatta l'assistenza se il problema persiste
1011PARAM_ERRORParametro della richiesta non validoVerifica conteggi, unità, valori delle enumerazioni e array annidati
5002API_KEY_INVALIDChiave API non valida o mancanteVerifica l'intestazione APIKEY
9010SCAN_TEXT_ERRORIl prompt non ha superato la verifica dei contenutiModifica il prompt
9038PROHIBITED_CONTENTL'output generato contiene contenuti vietatiModifica gli input e riprova
9051COINS_NOT_ENOUGHCrediti insufficientiAggiungi 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 chiamanteEndpointAutenticazione
Applicazione WebPOST /floorPlan/generateIntestazione token di accesso
API pubblicaPOST /api/v1/floorPlan/generateIntestazione 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 imageNumbers ed extData interni; i client pubblici non ne hanno bisogno.
  • API pubblica determina i metadati delle chiamate API dall'endpoint e dalle credenziali. Campi della richiesta come isApiCall e genByMember non sono necessari.
  • balcon è accettato per compatibilità e normalizzato in balcony; le nuove integrazioni devono inviare balcony.
  • I limiti attuali del server pubblico restano 0–5 camere da letto e 0.5–4 bagni, anche se un'altra interfaccia offre temporaneamente selettori più ampi.