O motor de home staging virtual por trás do aplicativo web agora está disponível como API HTTP. Você envia a foto de um ambiente, informa um tipo de cômodo e um estilo de mobília, e a imagem mobiliada volta na mesma resposta. Custa $0.15 por imagem, não há assinatura, nem mínimo, nem fatura mensal, e a documentação de referência está em stagify.ai/developers.html.
Este texto é o que uma página de referência não consegue ser: por que a API tem o formato que tem, e o punhado de coisas que vão te derrubar na primeira tarde.
A API inteira é um único endpoint
Existe exatamente uma chamada que custa dinheiro.
curl https://stagify.ai/api/v1/renders \
-H "Authorization: Bearer $STAGIFY_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-F "image=@living-room.jpg" \
-F "roomType=Living room" \
-F "furnitureStyle=modern" \
-F "labelVirtuallyStaged=true"
Essa é a integração. A resposta traz a imagem mobiliada como data URL, junto com um status e um id de requisição. Todo o resto da API é gratuito e somente leitura: GET /api/v1/options entrega os valores aceitos de cada enum, GET /api/v1/me informa se sua chave funciona, GET /api/v1/credits reporta o saldo e GET /api/v1/renders/{id} recupera um render específico.
As requisições são multipart/form-data, porque você está enviando uma fotografia e base64 num corpo JSON custaria um terço a mais de bytes por nada. As imagens são JPEG, PNG ou WebP de até 25 MB, e o que é verificado é o tipo MIME, não a extensão do arquivo.
Por que não existe fila de trabalhos
O desenho óbvio para uma API de imagens lenta é aceitar a requisição, devolver um id de job e fazer o cliente consultar o resultado. Deliberadamente não fizemos isso, e vale dizer o motivo, porque de fora parece um atalho e não é.
Este aplicativo não tem fila de trabalhos alguma. Adicionar uma só para a API significaria introduzir uma fila cujos jobs vivem em um único processo, num host que reinicia a cada deploy. Quando isso acontece no meio de um render, o crédito do cliente já foi gasto e não sobra socket nenhum para avisá-lo. Essa falha é estritamente pior que uma conexão caída, porque uma conexão caída pode ser repetida com a mesma chave de idempotência e não custa nada.
Então um render segura a conexão até terminar, o que leva de alguns segundos a alguns minutos. Configure o read timeout do seu cliente em 300 segundos. O padrão na maioria das bibliotecas HTTP é 30 ou 60, e um cliente que desiste aos 30 segundos vai parecer uma API que falha o tempo todo enquanto gasta créditos em silêncio em renders que nunca recolhe.
status: "succeeded", e GET /api/v1/renders/{id} já existe. Se algum dia acrescentarmos uma fila, ela chegará como um novo valor de status no mesmo endpoint, não como uma API nova. Trate qualquer status diferente de succeeded como “vá consultar o GET” e seu cliente já está preparado para o futuro.
O mesmo raciocínio limita variations a 1. Uma requisição é um crédito é uma imagem é um estorno, sem aritmética de distribuição parcial em nenhum ponto do dinheiro. Se você quer três versões de um ambiente, dispare três requisições simultâneas: assim você obtém mais paralelismo do que o fan-out jamais deu.
Créditos pré-pagos, e por que isso é um recurso de segurança
Você compra créditos antecipadamente. Cada render bem-sucedido gasta um, e um render que falha é estornado automaticamente, então você nunca paga por uma foto que não recebeu. Os pacotes começam em 20 créditos por $3, e o preço por imagem cai conforme eles crescem, até $0.12 por imagem no pacote de 500 créditos. A tabela atualizada está na página de documentação da API, gerada a partir dos mesmos dados contra os quais o webhook de pagamento cobra, de modo que ela não pode divergir do que você é de fato cobrado.
Cobrança por uso teria sido mais fácil de construir. O pré-pago é melhor para você num ponto específico: uma chave roubada pode te custar no máximo o saldo que restar nela. Não há fatura no fim do mês, não há excedente, e não existe cenário em que uma chave vazada vire uma conta de quatro dígitos antes de alguém perceber. A parada seca no zero é o objetivo, não uma limitação, e é também por isso que toda resposta carrega um cabeçalho X-Stagify-Credits-Remaining: você vê o muro se aproximar sem precisar consultar.
As chaves são destinadas apenas a uso servidor a servidor. A API não envia cabeçalhos CORS, então o JavaScript do navegador não consegue chamá-la, e isso é proposital, não uma omissão que pretendemos corrigir. Uma chave alcançável a partir de um navegador é uma chave vazada. Mostramos uma chave nova exatamente uma vez, guardamos apenas um hash dela e revogamos na hora pelo painel de chaves da API.
Quatro coisas que vão te derrubar
Toda API tem comportamentos perfeitamente razoáveis depois de explicados e desconcertantes antes disso. Aqui estão os nossos, ditos com clareza em vez de deixados numa tabela de parâmetros.
roomTypediferencia maiúsculas e espaços, e um valor errado não é rejeitado. Ele é escrito no prompt como texto livre, entãoLiving Roomnão éLiving room. Você vai receber um render, só que não o que queria, e terá pago por ele. O conjunto aceito éBedroom,Living room,Dining room,Kitchen,Office,Bathroom,OutdoorseDorm. Puxe-o deGET /api/v1/optionsem vez de redigitá-lo no seu próprio dropdown.- Um
furnitureStylenão reconhecido vira silenciosamentestandard. Mesma classe de problema, sintoma mais discreto: um erro de digitação no nome de um estilo não dá erro, só entrega o visual padrão em todas as imagens do lote. removeFurnitureaceitatrueouon, e nada mais. Não1, nãoyes. Os dois são lidos como false, e você recebe uma foto mobiliada com o sofá antigo ainda lá. Seu companheirokeepFurnitureaceita texto livre nomeando o que deve ficar no lugar, até 500 caracteres, e só é lido quandoremoveFurnitureestá realmente ativo.- Envie uma
Idempotency-Keyem toda requisição. Omiti-la é permitido e significa nenhuma proteção contra repetição, que é o padrão honesto; não vamos derivá-la da sua foto, porque então dois renders genuinamente distintos do mesmo ambiente colidiriam e o segundo chamador receberia a imagem do primeiro. Repita com o mesmo valor e uma requisição concluída é reproduzida do armazenamento comX-Stagify-Replayed: truee sem segunda cobrança. Reutilize uma com parâmetros diferentes e você recebe422 IDEMPOTENCY_KEY_REUSED, que é a API dizendo que o seu gerador de chaves tem um bug.
Fora esses, os parâmetros que vale conhecer espelham o aplicativo web: additionalPrompt para direção em texto livre, e até cinco fotos de referência furnitureImage para o modelo se guiar.
A etiqueta de divulgação não pode ser desligada
A maioria das regras de MLS, e a orientação da NAR por trás delas, exige que uma foto de anúncio mobiliada digitalmente diga que é mobiliada digitalmente; desde janeiro de 2026, a AB 723 da Califórnia exige isso por lei. Nós escrevemos a versão estado a estado disso com detalhes.
labelVirtuallyStaged queima a divulgação nos pixels em vez de anexá-la como metadado, porque metadados são removidos por praticamente toda ferramenta pela qual uma imagem passa a caminho de um portal. Você controla a aparência: stampStyle escolhe entre dark, light, minimal e banner, stampScale dimensiona entre 0.7 e 1.6, e stampLang a renderiza em qualquer um de onze idiomas.
O que você não controla é o modo de falha. Se a etiqueta é pedida e não pode ser aplicada, a imagem é retida em vez de entregue sem etiqueta. A chamada responde 500 DISCLOSURE_STAMP_FAILED e seu crédito é estornado. Não há flag para desativar isso, nem padrão por chave que desligue em silêncio. A alternativa é entregar uma foto mobiliada sem etiqueta a um cliente que pediu explicitamente que fosse etiquetada, que é o único bug deste sistema capaz de colocar alguém diante de um regulador.
Erros, e a única regra sobre eles
Toda falha responde com um corpo JSON que traz tanto uma string error quanto um code. Ramifique pelo código, nunca pela mensagem. Mensagens são reescritas; códigos não.
Os que você vai realmente encontrar em produção são 402 INSUFFICIENT_CREDITS (recarregue; o corpo traz o saldo restante), 409 CONCURRENCY_LIMIT (renders demais em andamento numa mesma chave; a permissão padrão é três por vez, então espere um segundo e tente de novo), 409 REQUEST_IN_FLIGHT (você repetiu uma chave de idempotência que ainda está rodando, então aguarde em vez de insistir), 429 RATE_LIMITED e 422 NO_IMAGE_GENERATED, que significa que o modelo não devolveu nada e é estornado automaticamente. O limite de renders é atualmente de 60 por chave a cada cinco minutos; se você precisar de mais, ou de uma fatura em vez de cartão, escreva para nós.
Repare no padrão em todos eles: tudo que falha depois de uma cobrança é estornado. Essa invariante é a razão de a API ser síncrona e a razão de variations estar limitado a um, e é a coisa pela qual abriríamos mão de funcionalidades.
Para quem isto serve, e para quem não
A API existe para os casos em que o staging é uma etapa no pipeline de outra pessoa e não algo que alguém senta para fazer:
- Portais de anúncios e fornecedores de IDX que mobiliam na ingestão, para que a foto de ambiente vazio de um corretor já chegue mobiliada à grade de resultados.
- Ferramentas de entrega de fotógrafos. Se você já tem um script que renomeia, redimensiona e envia um ensaio, o staging vira mais uma etapa dele em vez de uma noite num aplicativo web.
- Produtos de PropTech que querem staging como recurso sem construir o encanamento do modelo, a marcação da divulgação e o tratamento de falhas por trás.
- Trabalho em lote de qualquer tamanho, porque o preço é por imagem e o piso é $3.
Ela decididamente não é para quem vai mobiliar uma casa só. Se esse é o seu caso, o aplicativo web faz mais que a API, já que o Masking Studio e o AI Designer não têm equivalente na API, e ele é gratuito, sem marca d'água. Pagar $0.15 para fazer em código o que dá para fazer de graça num navegador seria uma escolha estranha, e preferimos dizer isso a te vender um pacote de créditos.
Começando
Crie uma chave na página de chaves da API, compre o menor pacote e gaste um crédito numa foto cujo resultado você já conhece. Depois leia a referência com calma antes de escrever o laço em lote, em especial a tabela de idempotência. Vinte créditos são $3, e isso é mais que suficiente para descobrir se isto encaixa no seu pipeline.
Fontes e notas
- Documentação da API do Stagify. A referência autoritativa para endpoints, parâmetros, códigos de erro e preços atuais dos pacotes de crédito. Onde este artigo e aquela página divergirem, aquela página está certa: a tabela de preços dela é gerada a partir dos mesmos dados contra os quais o webhook de pagamento cobra, e este aqui é texto escrito num dia específico.
- Painel de chaves da API e créditos. Crie e revogue chaves, compre pacotes e veja o saldo. Somente no desktop.
- Os limites de taxa, a permissão de concorrência por chave e os preços dos pacotes citados aqui são os padrões no momento da escrita e estão sujeitos a mudança. Limites maiores e cobrança por fatura estão disponíveis sob demanda em team@stagify.ai.
- A AB 723 da Califórnia e as regras de divulgação das MLS mencionadas acima são tratadas com fontes em É preciso declarar o home staging virtual? em vez de repetidas aqui.