Documentação da API de geração de plantas baixas#
URL Base:
https://api.ideal.house
Versão: v1
Atualizado: 2026-08-09
📖 Visão Geral#
A API de geração de plantas baixas cria um projeto de planta baixa residencial em preto e branco, vista superior, estilo CAD, com base em requisitos estruturados de ambientes e em um prompt personalizado opcional ou imagem de referência.
O resultado destina-se à exploração inicial do layout. Não se trata de um desenho construtivo; dimensões, geometria, posicionamento de louças e conformidade com as normas de construção devem ser revisados por profissional qualificado.
O fluxo é assíncrono:
- Criar uma tarefa — Envie os parâmetros da planta baixa e receba um
taskId. - Consultar resultados — Consulte o endpoint de resultado com o
taskIdaté que a tarefa alcance um status final.
🔐 Autenticação#
Todas as requisições públicas da API devem incluir uma chave API.
| Cabeçalho | Obrigatório | Valor |
|---|---|---|
APIKEY | ✅ Sim | Sua chave API |
Content-Type | ✅ Sim para POST | application/json |
[!WARNING] Mantenha sua chave API segura. Não a exponha em código do lado do cliente ou repositórios públicos.
💰 Dedução de Créditos#
Os créditos são deduzidos após a criação bem-sucedida de uma tarefa de geração. Se a tarefa falhar, os créditos deduzidos são estornados automaticamente. Créditos insuficientes retornam o código de erro 9051.
Modelo (modelType) | Tamanho da saída | Créditos |
|---|---|---|
Base | 1536 × 1024 | 10 |
Pro | 2496 × 1664 | 20 |
Flash não é suportado pela API de Planta Baixa API.
Consulte Referência de Dedução de Créditos para comportamento comum de cobrança.
📌 Endpoints da API#
1. Criar Tarefa de Planta Baixa#
Cria uma tarefa de geração de planta baixa e retorna um ID de tarefa único.
Endpointo
POST /api/v1/floorPlan/generate
Cabeçalhos da requisição
| Cabeçalho | Obrigatório | Descrição |
|---|---|---|
APIKEY | ✅ Sim | Chave de autenticação da API |
Content-Type | ✅ Sim | Deve ser application/json |
Corpo da requisição#
| Campo | Tipo | Obrigatório | Descrição | Padrão |
|---|---|---|---|---|
bedrooms | integer | ❌ Não | Quantidade de quartos de 0 a 5 | 2 |
bathrooms | number | ❌ Não | Quantidade total de banheiros de 0.5 a 4, em incrementos de 0.5 | 1.5 |
totalArea | string | ✅ Sim | Área total alvo positiva com unidade m² ou ft², como 220 m² ou 1386 ft² | — |
bedroomAreaRanges | array<object> | ❌ Não | Orientação opcional de dimensionamento de quartos. Veja Intervalos de Área dos Quartos | Derivado de totalArea quando omitido |
bathroomDetails | object | ❌ Não | Preferências apenas para banheiros completos. Veja Detalhes do Banheiro | — |
kitchenDetails | object | ❌ Não | Configuração opcional da cozinha. Veja Detalhes da Cozinha | — |
keyRooms | array<string> | ❌ Não | Ambientes ou espaços adicionais. Veja Ambientes Principais | [] |
prompt | string | ❌ Não | Prioridades adicionais de layout. Não pode substituir contagens estruturadas ou restrições visuais rígidas | "" |
refImageUrl | string | ❌ Não | URL da imagem de referência de acesso público | "" |
modelType | string | ❌ Não | Enum: Base, Pro | Base |
[!IMPORTANT] A API pública API atualmente valida
bedroomscomo0–5ebathroomscomo0.5–4. Valores disponíveis em outra interface do cliente não ampliam esses limites no lado do servidor.
Regras gerais de requisição#
- Todos os valores de enumeração diferenciam maiúsculas de minúsculas e devem usar os valores em inglês apresentados neste documento.
totalAreaé uma área total alvo usada para orientar escala e proporções; não é tratada como uma dimensão construtiva exata.- O prompt personalizado efetivo é limitado aos primeiros 800 caracteres quando o prompt de imagem estruturado é montado.
- Campos estruturados têm precedência sobre instruções conflitantes em
prompt. - Uma tarefa bem-sucedida gera exatamente uma imagem.
📐 Área Total#
totalArea contém um valor numérico positivo seguido de uma unidade de área.
| Unidade | Exemplo |
|---|---|
m² | 220 m² |
ft² | 1386 ft² |
Espaço em branco antes da unidade é recomendado. Valores decimais são aceitos quando positivos.
Exemplos válidos:
{
"totalArea": "200 m²"
}
{
"totalArea": "1850 ft²"
}
🛏️ Intervalos de Área dos Quartos#
bedroomAreaRanges fornece orientação relativa de dimensionamento de quartos. Não solicita rótulos de área numérica na imagem gerada.
Cada item tem o seguinte formato:
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
name | string | ❌ Não | Identidade do quarto, por exemplo Room 1 (Master) ou Room 2 |
minArea | string | ❌ Não | Área mínima positiva |
maxArea | string | ❌ Não | Área máxima positiva; não pode ser menor que minArea |
unit | string | ❌ Não | Enum: m², ft²; use a mesma unidade que totalArea |
Exemplo de intervalo explícito
{
"bedroomAreaRanges": [
{
"name": "Room 1 (Master)",
"minArea": "30",
"maxArea": "40",
"unit": "m²"
},
{
"name": "Room 2",
"minArea": "20",
"maxArea": "30",
"unit": "m²"
}
]
}
Regras quando um array não vazio é fornecido:
- Seu comprimento deve ser igual a
bedrooms. - Cada
minAreaemaxAreafornecido deve ser uma string numérica positiva. - Quando ambos os valores são fornecidos,
minArea <= maxArea. unit, quando fornecido, deve serm²ouft².- Os nomes são preservados. Itens vazios ou nulos não fornecem orientação de dimensionamento.
Intervalos automáticos quando omitido#
O campo pode ser omitido ou enviado como array vazio. Quando nenhum item contém minArea ou maxArea eficaz, o caminho de geração estruturado deriva intervalos internos de quartos a partir de totalArea e bedrooms:
- O orçamento de área do quarto começa em 20% da área total para um quarto.
- O orçamento aumenta em 7.5 pontos percentuais para cada quarto adicional, limitado a 50%.
- O primeiro quarto recebe um peso de dimensionamento de
1.3; cada outro quarto recebe um peso de1.0. - Cada alvo se torna um intervalo aproximado de
±10%, arredondado para unidades de área inteiras. - A unidade é herdada de
totalArea. - Nomes de quartos não vazios existentes são mantidos; caso contrário, o servidor usa
Room 1,Room 2, e assim por diante.
Para 200 m² e 4 quartos, a orientação derivada atual é aproximadamente:
[
{ "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²" }
]
Esses valores são orientação proporcional interna, não áreas finais garantidas dos ambientes. Intervalos válidos explícitos sempre têm precedência sobre intervalos automáticos.
Quando bedrooms é 0, omita bedroomAreaRanges ou envie [].
🛁 Detalhes do Banheiro#
bathrooms representa a contagem total de banheiros:
- Sua parte inteira é o número de banheiros completos.
- Uma fração
.5adiciona um lavabo. - Cada banheiro completo é configurado para incluir vaso sanitário, bancada com pia ou lavatório e chuveiro ou área molhada.
- Um lavabo contém apenas vaso sanitário e bancada com pia ou lavatório, sem chuveiro ou banheira.
bathroomDetails configura apenas banheiros completos:
{
"bathroomDetails": {
"fullBathroomOptions": [
{
"name": "Bathroom 1",
"wetDrySeparation": "yes",
"bathtub": "required"
},
{
"name": "Bathroom 2",
"wetDrySeparation": "no",
"bathtub": "optional"
}
]
}
}
| Campo | Tipo | Valores permitidos | Descrição |
|---|---|---|---|
name | string | Bathroom 1, Bathroom 2, etc. | Identidade de exibição opcional |
wetDrySeparation | string / null | yes, no, null | Se deve exibir zona molhada separada |
bathtub | string / null | no, optional, required, null | Preferência de banheira |
Regras:
fullBathroomOptions.lengthnão pode excederfloor(bathrooms).- O array só pode conter os banheiros completos para os quais preferências foram selecionadas.
- Um valor
nullsignifica não especificado. - Uma banheira obrigatória é adicional às louças padrão do banheiro completo; não substitui o vaso sanitário ou chuveiro.
- Separação molhada/seca é uma divisória interna dentro de um banheiro contabilizado, não um banheiro adicional.
🍳 Detalhes da Cozinha#
Todos os campos filhos de kitchenDetails são opcionais. Omita o objeto inteiro quando nenhuma preferência de cozinha for selecionada.
{
"kitchenDetails": {
"type": "open",
"size": "standard",
"layout": "U",
"islandType": "preparation",
"storage": "maximum",
"features": ["breakfast nook", "pantry"]
}
}
| Campo | Tipo | Valores permitidos |
|---|---|---|
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 |
Configuração parcial é válida. Por exemplo:
{
"kitchenDetails": {
"type": "semi-open"
}
}
🚪 Ambientes Principais#
keyRooms aceita um array com esses valores exatos:
| Valor | Descrição |
|---|---|
walk-in closet | Closet dedicado conectado a uma zona de quartos |
laundry room | Espaço de lavanderia dedicado |
storage room | Sala de armazenamento geral |
utility room | Sala mecânica ou de serviços |
home office | Home office ou estudo dedicado |
garage | Garagem com abertura externa para veículo e acesso interno ao lar |
pantry | Despensa adjacente à cozinha |
combined living-dining | Um ambiente compartilhado de sala e jantar |
balcony | Varanda externa conectada à área social ou ao quarto principal |
O valor legado da Web balcon também é aceito e normalizado para balcony.
Regras:
- Valores em branco são ignorados e valores duplicados são removidos.
- Ambientes principais selecionados são solicitados uma vez.
- Espaços opcionais não selecionados são excluídos do programa de ambientes gerado.
- Se
pantryaparecer em amboskitchenDetails.featuresekeyRooms, apenas uma despensa será solicitada.
Exemplo:
{
"keyRooms": [
"garage",
"home office",
"combined living-dining"
]
}
🖼️ Imagem de Referência#
refImageUrl é opcional e deve ser diretamente acessível pelo servidor da API.
Requisitos:
- Formato: JPG/JPEG, PNG ou WebP.
- Tamanho máximo do arquivo: 20 MB.
- Dimensões mínimas: 128 × 128 px.
- Dimensões máximas: 6,000 × 6,000 px. Imagens maiores são dimensionadas proporcionalmente antes do processamento.
A imagem de referência orienta layout, adjacência, proporções ou estilo visual. Ela não substitui contagens estruturadas de ambientes ou outras restrições rígidas.
🤖 Tipos de Modelo#
| Valor | Descrição |
|---|---|
Base | Padrão. Qualidade equilibrada de geração, saída 1536 × 1024 |
Pro | Saída de maior resolução 2496 × 1664 com tempo de geração esperado mais longo |
Somente Base e Pro são suportados.
Campos não presentes no contrato público da API#
Os clientes da API pública não devem depender dos campos a seguir:
| Campo | Notas |
|---|---|
imageNumbers | O gerador atual sempre retorna uma imagem; este campo não é necessário |
extData | Metadados internos de rastreamento de grupo de tarefas da Web; clientes públicos devem omiti-lo |
isApiCall | Determinado pelo endpoint da API, não pelo corpo da requisição |
genByMember | Metadado interno de geração, não um campo de requisição de Planta Baixa |
Campos legados removidos que não devem ser enviados:
floorplanSetting
roomCounts
grossArea
totalAreaValue
totalAreaUnit
totalAreaType
fullBathrooms
halfBathrooms
halfBathroomRequirement
kitchenType
diningRooms
livingRooms
extras
referenceImage
hasDetailOptions
📥 Exemplos de Criação de Tarefa#
Requisição mínima com intervalos automáticos de quartos#
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"
}'
Requisição 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();
Resposta de sucesso na criação da tarefa#
{
"code": 0,
"message": "success",
"data": 1234567890123456789
}
| Campo | Tipo | Descrição |
|---|---|---|
code | integer | 0 indica que a tarefa foi criada com sucesso |
message | string | Mensagem de resposta |
data | long | ID da tarefa usado para consultar o endpoint de resultado |
2. Obter Resultado da Tarefa#
Retorna o progresso da tarefa e a imagem gerada quando disponível.
Endpointo
GET /api/v1/floorPlan/result?taskId={taskId}
Cabeçalhos da requisição
| Cabeçalho | Obrigatório | Descrição |
|---|---|---|
APIKEY | ✅ Sim | Chave de autenticação da API |
Parâmetros de query
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
taskId | long | ✅ Sim | ID da tarefa retornado pelo endpoint de criação |
Exemplos de requisição de resultado#
cURL
curl -X GET "https://api.ideal.house/api/v1/floorPlan/result?taskId=1234567890123456789" \
-H "APIKEY: your_api_key_here"
Consulta periódica em 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"])
Consulta periódica em 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');
Resposta de tarefa concluída#
{
"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
}
}
}
Resposta de processamento#
{
"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
}
}
Resposta de tarefa falhada#
{
"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
}
}
Campos do resultado#
| Campo | Tipo | Descrição |
|---|---|---|
id | long | ID da tarefa |
status | string | Status atual da tarefa |
waitNumber | integer | Número de tarefas à frente na fila; 0 significa nenhuma tarefa na fila à frente |
percentage | integer | Porcentagem aproximada de conclusão de 0 a 100 |
input | object | Entrada normalizada da tarefa, incluindo intervalos automáticos de quartos quando aplicável |
output | object / null | Saída gerada quando a tarefa é bem-sucedida; caso contrário geralmente null |
output.resultUrl | string | URL assinada da imagem da planta baixa gerada |
output.width | integer | Largura de saída em pixels |
output.height | integer | Altura de saída em pixels |
📊 Status da Tarefa#
| Status | Descrição |
|---|---|
Unprocessed | A tarefa foi criada mas ainda não iniciou |
Processing | A tarefa está sendo processada |
Success | Tarefa concluída e output.resultUrl disponível |
Failed | A tarefa falhou |
Termination | A tarefa foi interrompida ou terminada |
Consulte a cada 3–5 segundos. Consulte Limite de Tarefas da API.
❌ Respostas de Erro#
Todas as respostas de erro usam a estrutura de resposta comum:
{
"code": 1011,
"message": "bedroomAreaRanges size must match bedrooms",
"data": null
}
| Código | Nome | Descrição | Ação sugerida |
|---|---|---|---|
1001 | FAILED | Falha genérica na requisição | Verifique o campo message |
1003 | INTERNAL_ERROR | Erro interno do servidor | Tente novamente mais tarde; entre em contato com o suporte se persistir |
1011 | PARAM_ERROR | Parâmetro de requisição inválido | Verifique contagens, unidades, valores de enumeração e arrays aninhados |
5002 | API_KEY_INVALID | Chave API inválida ou ausente | Verifique o cabeçalho APIKEY |
9010 | SCAN_TEXT_ERROR | O prompt falhou na revisão de conteúdo | Revise o prompt |
9038 | PROHIBITED_CONTENT | A saída gerada contém conteúdo proibido | Ajuste os entradas e tente novamente |
9051 | COINS_NOT_ENOUGH | Créditos insuficientes | Adicione créditos e tente novamente |
Consulte Referência de Códigos de Erro para a lista completa de erros comuns.
🔄 Notas de Integração com a Web#
O aplicativo Web autenticado e a API pública API usam endpoints e métodos de autenticação diferentes:
| Cliente | Endpoint | Autenticação |
|---|---|---|
| Aplicativo Web | POST /floorPlan/generate | Cabeçalho de token token |
| API pública API | POST /api/v1/floorPlan/generate | Cabeçalho APIKEY |
Os formatos dos campos de negócio estão alinhados, mas clientes da API pública API devem seguir os limites no lado do servidor e o contrato público neste documento. Em particular:
- Clientes Web podem incluir
imageNumberseextDatainternos; clientes públicos não precisam deles. - A API pública API determina metadados de chamada API com base no endpoint e nas credenciais. Campos de requisição como
isApiCallegenByMembersão desnecessários. balconé aceito por compatibilidade e normalizado parabalcony; novas integrações devem enviarbalcony.- Os limites atuais do servidor público permanecem
0–5quartos e0.5–4banheiros, mesmo se outra interface apresentar seletores mais amplos temporariamente.