# ImobyFlow API — referência completa (1.0.0) Base: https://api.imobyflow.com.br/v1 Autenticação: `Authorization: Bearer imob_live_…` — só no cabeçalho, nunca na URL. Língua: `Accept-Language: pt-BR` ou `en`. ## Convenções - Acrescentar não quebra: campos, eventos, rotas e valores novos podem chegar a qualquer momento. O seu sistema deve tolerar campo que ele não conhece. - O que quebra uma integração existente sai numa versão nova (`/v2`). A versão anterior continua funcionando por pelo menos 12 meses depois do aviso, publicado aqui e mandado por e-mail ao dono da conta. - Os valores de código (`VENDA`, `ACTIVE`, os subtipos) são os mesmos da plataforma, sem tradução no meio. - Erros em `application/problem+json` (RFC 9457): `type`, `title`, `status`, `code`, `requestId`, `detail` e `invalidParams` (todos os problemas de uma vez). - Listas: `limit` e `cursor`; siga o `nextCursor` até ele vir nulo. - Escrita: campo ausente não apaga; `null` limpa; campo desconhecido é erro 400; nada mudou = `UNCHANGED`, sem escrita. - `?dryRun=true` valida e diz o que aconteceria, sem gravar. `Idempotency-Key` (até 100 caracteres) torna a re-tentativa segura por 24 h. ## Conta A conta dona da chave: plano, cota de imóveis, permissões da chave, limites e o uso do mês. ### GET /me — Quem sou eu A primeira chamada de toda integração: confirma que a chave vale e mostra a conta, as permissões desta chave, os limites e o uso do mês. - Permissão: qualquer chave válida Resposta 200: - `data` (Me): Conta. Erros: só os comuns ```bash curl -X GET 'https://api.imobyflow.com.br/v1/me' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' ``` ## Listas de valores Os valores aceitos em cada campo de código: tipos de imóvel, finalidades, status, etapas, permissões e eventos. São os MESMOS valores do banco — não existe tradução no meio. ### GET /reference/property-types — Tipos de imóvel As categorias e os subtipos. É o subtipo que vai no campo `type`. - Permissão: qualquer chave válida Resposta 200: - `data` (array): A lista. Erros: só os comuns ```bash curl -X GET 'https://api.imobyflow.com.br/v1/reference/property-types' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' ``` ### GET /reference/purposes — Finalidades Venda e locação. - Permissão: qualquer chave válida Resposta 200: - `data` (array): A lista. Erros: só os comuns ```bash curl -X GET 'https://api.imobyflow.com.br/v1/reference/purposes' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' ``` ### GET /reference/property-statuses — Status do imóvel Os status que o imóvel pode ter. - Permissão: qualquer chave válida Resposta 200: - `data` (array): A lista. Erros: só os comuns ```bash curl -X GET 'https://api.imobyflow.com.br/v1/reference/property-statuses' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' ``` ### GET /reference/lead-statuses — Etapas do cliente As etapas do atendimento. - Permissão: qualquer chave válida Resposta 200: - `data` (array): A lista. Erros: só os comuns ```bash curl -X GET 'https://api.imobyflow.com.br/v1/reference/lead-statuses' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' ``` ### GET /reference/partnership-statuses — Etapas da parceria As etapas da parceria. - Permissão: qualquer chave válida Resposta 200: - `data` (array): A lista. Erros: só os comuns ```bash curl -X GET 'https://api.imobyflow.com.br/v1/reference/partnership-statuses' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' ``` ### GET /reference/construction-stages — Estágios da obra Os estágios de um lançamento. - Permissão: qualquer chave válida Resposta 200: - `data` (array): A lista. Erros: só os comuns ```bash curl -X GET 'https://api.imobyflow.com.br/v1/reference/construction-stages' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' ``` ### GET /reference/scopes — Permissões As permissões que uma chave pode ter. - Permissão: qualquer chave válida Resposta 200: - `data` (array): A lista. Erros: só os comuns ```bash curl -X GET 'https://api.imobyflow.com.br/v1/reference/scopes' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' ``` ### GET /reference/event-types — Tipos de evento Os eventos, com a permissão de leitura que dá acesso a cada um. - Permissão: qualquer chave válida Resposta 200: - `data` (array): A lista. Erros: só os comuns ```bash curl -X GET 'https://api.imobyflow.com.br/v1/reference/event-types' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' ``` ## Cidades e bairros O catálogo de localização: cidade pelo código do IBGE e bairro pelo identificador do catálogo. Bairro é fechado contra o catálogo — é por ele que o imóvel entra nas recomendações. ### GET /geo/cities — Cidades As cidades do catálogo, com o código do IBGE. - Permissão: qualquer chave válida - `uf`: Só as de um estado (2 letras). - `q`: Parte do nome (sem acento conta igual). - `limit`: Itens por página: de 1 a 1000 (padrão 100). - `cursor`: O `nextCursor` da página anterior. A lista acabou quando ele vem nulo. Ele vale só para esta rota e esta conta. Resposta 200: - `data` (array): As cidades. - `nextCursor` (string; nullable): Próxima página. - `total` (integer): Total no filtro. Erros: `invalid_param` ```bash curl -X GET 'https://api.imobyflow.com.br/v1/geo/cities' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' ``` ### GET /geo/cities/{cityId}/neighborhoods — Bairros de uma cidade Os bairros do catálogo. O `neighborhoodSlug` daqui é o que garante que o imóvel entra nas recomendações. - Permissão: qualquer chave válida - `cityId`: Código do IBGE (7 dígitos). - `limit`: Itens por página: de 1 a 1000 (padrão 100). - `cursor`: O `nextCursor` da página anterior. A lista acabou quando ele vem nulo. Ele vale só para esta rota e esta conta. Resposta 200: - `data` (array): Os bairros. - `nextCursor` (string; nullable): Próxima página. - `total` (integer): Total. Erros: `invalid_param`, `not_found` ```bash curl -X GET 'https://api.imobyflow.com.br/v1/geo/cities/4106902/neighborhoods' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' ``` ## Imóveis A carteira da conta: ler, sincronizar pelo código do seu sistema, mudar status, confirmar disponibilidade, enviar fotos por endereço e mandar para a lixeira. ### GET /properties — Listar a carteira A carteira da conta, mais recentes antes, com filtros. Para sincronizar, use `updatedSince` — ou os eventos. - Permissão: `properties:read` - `limit`: Itens por página: de 1 a 100 (padrão 50). - `cursor`: O `nextCursor` da página anterior. A lista acabou quando ele vem nulo. Ele vale só para esta rota e esta conta. - `status`: Status (`DELETED` = lixeira). - `purpose`: Finalidade. - `type`: Subtipo. - `citySlug`: Identificador da cidade no catálogo. - `updatedSince`: Só o que mudou desde esta data/hora (ISO 8601, UTC). - `radar`: `pending` = só quem tem pendência para as recomendações; `ready` = só quem está pronto. Resposta 200: - `data` (array): Os imóveis. - `nextCursor` (string; nullable): Cursor da próxima página (nulo = acabou). Erros: `invalid_param`, `invalid_cursor`, `upstream_timeout`, `upstream_busy` ```bash curl -X GET 'https://api.imobyflow.com.br/v1/properties' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' ``` ### GET /properties/by-ref/{ref} — Um imóvel pelo seu código O imóvel pelo código do seu sistema (`externalRef`). - Permissão: `properties:read` - `ref`: O código do imóvel no seu sistema (até 80 caracteres; codifique espaço e `/`). Resposta 200: - `data` (Property): O imóvel. Erros: `not_found` ```bash curl -X GET 'https://api.imobyflow.com.br/v1/properties/by-ref/AP1234' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' ``` ### GET /properties/{propertyId} — Um imóvel O imóvel, com a situação nas recomendações, na análise e na confirmação. - Permissão: `properties:read` - `propertyId`: Id do imóvel (`prop-…`). Resposta 200: - `data` (Property): O imóvel. Erros: `not_found` ```bash curl -X GET 'https://api.imobyflow.com.br/v1/properties/prop-3f9a1c2b7d4e' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' ``` ### GET /feed — Estado da sincronização do feed Como terminou a última sincronização do link do CRM e se há outra agendada — para conferir o resultado depois de um `POST /v1/feed/sync`. Nunca traz o link nem o token. - Permissão: `properties:read` Resposta 200: - `data` (FeedSync): O estado. Erros: só os comuns ```bash curl -X GET 'https://api.imobyflow.com.br/v1/feed' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' ``` ### POST /feed/sync — Sincronizar o feed agora Avise depois de mudar a carteira no CRM: a ImobyFlow busca o MESMO link do feed, pela mesma sincronização de 6 em 6 horas — só o que mudou é gravado. A primeira chamada de cada janela de 10 minutos sincroniza na hora; as seguintes deixam UMA sincronização agendada para o fim da janela, então nenhuma alteração espera as 6 horas e chamar a cada mudança não sobrecarrega nada. Acompanhe por `GET /v1/feed` ou pelos eventos dos imóveis. - Permissão: `properties:write` - Aceita `?dryRun=true` - Aceita `Idempotency-Key` Resposta 202 (200 quando já havia uma agendada (`ALREADY_SCHEDULED`) e no ensaio.): - `data` (FeedSync): O estado. - `result` (FeedSyncResult): O desfecho. Erros: `feed_not_configured`, `invalid_idempotency_key`, `idempotency_key_reused`, `idempotency_in_progress`, `request_refused` ```bash # Modo ensaio: nada é gravado. Tire o ?dryRun=true para gravar de verdade. curl -X POST 'https://api.imobyflow.com.br/v1/feed/sync?dryRun=true' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' \ -H "Idempotency-Key: $(uuidgen)" ``` ### PUT /properties/by-ref/{ref} — Criar ou atualizar pelo seu código O caminho natural de sincronização: cria o imóvel se o código for novo (201) ou atualiza o que existe (200). Campo ausente não apaga; nada mudou = `UNCHANGED`, sem escrita. A edição feita na tela vence e volta em `result.conflicts`. - Permissão: `properties:write` - Aceita `?dryRun=true` - Aceita `Idempotency-Key` - `ref`: O código do imóvel no seu sistema (até 80 caracteres; codifique espaço e `/`). Corpo: - `externalRef` (string): O código do imóvel no seu sistema (só no POST; no PUT ele vai no caminho). - `title` (string): Título. Marcação HTML é removida. - `description` (string): Descrição. `
` e `

` viram quebra de linha; o resto da marcação sai. - `type` (string; APARTAMENTO | CASA_RUA | CASA_CONDOMINIO | CASA_VILA | STUDIO | FLAT | COBERTURA | SALA_COMERCIAL | LOJA_PONTO | GALPAO | PREDIO | TERRENO_RUA | TERRENO_CONDOMINIO | CHACARA_SITIO | FAZENDA): Subtipo. - `purposes` (array): Finalidades. - `salePrice` (number; nullable): Preço de venda, em reais. Obrigatório com `VENDA`. - `rentPrice` (number; nullable): Aluguel, em reais. Obrigatório com `LOCACAO`. - `address` (AddressInput): Endereço. - `bedrooms` (integer; nullable): Quartos. - `suites` (integer; nullable): Suítes. - `bathrooms` (integer; nullable): Banheiros. - `parkingSpots` (integer; nullable): Vagas. - `area` (number; nullable): Área privativa total, em m². - `privateArea` (number; nullable): Área coberta, em m². - `listingUrl` (string; nullable): Endereço do anúncio no seu site (http ou https). - `captadorName` (string; nullable): Nome do captador em texto. - `captadorAccountId` (string; nullable): Id do corretor responsável da equipe. - `partnershipTerms` (PartnershipTerms): Condições para parceiros. - `photos` (array): Até 30 endereços; a 1ª é a capa. Baixadas depois da resposta (veja `photoSync`). Ausente = a galeria fica como está; lista vazia = tirar as fotos. Resposta 200 (201 quando cria.): - `data` (Property): O objeto como ficou. - `result` (PropertyWriteResult): O desfecho. Erros: `invalid_body`, `invalid_param`, `payload_too_large`, `invalid_idempotency_key`, `idempotency_key_reused`, `idempotency_in_progress`, `request_refused`, `feed_sync_active`, `plan_limit_reached`, `property_in_trash`, `invalid_property`, `concurrent_write`, `upstream_timeout` ```bash # Modo ensaio: nada é gravado. Tire o ?dryRun=true para gravar de verdade. curl -X PUT 'https://api.imobyflow.com.br/v1/properties/by-ref/AP1234?dryRun=true' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' \ -H "Idempotency-Key: $(uuidgen)" \ -H 'Content-Type: application/json' \ --data @- <<'JSON' { "title": "Apartamento 3 quartos no Bigorrilho", "type": "APARTAMENTO", "purposes": [ "VENDA" ], "salePrice": 890000, "address": { "cityId": "4106902", "neighborhoodSlug": "bigorrilho", "street": "Rua Padre Anchieta", "number": "1500", "complement": "Ap 82" }, "bedrooms": 3, "suites": 1, "bathrooms": 2, "parkingSpots": 2, "area": 98, "photos": [ "https://www.suaimobiliaria.com.br/fotos/AP1234/1.jpg", "https://www.suaimobiliaria.com.br/fotos/AP1234/2.jpg" ] } JSON ``` ### POST /properties — Cadastrar um imóvel Cria um imóvel. O mínimo: `type`, `purposes`, o preço de cada finalidade e o endereço com a cidade. Código que já existe → 409 com o id. - Permissão: `properties:write` - Aceita `?dryRun=true` - Aceita `Idempotency-Key` Corpo: - `externalRef` (string): O código do imóvel no seu sistema (só no POST; no PUT ele vai no caminho). - `title` (string): Título. Marcação HTML é removida. - `description` (string): Descrição. `
` e `

` viram quebra de linha; o resto da marcação sai. - `type` (string; APARTAMENTO | CASA_RUA | CASA_CONDOMINIO | CASA_VILA | STUDIO | FLAT | COBERTURA | SALA_COMERCIAL | LOJA_PONTO | GALPAO | PREDIO | TERRENO_RUA | TERRENO_CONDOMINIO | CHACARA_SITIO | FAZENDA): Subtipo. - `purposes` (array): Finalidades. - `salePrice` (number; nullable): Preço de venda, em reais. Obrigatório com `VENDA`. - `rentPrice` (number; nullable): Aluguel, em reais. Obrigatório com `LOCACAO`. - `address` (AddressInput): Endereço. - `bedrooms` (integer; nullable): Quartos. - `suites` (integer; nullable): Suítes. - `bathrooms` (integer; nullable): Banheiros. - `parkingSpots` (integer; nullable): Vagas. - `area` (number; nullable): Área privativa total, em m². - `privateArea` (number; nullable): Área coberta, em m². - `listingUrl` (string; nullable): Endereço do anúncio no seu site (http ou https). - `captadorName` (string; nullable): Nome do captador em texto. - `captadorAccountId` (string; nullable): Id do corretor responsável da equipe. - `partnershipTerms` (PartnershipTerms): Condições para parceiros. - `photos` (array): Até 30 endereços; a 1ª é a capa. Baixadas depois da resposta (veja `photoSync`). Ausente = a galeria fica como está; lista vazia = tirar as fotos. Resposta 201: - `data` (Property): O objeto como ficou. - `result` (PropertyWriteResult): O desfecho. Erros: `invalid_body`, `invalid_param`, `payload_too_large`, `invalid_idempotency_key`, `idempotency_key_reused`, `idempotency_in_progress`, `request_refused`, `feed_sync_active`, `plan_limit_reached`, `external_ref_exists`, `invalid_property`, `concurrent_write` ```bash # Modo ensaio: nada é gravado. Tire o ?dryRun=true para gravar de verdade. curl -X POST 'https://api.imobyflow.com.br/v1/properties?dryRun=true' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' \ -H "Idempotency-Key: $(uuidgen)" \ -H 'Content-Type: application/json' \ --data @- <<'JSON' { "externalRef": "AP1234", "title": "Apartamento 3 quartos no Bigorrilho", "type": "APARTAMENTO", "purposes": [ "VENDA" ], "salePrice": 890000, "address": { "cityId": "4106902", "neighborhoodSlug": "bigorrilho", "street": "Rua Padre Anchieta", "number": "1500", "complement": "Ap 82" }, "bedrooms": 3, "suites": 1, "bathrooms": 2, "parkingSpots": 2, "area": 98, "photos": [ "https://www.suaimobiliaria.com.br/fotos/AP1234/1.jpg", "https://www.suaimobiliaria.com.br/fotos/AP1234/2.jpg" ] } JSON ``` ### PATCH /properties/{propertyId} — Alterar parte de um imóvel Muda só o que vier. Para limpar um campo, mande `null`. - Permissão: `properties:write` - Aceita `?dryRun=true` - Aceita `Idempotency-Key` - `propertyId`: Id do imóvel (`prop-…`). Corpo: - `externalRef` (string): O código do imóvel no seu sistema (só no POST; no PUT ele vai no caminho). - `title` (string): Título. Marcação HTML é removida. - `description` (string): Descrição. `
` e `

` viram quebra de linha; o resto da marcação sai. - `type` (string; APARTAMENTO | CASA_RUA | CASA_CONDOMINIO | CASA_VILA | STUDIO | FLAT | COBERTURA | SALA_COMERCIAL | LOJA_PONTO | GALPAO | PREDIO | TERRENO_RUA | TERRENO_CONDOMINIO | CHACARA_SITIO | FAZENDA): Subtipo. - `purposes` (array): Finalidades. - `salePrice` (number; nullable): Preço de venda, em reais. Obrigatório com `VENDA`. - `rentPrice` (number; nullable): Aluguel, em reais. Obrigatório com `LOCACAO`. - `address` (AddressInput): Endereço. - `bedrooms` (integer; nullable): Quartos. - `suites` (integer; nullable): Suítes. - `bathrooms` (integer; nullable): Banheiros. - `parkingSpots` (integer; nullable): Vagas. - `area` (number; nullable): Área privativa total, em m². - `privateArea` (number; nullable): Área coberta, em m². - `listingUrl` (string; nullable): Endereço do anúncio no seu site (http ou https). - `captadorName` (string; nullable): Nome do captador em texto. - `captadorAccountId` (string; nullable): Id do corretor responsável da equipe. - `partnershipTerms` (PartnershipTerms): Condições para parceiros. - `photos` (array): Até 30 endereços; a 1ª é a capa. Baixadas depois da resposta (veja `photoSync`). Ausente = a galeria fica como está; lista vazia = tirar as fotos. Resposta 200: - `data` (Property): O objeto como ficou. - `result` (PropertyWriteResult): O desfecho. Erros: `invalid_body`, `invalid_param`, `payload_too_large`, `invalid_idempotency_key`, `idempotency_key_reused`, `idempotency_in_progress`, `request_refused`, `not_found`, `feed_sync_active`, `property_in_trash`, `invalid_property` ```bash # Modo ensaio: nada é gravado. Tire o ?dryRun=true para gravar de verdade. curl -X PATCH 'https://api.imobyflow.com.br/v1/properties/prop-3f9a1c2b7d4e?dryRun=true' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' \ -H "Idempotency-Key: $(uuidgen)" \ -H 'Content-Type: application/json' \ --data @- <<'JSON' { "salePrice": 870000 } JSON ``` ### POST /properties/{propertyId}/status — Mudar o status Disponível, arquivado, vendido ou alugado — a mesma função da tela: só disponível ocupa a cota do plano, e quem negocia o imóvel é avisado. Vendido não volta pelo feed. - Permissão: `properties:write` - Aceita `?dryRun=true` - Aceita `Idempotency-Key` - `propertyId`: Id do imóvel (`prop-…`). Corpo: - `status` (string; ACTIVE | INACTIVE | SOLD | RENTED): O novo status. Resposta 200: - `data` (Property): O objeto como ficou. - `result` (PropertyWriteResult): O desfecho. Erros: `invalid_body`, `invalid_param`, `payload_too_large`, `invalid_idempotency_key`, `idempotency_key_reused`, `idempotency_in_progress`, `request_refused`, `not_found`, `plan_limit_reached` ```bash # Modo ensaio: nada é gravado. Tire o ?dryRun=true para gravar de verdade. curl -X POST 'https://api.imobyflow.com.br/v1/properties/prop-3f9a1c2b7d4e/status?dryRun=true' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' \ -H "Idempotency-Key: $(uuidgen)" \ -H 'Content-Type: application/json' \ --data @- <<'JSON' { "status": "SOLD" } JSON ``` ### POST /properties/confirm — Confirmar disponibilidade em lote A régua dos 60 dias tira do ar o imóvel que ninguém confirma. Mande até 200 `ids` e `refs`; confirmado há menos de 24 h não regrava (`ALREADY_CONFIRMED`). - Permissão: `properties:write` - Aceita `?dryRun=true` - Aceita `Idempotency-Key` Corpo: - `ids` (array): Ids dos imóveis. - `refs` (array): Códigos do seu sistema. Resposta 200: - `data` (array): O desfecho de cada imóvel. - `result` (object): O resumo. - `result.dryRun` (boolean): Ensaio. - `result.summary` (object): Contagem por desfecho. Erros: `invalid_body`, `invalid_param`, `payload_too_large`, `invalid_idempotency_key`, `idempotency_key_reused`, `idempotency_in_progress`, `request_refused` ```bash # Modo ensaio: nada é gravado. Tire o ?dryRun=true para gravar de verdade. curl -X POST 'https://api.imobyflow.com.br/v1/properties/confirm?dryRun=true' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' \ -H "Idempotency-Key: $(uuidgen)" \ -H 'Content-Type: application/json' \ --data @- <<'JSON' { "refs": [ "AP1234", "CA0042" ] } JSON ``` ### DELETE /properties/{propertyId} — Mandar para a lixeira Lixeira de 30 dias (restaurável pela tela). Trava de encolhimento: no máximo 20% da carteira (e pelo menos 10) em 24 horas — um laço no seu sistema não esvazia a carteira. Com o feed do CRM ligado, quem tira imóvel do ar é o feed. - Permissão: `properties:write` - Aceita `?dryRun=true` - Aceita `Idempotency-Key` - `propertyId`: Id do imóvel (`prop-…`). Resposta 200: - `data` (Property): O objeto como ficou. - `result` (PropertyWriteResult): O desfecho. Erros: `invalid_param`, `invalid_idempotency_key`, `idempotency_key_reused`, `idempotency_in_progress`, `request_refused`, `not_found`, `shrink_guard`, `feed_sync_active` ```bash # Modo ensaio: nada é gravado. Tire o ?dryRun=true para gravar de verdade. curl -X DELETE 'https://api.imobyflow.com.br/v1/properties/prop-3f9a1c2b7d4e?dryRun=true' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' \ -H "Idempotency-Key: $(uuidgen)" ``` ## Clientes Os clientes da conta, com o perfil de busca que liga as recomendações: ler, sincronizar pelo código do seu sistema, mover no funil, arquivar e registrar atendimentos. ### GET /leads — Listar clientes Os clientes da conta, mais recentes antes, com filtros. - Permissão: `leads:read` - `limit`: Itens por página: de 1 a 100 (padrão 50). - `cursor`: O `nextCursor` da página anterior. A lista acabou quando ele vem nulo. Ele vale só para esta rota e esta conta. - `state`: `ACTIVE` (padrão), `ARCHIVED` ou `DELETED`. - `status`: Etapa. - `ownerAccountId`: Só os de um corretor. - `updatedSince`: Só o que mudou desde esta data/hora (ISO 8601, UTC). - `radar`: `pending` = só quem tem pendência para as recomendações; `ready` = só quem está pronto. Resposta 200: - `data` (array): Os clientes. - `nextCursor` (string; nullable): Cursor da próxima página (nulo = acabou). Erros: `invalid_param`, `invalid_cursor`, `upstream_timeout`, `upstream_busy` ```bash curl -X GET 'https://api.imobyflow.com.br/v1/leads' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' ``` ### GET /leads/{leadId} — Um cliente O cliente, com o perfil de busca e a situação nas recomendações. - Permissão: `leads:read` - `leadId`: Id do cliente (`lead-…`). Resposta 200: - `data` (Lead): O cliente. Erros: `not_found` ```bash curl -X GET 'https://api.imobyflow.com.br/v1/leads/lead-7c2e9a1b3d5f' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' ``` ### GET /leads/by-ref/{ref} — Um cliente pelo seu código O cliente pelo código do seu sistema. - Permissão: `leads:read` - `ref`: O código do cliente no seu sistema (até 80 caracteres). Resposta 200: - `data` (Lead): O cliente. Erros: `not_found` ```bash curl -X GET 'https://api.imobyflow.com.br/v1/leads/by-ref/CLI-889' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' ``` ### PUT /leads/by-ref/{ref} — Criar, atualizar ou vincular pelo seu código Cria o cliente (201), atualiza (200) — ou VINCULA: o código é novo, mas a pessoa já está aqui pelo telefone ou e-mail (veio de um portal, da planilha); o código passa a apontar para ela (`LINKED`), sem um segundo cliente. Na criação, `consentGiven: true` é obrigatório. - Permissão: `leads:write` - Aceita `?dryRun=true` - Aceita `Idempotency-Key` - `ref`: O código do cliente no seu sistema (até 80 caracteres). Corpo: - `externalRef` (string): O código do cliente no seu sistema (só no POST). - `name` (string): Nome. Obrigatório na criação. - `phones` (array): Até 5 telefones. Na criação, telefone ou e-mail. - `email` (string; nullable): E-mail. - `status` (string; NEW | ATTENDING | PROPOSAL | WON | LOST): Etapa do atendimento. - `notes` (string): Anotações. - `preApproved` (boolean): Crédito pré-aprovado. - `sharedToNetwork` (boolean): O perfil pode receber imóveis de parceiros. - `interest` (InterestInput): Perfil de busca. - `ownerAccountId` (string): O corretor responsável, pelo id. - `ownerEmail` (string): O corretor responsável, pelo e-mail — é como o seu sistema o conhece. Sem responsável, vale a distribuição da imobiliária. - `lastActivityAt` (string): A última movimentação no SEU sistema. Só anda para a frente. Mais de 60 dias atrás na criação = o cliente entra arquivado (base histórica). - `consentGiven` (boolean): Obrigatório `true` na criação: a imobiliária declara ter a base legal para tratar o dado (Termos da API). Resposta 200 (201 quando cria.): - `data` (Lead): O objeto como ficou. - `result` (LeadWriteResult): O desfecho. Erros: `invalid_body`, `invalid_param`, `payload_too_large`, `invalid_idempotency_key`, `idempotency_key_reused`, `idempotency_in_progress`, `request_refused`, `consent_required`, `lead_linked_to_other_ref`, `lead_in_trash`, `external_ref_exists`, `concurrent_write` ```bash # Modo ensaio: nada é gravado. Tire o ?dryRun=true para gravar de verdade. curl -X PUT 'https://api.imobyflow.com.br/v1/leads/by-ref/CLI-889?dryRun=true' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' \ -H "Idempotency-Key: $(uuidgen)" \ -H 'Content-Type: application/json' \ --data @- <<'JSON' { "name": "Carlos Pereira", "phones": [ { "number": "(41) 99999-8888", "isWhatsApp": true } ], "email": "carlos@example.com", "status": "ATTENDING", "ownerEmail": "marina@suaimobiliaria.com.br", "interest": { "purposes": [ "VENDA" ], "propertyTypes": [ "APARTAMENTO" ], "locations": [ { "cityId": "4106902", "neighborhoodSlug": "bigorrilho" } ], "salePriceMax": 950000, "bedrooms": 3 }, "lastActivityAt": "2026-10-02T15:00:00Z", "consentGiven": true } JSON ``` ### POST /leads — Cadastrar um cliente Cria um cliente. O mínimo: `name`, um telefone ou e-mail e `consentGiven: true`. Contato que já existe → 409 com o id. Sem responsável, vale a distribuição da imobiliária. - Permissão: `leads:write` - Aceita `?dryRun=true` - Aceita `Idempotency-Key` Corpo: - `externalRef` (string): O código do cliente no seu sistema (só no POST). - `name` (string): Nome. Obrigatório na criação. - `phones` (array): Até 5 telefones. Na criação, telefone ou e-mail. - `email` (string; nullable): E-mail. - `status` (string; NEW | ATTENDING | PROPOSAL | WON | LOST): Etapa do atendimento. - `notes` (string): Anotações. - `preApproved` (boolean): Crédito pré-aprovado. - `sharedToNetwork` (boolean): O perfil pode receber imóveis de parceiros. - `interest` (InterestInput): Perfil de busca. - `ownerAccountId` (string): O corretor responsável, pelo id. - `ownerEmail` (string): O corretor responsável, pelo e-mail — é como o seu sistema o conhece. Sem responsável, vale a distribuição da imobiliária. - `lastActivityAt` (string): A última movimentação no SEU sistema. Só anda para a frente. Mais de 60 dias atrás na criação = o cliente entra arquivado (base histórica). - `consentGiven` (boolean): Obrigatório `true` na criação: a imobiliária declara ter a base legal para tratar o dado (Termos da API). Resposta 201: - `data` (Lead): O objeto como ficou. - `result` (LeadWriteResult): O desfecho. Erros: `invalid_body`, `invalid_param`, `payload_too_large`, `invalid_idempotency_key`, `idempotency_key_reused`, `idempotency_in_progress`, `request_refused`, `consent_required`, `lead_exists`, `external_ref_exists`, `concurrent_write` ```bash # Modo ensaio: nada é gravado. Tire o ?dryRun=true para gravar de verdade. curl -X POST 'https://api.imobyflow.com.br/v1/leads?dryRun=true' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' \ -H "Idempotency-Key: $(uuidgen)" \ -H 'Content-Type: application/json' \ --data @- <<'JSON' { "externalRef": "CLI-889", "name": "Carlos Pereira", "phones": [ { "number": "(41) 99999-8888", "isWhatsApp": true } ], "email": "carlos@example.com", "status": "ATTENDING", "ownerEmail": "marina@suaimobiliaria.com.br", "interest": { "purposes": [ "VENDA" ], "propertyTypes": [ "APARTAMENTO" ], "locations": [ { "cityId": "4106902", "neighborhoodSlug": "bigorrilho" } ], "salePriceMax": 950000, "bedrooms": 3 }, "lastActivityAt": "2026-10-02T15:00:00Z", "consentGiven": true } JSON ``` ### PATCH /leads/{leadId} — Alterar parte de um cliente Muda só o que vier. Mudar a etapa entra no histórico, mas não conta como movimentação — para isso mande `lastActivityAt` ou registre um atendimento. - Permissão: `leads:write` - Aceita `?dryRun=true` - Aceita `Idempotency-Key` - `leadId`: Id do cliente (`lead-…`). Corpo: - `externalRef` (string): O código do cliente no seu sistema (só no POST). - `name` (string): Nome. Obrigatório na criação. - `phones` (array): Até 5 telefones. Na criação, telefone ou e-mail. - `email` (string; nullable): E-mail. - `status` (string; NEW | ATTENDING | PROPOSAL | WON | LOST): Etapa do atendimento. - `notes` (string): Anotações. - `preApproved` (boolean): Crédito pré-aprovado. - `sharedToNetwork` (boolean): O perfil pode receber imóveis de parceiros. - `interest` (InterestInput): Perfil de busca. - `ownerAccountId` (string): O corretor responsável, pelo id. - `ownerEmail` (string): O corretor responsável, pelo e-mail — é como o seu sistema o conhece. Sem responsável, vale a distribuição da imobiliária. - `lastActivityAt` (string): A última movimentação no SEU sistema. Só anda para a frente. Mais de 60 dias atrás na criação = o cliente entra arquivado (base histórica). - `consentGiven` (boolean): Obrigatório `true` na criação: a imobiliária declara ter a base legal para tratar o dado (Termos da API). Resposta 200: - `data` (Lead): O objeto como ficou. - `result` (LeadWriteResult): O desfecho. Erros: `invalid_body`, `invalid_param`, `payload_too_large`, `invalid_idempotency_key`, `idempotency_key_reused`, `idempotency_in_progress`, `request_refused`, `not_found`, `lead_in_trash` ```bash # Modo ensaio: nada é gravado. Tire o ?dryRun=true para gravar de verdade. curl -X PATCH 'https://api.imobyflow.com.br/v1/leads/lead-7c2e9a1b3d5f?dryRun=true' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' \ -H "Idempotency-Key: $(uuidgen)" \ -H 'Content-Type: application/json' \ --data @- <<'JSON' { "status": "PROPOSAL", "lastActivityAt": "2026-10-02T15:00:00Z" } JSON ``` ### POST /leads/{leadId}/state — Arquivar ou reativar `ARCHIVED` arquiva; `ACTIVE` reativa. A mesma função da tela. - Permissão: `leads:write` - Aceita `?dryRun=true` - Aceita `Idempotency-Key` - `leadId`: Id do cliente (`lead-…`). Corpo: - `state` (string; ACTIVE | ARCHIVED): O estado. Resposta 200: - `data` (Lead): O objeto como ficou. - `result` (LeadWriteResult): O desfecho. Erros: `invalid_body`, `invalid_param`, `payload_too_large`, `invalid_idempotency_key`, `idempotency_key_reused`, `idempotency_in_progress`, `request_refused`, `not_found`, `lead_in_trash` ```bash # Modo ensaio: nada é gravado. Tire o ?dryRun=true para gravar de verdade. curl -X POST 'https://api.imobyflow.com.br/v1/leads/lead-7c2e9a1b3d5f/state?dryRun=true' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' \ -H "Idempotency-Key: $(uuidgen)" \ -H 'Content-Type: application/json' \ --data @- <<'JSON' { "state": "ARCHIVED" } JSON ``` ### POST /leads/{leadId}/interactions — Registrar um atendimento Contato, visita, proposta ou anotação feitos no SEU sistema, com a data dele. Conta como movimentação (o cliente não é arquivado por inatividade). - Permissão: `leads:write` - Aceita `?dryRun=true` - Aceita `Idempotency-Key` - `leadId`: Id do cliente (`lead-…`). Corpo: - `type` (string; CONTACT | VISIT | PROPOSAL | NOTE): `CONTACT`, `VISIT`, `PROPOSAL` ou `NOTE`. - `note` (string): Anotação. - `at` (string): Quando aconteceu (padrão: agora). Resposta 200: - `data` (Lead): O objeto como ficou. - `result` (LeadWriteResult): O desfecho. Erros: `invalid_body`, `invalid_param`, `payload_too_large`, `invalid_idempotency_key`, `idempotency_key_reused`, `idempotency_in_progress`, `request_refused`, `not_found` ```bash # Modo ensaio: nada é gravado. Tire o ?dryRun=true para gravar de verdade. curl -X POST 'https://api.imobyflow.com.br/v1/leads/lead-7c2e9a1b3d5f/interactions?dryRun=true' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' \ -H "Idempotency-Key: $(uuidgen)" \ -H 'Content-Type: application/json' \ --data @- <<'JSON' { "type": "VISIT", "note": "Visitou o AP1234 com a esposa.", "at": "2026-10-02T15:00:00Z" } JSON ``` ### DELETE /leads/{leadId} — Mandar para a lixeira Lixeira de 30 dias; cancela as parcerias abertas do cliente, como a tela. A mesma trava de encolhimento dos imóveis. - Permissão: `leads:write` - Aceita `?dryRun=true` - Aceita `Idempotency-Key` - `leadId`: Id do cliente (`lead-…`). Resposta 200: - `data` (Lead): O objeto como ficou. - `result` (LeadWriteResult): O desfecho. Erros: `invalid_param`, `invalid_idempotency_key`, `idempotency_key_reused`, `idempotency_in_progress`, `request_refused`, `not_found`, `shrink_guard` ```bash # Modo ensaio: nada é gravado. Tire o ?dryRun=true para gravar de verdade. curl -X DELETE 'https://api.imobyflow.com.br/v1/leads/lead-7c2e9a1b3d5f?dryRun=true' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' \ -H "Idempotency-Key: $(uuidgen)" ``` ## Oportunidades (Radar) As oportunidades que o Radar encontra entre imóveis e clientes — da própria carteira e de parceiros —, com a mesma regra de exibição do painel. ### GET /properties/{propertyId}/matches — Oportunidades de um imóvel Os clientes que combinam com o imóvel. Só clientes da própria carteira — cliente de parceiro nunca aparece no seu imóvel. - Permissão: `radar:read` - `propertyId`: Id do imóvel (`prop-…`). Resposta 200: - `data` (array): As oportunidades. - `nextCursor` (string; nullable): Cursor da próxima página (nulo = acabou). Erros: `not_found` ```bash curl -X GET 'https://api.imobyflow.com.br/v1/properties/prop-3f9a1c2b7d4e/matches' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' ``` ### GET /leads/{leadId}/matches — Oportunidades de um cliente Os imóveis que servem ao cliente — da carteira e de parceiros. - Permissão: `radar:read` - `leadId`: Id do cliente (`lead-…`). Resposta 200: - `data` (array): As oportunidades. - `nextCursor` (string; nullable): Cursor da próxima página (nulo = acabou). Erros: `not_found` ```bash curl -X GET 'https://api.imobyflow.com.br/v1/leads/lead-7c2e9a1b3d5f/matches' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' ``` ### GET /matches — Oportunidades da conta As oportunidades, mais recentes antes. As de parceiros seguem a regra de exibição do painel: sem assinatura ativa, o parceiro fica escondido (`locked`). O nome do cliente só sai com `leads:read` na chave. - Permissão: `radar:read` - `limit`: Itens por página: de 1 a 100 (padrão 50). - `cursor`: O `nextCursor` da página anterior. A lista acabou quando ele vem nulo. Ele vale só para esta rota e esta conta. - `status`: Situação. - `scope`: Origem. - `ownerAccountId`: Só os de um corretor. Resposta 200: - `data` (array): As oportunidades. - `nextCursor` (string; nullable): Cursor da próxima página (nulo = acabou). Erros: `invalid_param`, `invalid_cursor`, `upstream_timeout`, `upstream_busy` ```bash curl -X GET 'https://api.imobyflow.com.br/v1/matches' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' ``` ### POST /matches/{matchId}/dismiss — Descartar oportunidade A decisão do corretor, tomada no seu sistema. Oportunidade favoritada não se descarta. - Permissão: `radar:write` - Aceita `?dryRun=true` - Aceita `Idempotency-Key` - `matchId`: Id da oportunidade. Tem `#`: mande codificado (`%23`). Resposta 200: - `data` (Match): O objeto como ficou. - `result` (MatchWriteResult): O desfecho. Erros: `invalid_param`, `invalid_idempotency_key`, `idempotency_key_reused`, `idempotency_in_progress`, `request_refused`, `not_found` ```bash # Modo ensaio: nada é gravado. Tire o ?dryRun=true para gravar de verdade. curl -X POST 'https://api.imobyflow.com.br/v1/matches/m%23prop-3f9a1c2b7d4e%23lead-7c2e9a1b3d5f%23L/dismiss?dryRun=true' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' \ -H "Idempotency-Key: $(uuidgen)" ``` ### POST /matches/{matchId}/restore — Restaurar oportunidade Volta a oportunidade descartada para as novas. - Permissão: `radar:write` - Aceita `?dryRun=true` - Aceita `Idempotency-Key` - `matchId`: Id da oportunidade. Tem `#`: mande codificado (`%23`). Resposta 200: - `data` (Match): O objeto como ficou. - `result` (MatchWriteResult): O desfecho. Erros: `invalid_param`, `invalid_idempotency_key`, `idempotency_key_reused`, `idempotency_in_progress`, `request_refused`, `not_found` ```bash # Modo ensaio: nada é gravado. Tire o ?dryRun=true para gravar de verdade. curl -X POST 'https://api.imobyflow.com.br/v1/matches/m%23prop-3f9a1c2b7d4e%23lead-7c2e9a1b3d5f%23L/restore?dryRun=true' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' \ -H "Idempotency-Key: $(uuidgen)" ``` ## Parcerias As parcerias da equipe, com a etapa e as duas pontas. Só o lado que captou o cliente move o funil. ### GET /partnerships — Parcerias da equipe Todas as parcerias numa resposta. O `nextCursor` existe no contrato para quando ela paginar — siga-o desde já. - Permissão: `partnerships:read` - `status`: Etapa. - `updatedSince`: Só o que mudou desde esta data/hora (ISO 8601, UTC). Resposta 200: - `data` (array): As parcerias. - `nextCursor` (string; nullable): Cursor da próxima página (nulo = acabou). Erros: `invalid_param`, `upstream_timeout` ```bash curl -X GET 'https://api.imobyflow.com.br/v1/partnerships' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' ``` ### GET /partnerships/{partnershipId} — Uma parceria A parceria, com as duas pontas e quem pode mover o funil. - Permissão: `partnerships:read` - `partnershipId`: Id da parceria (`pship-…`). Resposta 200: - `data` (Partnership): A parceria. Erros: `not_found` ```bash curl -X GET 'https://api.imobyflow.com.br/v1/partnerships/pship-5b8d2f1e9a3c' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' ``` ### POST /partnerships/{partnershipId}/status — Mover a etapa da parceria Só o lado que captou o cliente move o funil (`canMoveFunnel`). A contraparte só encerra depois de pedir atualização e ficar 15 dias sem resposta — a regra da tela. - Permissão: `partnerships:write` - Aceita `?dryRun=true` - Aceita `Idempotency-Key` - `partnershipId`: Id da parceria (`pship-…`). Corpo: - `status` (string; PENDING | ACCEPTED | DECLINED | CANCELLED | LEAD_REGISTERED | CONTACTED | NEGOTIATING | PROPOSAL | WON | LOST): A nova etapa. Resposta 200: - `data` (Partnership): O objeto como ficou. - `result` (PartnershipWriteResult): O desfecho. Erros: `invalid_body`, `invalid_param`, `payload_too_large`, `invalid_idempotency_key`, `idempotency_key_reused`, `idempotency_in_progress`, `request_refused`, `not_found` ```bash # Modo ensaio: nada é gravado. Tire o ?dryRun=true para gravar de verdade. curl -X POST 'https://api.imobyflow.com.br/v1/partnerships/pship-5b8d2f1e9a3c/status?dryRun=true' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' \ -H "Idempotency-Key: $(uuidgen)" \ -H 'Content-Type: application/json' \ --data @- <<'JSON' { "status": "PROPOSAL" } JSON ``` ## Equipe Quem está na equipe: nome, e-mail, papel e CRECI. É pelo e-mail que o seu sistema reconhece o corretor. ### GET /team — A equipe Quem está na equipe, inclusive suspensos. - Permissão: `team:read` Resposta 200: - `data` (array): A equipe. - `nextCursor` (string; nullable): Cursor da próxima página (nulo = acabou). Erros: `not_available` ```bash curl -X GET 'https://api.imobyflow.com.br/v1/team' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' ``` ## Lançamentos O catálogo de lançamentos da cidade: empreendimento, tipologias, tabela e estágio da obra. ### GET /launches — Lançamentos da cidade O catálogo de lançamentos, com as tipologias. - Permissão: `launches:read` - `limit`: Itens por página: de 1 a 50 (padrão 20). - `cursor`: O `nextCursor` da página anterior. A lista acabou quando ele vem nulo. Ele vale só para esta rota e esta conta. - `citySlug`: Identificador da cidade no catálogo. - `neighborhood`: Bairro (nome). - `type`: Subtipo. - `stage`: Estágio da obra. - `priceMin`: Preço mínimo. - `priceMax`: Preço máximo. - `q`: Busca no nome. Resposta 200: - `data` (array): Os empreendimentos. - `nextCursor` (string; nullable): Cursor da próxima página (nulo = acabou). Erros: `invalid_param`, `invalid_cursor`, `upstream_timeout`, `upstream_busy` ```bash curl -X GET 'https://api.imobyflow.com.br/v1/launches' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' ``` ## Captação Os proprietários que chegam à vez da conta e o aceite, que debita o crédito e libera o contato. Aceitar exige uma permissão própria e o termo específico aceito no painel. ### GET /captacao/offers — Proprietários na vez da conta Os proprietários na vez da conta agora, com o prazo correndo — os mesmos cards da mesa —, e o resumo (crédito, pausa, módulo valendo). Antes do aceite, contato e endereço não existem na resposta. - Permissão: `captacao:read` Resposta 200: - `data` (array): Os proprietários. - `summary` (CaptacaoSummary): O resumo da mesa. - `nextCursor` (string; nullable): Sempre nulo hoje. Erros: `captacao_not_active`, `not_available` ```bash curl -X GET 'https://api.imobyflow.com.br/v1/captacao/offers' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' ``` ### GET /captacao/offers/{offerId} — Um proprietário Na vez da conta (sem contato) ou já aceito por ela (com contato). - Permissão: `captacao:read` - `offerId`: Id do proprietário na mesa (`cap-…`). Resposta 200: - `data` (CaptacaoOffer): O proprietário. Erros: `not_found`, `captacao_not_active` ```bash curl -X GET 'https://api.imobyflow.com.br/v1/captacao/offers/cap-8e7d6c5b4a39' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' ``` ### GET /captacao/owners — Proprietários aceitos Os aceitos, por aba da mesa, em páginas de 10, com a contagem das três abas. - Permissão: `captacao:read` - `tab`: A aba (padrão `ACTIVE`). - `cursor`: O `nextCursor` da página anterior. A lista acabou quando ele vem nulo. Ele vale só para esta rota e esta conta. Resposta 200: - `data` (array): Os aceitos. - `nextCursor` (string; nullable): Próxima página. - `total` (integer; nullable): Total na aba. - `counts` (object; nullable): Quantos em cada aba. Erros: `invalid_param`, `invalid_cursor`, `captacao_not_active` ```bash curl -X GET 'https://api.imobyflow.com.br/v1/captacao/owners' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' ``` ### POST /captacao/offers/{offerId}/accept — Aceitar um proprietário O único caminho da API que gasta dinheiro: debita o crédito e libera o contato. Exige a permissão `captacao:accept` e o termo do item 13 dos Termos da API aceito pelo dono no painel. Cada aceite grava a chave, o IP e a versão do termo. Ensaio responde `WOULD_ACCEPT` com o preço; a re-tentativa do mesmo aceite, `ALREADY_ACCEPTED`, sem segundo débito. - Permissão: `captacao:accept` - Aceita `?dryRun=true` - Aceita `Idempotency-Key` - `offerId`: Id do proprietário na mesa (`cap-…`). Resposta 200: - `data` (CaptacaoOffer): O proprietário (com contato). - `result` (CaptacaoAcceptResult): O desfecho. Erros: `invalid_param`, `invalid_idempotency_key`, `idempotency_key_reused`, `idempotency_in_progress`, `request_refused`, `not_found`, `captacao_not_active`, `captacao_terms_required`, `offer_unavailable`, `captacao_insufficient_credit` ```bash # Modo ensaio: nada é gravado. Tire o ?dryRun=true para gravar de verdade. curl -X POST 'https://api.imobyflow.com.br/v1/captacao/offers/cap-8e7d6c5b4a39/accept?dryRun=true' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' \ -H "Idempotency-Key: $(uuidgen)" ``` ## Eventos O que mudou na conta, em ordem, com 30 dias de memória — a sincronização incremental. O evento é enxuto: ids e os nomes dos campos que mudaram; o detalhe vem da leitura do recurso. ### GET /events — O que mudou Os eventos da conta em ordem, com 30 dias de memória. Guarde o `nextCursor` e mande de volta na próxima leitura — ele sempre vem, também quando não há nada novo. Cada tipo exige também a permissão de leitura do recurso. Um evento leva de segundos a mais de um minuto para aparecer: siga o CURSOR, nunca o relógio. - Permissão: `events:read` - `limit`: Itens por página: de 1 a 500 (padrão 100). - `cursor`: O `nextCursor` da página anterior. A lista acabou quando ele vem nulo. Ele vale só para esta rota e esta conta. - `since`: Começar desta data/hora (só sem cursor). - `types`: Só estes tipos, separados por vírgula. Resposta 200: - `data` (array): Os eventos, em ordem. - `nextCursor` (string): Onde continuar (sempre vem). - `hasMore` (boolean): Há mais para ler agora. Erros: `invalid_param`, `invalid_cursor` ```bash curl -X GET 'https://api.imobyflow.com.br/v1/events' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' ``` ## Webhooks Os endereços que recebem os eventos na hora, assinados no padrão Standard Webhooks, com nova tentativa, desligamento automático, reenvio e evento de teste. ### GET /webhooks — Endereços cadastrados Os endereços de webhook da conta. - Permissão: `webhooks:manage` Resposta 200: - `data` (array): Os endereços. Erros: só os comuns ```bash curl -X GET 'https://api.imobyflow.com.br/v1/webhooks' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' ``` ### POST /webhooks — Cadastrar um endereço Só HTTPS e só host público. A resposta traz o `secret` (`whsec_…`) UMA vez — guarde-o: é com ele que você confere a assinatura. Esta rota não aceita `Idempotency-Key` (a resposta guardada deixaria o segredo em texto); repetir cria outro endereço. - Permissão: `webhooks:manage` Corpo: - `url` (string): O endereço, só HTTPS e público. Credencial na URL é recusada. - `types` (array): Os tipos (ausente = todos os que a conta lê). - `description` (string; nullable): Descrição. Resposta 201: - `data` (Webhook): O endereço. - `secret` (string): O segredo, só nesta resposta. Erros: `invalid_body`, `invalid_param`, `payload_too_large`, `webhook_url_refused`, `webhook_limit_reached` ```bash curl -X POST 'https://api.imobyflow.com.br/v1/webhooks' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' \ -H 'Content-Type: application/json' \ --data @- <<'JSON' { "url": "https://crm.suaimobiliaria.com.br/imobyflow/eventos", "types": [ "property.updated", "lead.created" ], "description": "CRM — produção" } JSON ``` ### PATCH /webhooks/{webhookId} — Alterar um endereço Muda o endereço, os tipos, a descrição — ou desliga e religa (religar limpa o motivo do desligamento). - Permissão: `webhooks:manage` - Aceita `Idempotency-Key` - `webhookId`: Id do endereço (`wh_…`). Corpo: - `url` (string): O endereço. - `types` (array): Os tipos. - `description` (string; nullable): Descrição. - `status` (string; ACTIVE | DISABLED): `ACTIVE` religa (limpa o motivo do desligamento) e `DISABLED` desliga. Resposta 200: - `data` (Webhook): O endereço. Erros: `invalid_body`, `invalid_param`, `payload_too_large`, `invalid_idempotency_key`, `idempotency_key_reused`, `idempotency_in_progress`, `not_found`, `webhook_url_refused` ```bash curl -X PATCH 'https://api.imobyflow.com.br/v1/webhooks/wh_9c8b7a6f5e4d3c2b' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' \ -H "Idempotency-Key: $(uuidgen)" \ -H 'Content-Type: application/json' \ --data @- <<'JSON' { "status": "ACTIVE" } JSON ``` ### DELETE /webhooks/{webhookId} — Apagar um endereço Para de entregar e apaga o endereço. - Permissão: `webhooks:manage` - Aceita `Idempotency-Key` - `webhookId`: Id do endereço (`wh_…`). Resposta 200: - `data` (Webhook): O endereço apagado. - `result` (object): O desfecho. - `result.outcome` (string): `DELETED`. Erros: `invalid_idempotency_key`, `idempotency_key_reused`, `idempotency_in_progress`, `not_found` ```bash curl -X DELETE 'https://api.imobyflow.com.br/v1/webhooks/wh_9c8b7a6f5e4d3c2b' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' \ -H "Idempotency-Key: $(uuidgen)" ``` ### POST /webhooks/{webhookId}/rotate-secret — Trocar o segredo Gera um segredo novo, devolvido UMA vez. O anterior segue assinando junto por 24 horas — dá tempo de trocar no seu sistema sem perder evento. Sem `Idempotency-Key`. - Permissão: `webhooks:manage` - `webhookId`: Id do endereço (`wh_…`). Resposta 200: - `data` (Webhook): O endereço. - `secret` (string): O segredo novo. Erros: `not_found` ```bash curl -X POST 'https://api.imobyflow.com.br/v1/webhooks/wh_9c8b7a6f5e4d3c2b/rotate-secret' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' ``` ### POST /webhooks/{webhookId}/test — Mandar um evento de teste Entrega um `webhook.test` AGORA, assinado, e devolve o que o seu sistema respondeu. - Permissão: `webhooks:manage` - Aceita `Idempotency-Key` - `webhookId`: Id do endereço (`wh_…`). Resposta 200: - `data` (WebhookTestResult): O resultado. Erros: `invalid_idempotency_key`, `idempotency_key_reused`, `idempotency_in_progress`, `not_found` ```bash curl -X POST 'https://api.imobyflow.com.br/v1/webhooks/wh_9c8b7a6f5e4d3c2b/test' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' \ -H "Idempotency-Key: $(uuidgen)" ``` ### GET /webhooks/{webhookId}/deliveries — Entregas de um endereço As entregas, mais novas antes, com o status, as tentativas e o último código. - Permissão: `webhooks:manage` - `webhookId`: Id do endereço (`wh_…`). - `limit`: Itens por página: de 1 a 200 (padrão 50). - `cursor`: O `nextCursor` da página anterior. A lista acabou quando ele vem nulo. Ele vale só para esta rota e esta conta. Resposta 200: - `data` (array): As entregas. - `nextCursor` (string; nullable): Cursor da próxima página (nulo = acabou). Erros: `invalid_param`, `invalid_cursor`, `not_found` ```bash curl -X GET 'https://api.imobyflow.com.br/v1/webhooks/wh_9c8b7a6f5e4d3c2b/deliveries' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' ``` ### POST /webhooks/{webhookId}/deliveries/{deliveryId}/retry — Reenviar uma entrega Uma nova rodada de tentativas para a mesma entrega — com o MESMO `webhook-id`, então o seu sistema reconhece a repetição. A que já está agendada responde `ALREADY_SCHEDULED`. - Permissão: `webhooks:manage` - Aceita `Idempotency-Key` - `webhookId`: Id do endereço (`wh_…`). - `deliveryId`: Id da entrega (`dlv_…`). Resposta 200: - `data` (Delivery): A entrega. - `result` (object): O desfecho. - `result.outcome` (string; SCHEDULED | ALREADY_SCHEDULED): `SCHEDULED` ou `ALREADY_SCHEDULED`. Erros: `invalid_idempotency_key`, `idempotency_key_reused`, `idempotency_in_progress`, `not_found` ```bash curl -X POST 'https://api.imobyflow.com.br/v1/webhooks/wh_9c8b7a6f5e4d3c2b/deliveries/dlv_20261002164512000_evt_4f1c9a7e2b3d8c6a5e4f1b2c/retry' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' \ -H "Idempotency-Key: $(uuidgen)" ``` ## Lotes Até 500 imóveis ou clientes numa chamada, processados no ritmo da plataforma, com o desfecho de cada item. ### POST /properties/batch — Lote de imóveis Até 500 imóveis e 4 MB numa chamada. Cada item é o PUT pelo código (`externalRef` obrigatório) — as mesmas regras, os mesmos desfechos. Item mal formado volta `REJECTED` e não barra os outros; o mesmo código duas vezes no lote é recusado. Responde 202 na hora e processa no ritmo da plataforma (4 itens por segundo): 500 itens levam de 2 a 3 minutos. - Permissão: `properties:write` - Aceita `?dryRun=true` - Aceita `Idempotency-Key` Corpo: - `items` (array): Os itens (1 a 500). Resposta 202: - `data` (BatchCreated): O lote recebido. Erros: `invalid_body`, `invalid_param`, `payload_too_large`, `invalid_idempotency_key`, `idempotency_key_reused`, `idempotency_in_progress` ```bash # Modo ensaio: nada é gravado. Tire o ?dryRun=true para gravar de verdade. curl -X POST 'https://api.imobyflow.com.br/v1/properties/batch?dryRun=true' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' \ -H "Idempotency-Key: $(uuidgen)" \ -H 'Content-Type: application/json' \ --data @- <<'JSON' { "items": [ { "externalRef": "AP1234", "title": "Apartamento 3 quartos no Bigorrilho", "type": "APARTAMENTO", "purposes": [ "VENDA" ], "salePrice": 890000, "address": { "cityId": "4106902", "neighborhoodSlug": "bigorrilho", "street": "Rua Padre Anchieta", "number": "1500", "complement": "Ap 82" }, "bedrooms": 3, "suites": 1, "bathrooms": 2, "parkingSpots": 2, "area": 98, "photos": [ "https://www.suaimobiliaria.com.br/fotos/AP1234/1.jpg", "https://www.suaimobiliaria.com.br/fotos/AP1234/2.jpg" ] } ] } JSON ``` ### GET /properties/batch/{batchId} — Acompanhar o lote O status, a contagem e o desfecho de cada item, na ordem do pedido. O lote fica disponível por 7 dias. - Permissão: `properties:read` - `batchId`: Id do lote (`b-…`). Resposta 200: - `data` (Batch): O lote. Erros: `not_found` ```bash curl -X GET 'https://api.imobyflow.com.br/v1/properties/batch/b-4c1d9e2f7a3b8c6d' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' ``` ### POST /leads/batch — Lote de clientes Até 500 clientes e 4 MB numa chamada. Cada item é o PUT pelo código (`externalRef` obrigatório) — as mesmas regras, os mesmos desfechos. Item mal formado volta `REJECTED` e não barra os outros; o mesmo código duas vezes no lote é recusado. Responde 202 na hora e processa no ritmo da plataforma (4 itens por segundo): 500 itens levam de 2 a 3 minutos. - Permissão: `leads:write` - Aceita `?dryRun=true` - Aceita `Idempotency-Key` Corpo: - `items` (array): Os itens (1 a 500). Resposta 202: - `data` (BatchCreated): O lote recebido. Erros: `invalid_body`, `invalid_param`, `payload_too_large`, `invalid_idempotency_key`, `idempotency_key_reused`, `idempotency_in_progress` ```bash # Modo ensaio: nada é gravado. Tire o ?dryRun=true para gravar de verdade. curl -X POST 'https://api.imobyflow.com.br/v1/leads/batch?dryRun=true' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' \ -H "Idempotency-Key: $(uuidgen)" \ -H 'Content-Type: application/json' \ --data @- <<'JSON' { "items": [ { "externalRef": "CLI-889", "name": "Carlos Pereira", "phones": [ { "number": "(41) 99999-8888", "isWhatsApp": true } ], "email": "carlos@example.com", "status": "ATTENDING", "ownerEmail": "marina@suaimobiliaria.com.br", "interest": { "purposes": [ "VENDA" ], "propertyTypes": [ "APARTAMENTO" ], "locations": [ { "cityId": "4106902", "neighborhoodSlug": "bigorrilho" } ], "salePriceMax": 950000, "bedrooms": 3 }, "lastActivityAt": "2026-10-02T15:00:00Z", "consentGiven": true } ] } JSON ``` ### GET /leads/batch/{batchId} — Acompanhar o lote O status, a contagem e o desfecho de cada item, na ordem do pedido. O lote fica disponível por 7 dias. - Permissão: `leads:read` - `batchId`: Id do lote (`b-…`). Resposta 200: - `data` (Batch): O lote. Erros: `not_found` ```bash curl -X GET 'https://api.imobyflow.com.br/v1/leads/batch/b-4c1d9e2f7a3b8c6d' \ -H "Authorization: Bearer $IMOBYFLOW_API_KEY" \ -H 'Accept-Language: pt-BR' ``` ## Os objetos ### Problem Erro no formato RFC 9457 (`application/problem+json`). - `type` (string): Endereço da página deste erro, com a causa e o conserto. - `title` (string): O nome do erro, na língua do `Accept-Language`. - `status` (integer): O código HTTP. - `code` (string): Código estável — é por ele que o seu sistema decide o que fazer. - `requestId` (string): Id da requisição. Mande junto quando falar com o suporte. - `detail` (string): Explicação do caso (quando houver). - `invalidParams` (array): Todos os problemas do pedido de uma vez — não só o primeiro. ### Limits Os limites da faixa de uso da conta. - `ratePerSecond` (integer): Chamadas por segundo. - `burst` (integer): Pico tolerado num instante. - `monthlyQuota` (integer): Chamadas por mês (mês de calendário, UTC). - `maxKeys` (integer): Chaves ativas ao mesmo tempo. - `maxWebhooks` (integer): Endereços de webhook. ### Me Quem é a conta, o que a chave pode fazer e quanto da cota já foi usado. - `account` (object): A conta dona da chave. - `account.id` (string): Id da conta. - `account.name` (string; nullable): Nome da empresa. - `account.type` (string; nullable): `IMOBILIARIA` ou `CONSTRUTORA`. - `account.plan` (string; nullable): Código do plano. - `access` (object): A liberação da API. - `access.status` (string; nullable): Estado da liberação (`APPROVED` quando vale). - `access.tier` (string): Faixa de uso: `PADRAO` ou `AMPLIADA`. - `access.pilotUntil` (string; nullable): Fim do período de piloto, quando houver. - `access.limits` (Limits): Os limites que valem para a conta. - `key` (object): A chave usada nesta chamada. - `key.id` (string; nullable): Id da chave (não é o segredo). - `key.name` (string; nullable): Nome dado no painel. - `key.scopes` (array): As permissões que valem para ESTA chave. - `key.expiresAt` (string; nullable): Quando a chave vence (sem prazo = nulo). - `usage` (object): O uso do mês. - `usage.month` (string): O mês (`AAAA-MM`, UTC). - `usage.calls` (integer): Chamadas feitas no mês. - `usage.monthlyQuota` (integer): A cota do mês. - `usage.remaining` (integer): O que ainda cabe. - `properties` (object): A cota de imóveis do plano. - `properties.active` (integer): Imóveis ativos agora. - `properties.limit` (integer; nullable): Teto de imóveis ativos do plano. ### ValueLabel Um valor aceito e o seu rótulo. - `value` (string): O valor que vai no campo. - `label` (string): O rótulo, na língua do `Accept-Language`. ### PropertyTypeGroup Uma categoria de imóvel e os seus subtipos. - `category` (string; RESIDENCIAL | COMERCIAL | TERRENO | RURAL): A categoria. - `label` (string): Rótulo da categoria. - `types` (array): Os subtipos da categoria — é o subtipo que vai em `type`. ### ScopeInfo Uma permissão que uma chave pode ter. - `id` (string; properties:read | properties:write | leads:read | leads:write | radar:read | radar:write | partnerships:read | partnerships:write | team:read | launches:read | launches:write | captacao:read | captacao:accept | events:read | webhooks:manage): A permissão. - `group` (string): O grupo, para exibir. - `label` (string): O nome, para exibir. - `description` (string): O que ela permite. ### EventTypeInfo Um tipo de evento. - `type` (string; property.created | property.updated | property.deleted | property.restored | property.purged | lead.created | lead.updated | lead.deleted | lead.restored | lead.purged | radar.client_summary | partnership.created | partnership.updated | captacao.offer_received | captacao.offer_accepted | captacao.offer_withdrawn): O tipo do evento. - `scope` (string; properties:read | properties:write | leads:read | leads:write | radar:read | radar:write | partnerships:read | partnerships:write | team:read | launches:read | launches:write | captacao:read | captacao:accept | events:read | webhooks:manage): A permissão de leitura que dá acesso a ele. - `description` (string): O que ele avisa. ### City Uma cidade do catálogo. - `cityId` (string): Código do IBGE, 7 dígitos — a forma mais segura de mandar a cidade. - `name` (string): Nome da cidade. - `uf` (string): Estado (UF). - `citySlug` (string): Identificador da cidade no catálogo. ### Neighborhood Um bairro do catálogo. - `neighborhoodSlug` (string): O identificador do bairro — o valor de `neighborhoodSlug` na escrita. - `name` (string): Nome do bairro. ### Address O endereço completo — o imóvel é da própria conta. - `neighborhood` (string; nullable): Nome do bairro. - `neighborhoodSlug` (string; nullable): Bairro do catálogo. Nulo quando o bairro ainda não foi reconhecido — aí o imóvel fica fora das recomendações até a curadoria decidir. - `city` (string; nullable): Nome da cidade. - `cityId` (string; nullable): Código do IBGE. - `citySlug` (string; nullable): Identificador da cidade no catálogo. - `state` (string; nullable): Estado (UF). - `street` (string; nullable): Rua. - `number` (string; nullable): Número. - `complement` (string; nullable): Complemento. ### AddressArea O endereço até o bairro. - `neighborhood` (string; nullable): Nome do bairro. - `neighborhoodSlug` (string; nullable): Bairro do catálogo. - `city` (string; nullable): Nome da cidade. - `cityId` (string; nullable): Código do IBGE. - `citySlug` (string; nullable): Identificador da cidade no catálogo. - `state` (string; nullable): Estado (UF). ### PartnershipTerms As condições para parceiros. - `commissionPercent` (number; nullable): Comissão de venda oferecida a parceiros, em %. - `rentCommissionMonths` (number; nullable): Comissão de locação, em aluguéis. - `splitListingPercent` (number; nullable): Parte da comissão que fica com quem captou, em %. ### PropertyRadar A situação do imóvel nas recomendações (Radar). - `eligible` (boolean): Entra nas recomendações agora (ativo e sem pendência). - `pending` (array): O que falta para entrar nas recomendações. A capa é obrigatória. - `labels` (array): As mesmas pendências, por extenso. ### Curation A análise do imóvel pela ImobyFlow antes de ele aparecer para parceiros. Imóvel novo pela API nasce em análise. - `status` (string; nullable): `PENDING`, `APPROVED` ou `REJECTED`. - `reason` (string; nullable; LANCAMENTO | SEM_VALOR | QUALIDADE_BAIXA | NAO_ANGARIACAO | MARCA_DAGUA | FOTOS_INSUFICIENTES | DADOS_INCOERENTES | OUTRO): O motivo da recusa, em código. - `label` (string; nullable): O motivo por extenso. ### Confirmation A régua dos 60 dias: imóvel não confirmado sai do ar. Gravar o imóvel pela API (ou confirmar) renova a data. - `lastConfirmedAt` (string; nullable): Última confirmação de que segue disponível. - `dueAt` (string; nullable): Quando a confirmação vence (a cada 60 dias). - `noticeAt` (string; nullable): Quando o aviso de confirmação foi mandado. - `offlineAt` (string; nullable): Quando sai do ar sem resposta (7 dias depois do aviso). ### LaunchBlock Dados de lançamento (empreendimento e tipologia). - `constructionStage` (string; nullable; LAUNCH | OFF_PLAN | NEW | READY): Estágio da obra. - `deliveryDate` (string; nullable): Previsão de entrega. - `constructionProgress` (integer; nullable): Andamento da obra, em %. - `unitsTotal` (integer; nullable): Unidades no total. - `unitsAvailable` (integer; nullable): Unidades disponíveis. - `unitsReserved` (integer; nullable): Unidades reservadas. - `unitsSold` (integer; nullable): Unidades vendidas. - `floorPlans` (array): As plantas. ### PhotoSync O download das fotos mandadas por endereço. Ele acontece depois da resposta — é aqui que você vê se a galeria entrou. - `state` (string): `QUEUED` (na fila), `DONE`, `PARTIAL` (algumas falharam), `FAILED` ou `NOT_QUEUED` (a fila recusou — o próximo pedido tenta de novo). - `requested` (integer; nullable): Fotos pedidas. - `ingested` (integer; nullable): Fotos baixadas e gravadas. - `failed` (integer; nullable): Fotos que falharam. - `queuedAt` (string; nullable): Quando entrou na fila. - `finishedAt` (string; nullable): Quando terminou. ### Property Um imóvel da carteira da conta. - `id` (string): Id do imóvel. - `externalRef` (string; nullable): O código do imóvel no SEU sistema. - `kind` (string; PROPERTY | DEVELOPMENT | TYPOLOGY): `PROPERTY` (avulso), `DEVELOPMENT` (empreendimento) ou `TYPOLOGY` (tipologia de um empreendimento). - `developmentId` (string; nullable): O empreendimento desta tipologia. - `status` (string; ACTIVE | INACTIVE | SOLD | RENTED | DELETED): Situação. `DELETED` = na lixeira (30 dias). - `type` (string; nullable; APARTAMENTO | CASA_RUA | CASA_CONDOMINIO | CASA_VILA | STUDIO | FLAT | COBERTURA | SALA_COMERCIAL | LOJA_PONTO | GALPAO | PREDIO | TERRENO_RUA | TERRENO_CONDOMINIO | CHACARA_SITIO | FAZENDA): Subtipo (veja as listas de valores). - `category` (string; nullable; RESIDENCIAL | COMERCIAL | TERRENO | RURAL): Categoria do subtipo. - `purposes` (array): Finalidades: `VENDA`, `LOCACAO` ou as duas. - `salePrice` (number; nullable): Preço de venda, em reais. - `rentPrice` (number; nullable): Aluguel mensal, em reais. - `title` (string; nullable): Título do anúncio. - `description` (string; nullable): Descrição, em texto corrido. - `address` (Address): Endereço. - `bedrooms` (integer; nullable): Quartos. - `suites` (integer; nullable): Suítes. - `bathrooms` (integer; nullable): Banheiros. - `parkingSpots` (integer; nullable): Vagas de garagem. - `area` (number; nullable): Área privativa total, em m² — a que se compara entre imóveis. - `privateArea` (number; nullable): Área coberta, em m² (só exibição). - `amenities` (array): Itens do imóvel e do condomínio. - `coverPhoto` (string; nullable): A capa (a 1ª foto). Sem capa o imóvel não entra nas recomendações. - `photos` (array): A galeria, na ordem. - `listingUrl` (string; nullable): Endereço do anúncio no seu site. - `captador` (object; nullable): O corretor responsável da equipe. - `captador.accountId` (string): Id do corretor. - `captador.name` (string; nullable): Nome. - `captadorName` (string; nullable): Nome do captador em texto (quem não está na equipe). - `sharedToNetwork` (boolean): Compartilhado com parceiros. - `partnershipTerms` (PartnershipTerms): Condições para parceiros. - `radar` (PropertyRadar): Situação nas recomendações. - `curation` (Curation): Análise da ImobyFlow. - `confirmation` (Confirmation): A confirmação de disponibilidade. - `inactiveReason` (string; nullable): Por que está arquivado (só com `status` = `INACTIVE`). - `deletedAt` (string; nullable): Quando foi para a lixeira. - `launch` (LaunchBlock; nullable): Dados de lançamento (só empreendimento e tipologia). - `photoSync` (PhotoSync; nullable): O download das fotos mandadas por endereço. - `createdAt` (string): Quando foi criado (UTC). - `updatedAt` (string): Última alteração (UTC). ### AddressInput O endereço. Vem inteiro quando vem. - `cityId` (string): Código do IBGE (7 dígitos). Com ele, `city` e `state` são dispensáveis. - `city` (string): Nome da cidade (com `state`). Nome desconhecido volta 400 com sugestões. - `state` (string): UF, 2 letras. - `neighborhoodSlug` (string): Bairro pelo identificador do catálogo — o caminho garantido. - `neighborhood` (string): Bairro em texto. Ele passa pelo dicionário de apelidos; o que não for reconhecido fica pendente para a curadoria, nunca vira um bairro inventado. - `street` (string): Rua. - `number` (string): Número. - `complement` (string): Complemento. ### PropertyInput Os campos que a API aceita no imóvel. Campo desconhecido é erro (400). Campo ausente não apaga; para limpar, mande `null`. - `externalRef` (string): O código do imóvel no seu sistema (só no POST; no PUT ele vai no caminho). - `title` (string): Título. Marcação HTML é removida. - `description` (string): Descrição. `
` e `

` viram quebra de linha; o resto da marcação sai. - `type` (string; APARTAMENTO | CASA_RUA | CASA_CONDOMINIO | CASA_VILA | STUDIO | FLAT | COBERTURA | SALA_COMERCIAL | LOJA_PONTO | GALPAO | PREDIO | TERRENO_RUA | TERRENO_CONDOMINIO | CHACARA_SITIO | FAZENDA): Subtipo. - `purposes` (array): Finalidades. - `salePrice` (number; nullable): Preço de venda, em reais. Obrigatório com `VENDA`. - `rentPrice` (number; nullable): Aluguel, em reais. Obrigatório com `LOCACAO`. - `address` (AddressInput): Endereço. - `bedrooms` (integer; nullable): Quartos. - `suites` (integer; nullable): Suítes. - `bathrooms` (integer; nullable): Banheiros. - `parkingSpots` (integer; nullable): Vagas. - `area` (number; nullable): Área privativa total, em m². - `privateArea` (number; nullable): Área coberta, em m². - `listingUrl` (string; nullable): Endereço do anúncio no seu site (http ou https). - `captadorName` (string; nullable): Nome do captador em texto. - `captadorAccountId` (string; nullable): Id do corretor responsável da equipe. - `partnershipTerms` (PartnershipTerms): Condições para parceiros. - `photos` (array): Até 30 endereços; a 1ª é a capa. Baixadas depois da resposta (veja `photoSync`). Ausente = a galeria fica como está; lista vazia = tirar as fotos. ### PropertyWriteResult O desfecho da escrita. - `outcome` (string): O que aconteceu: `CREATED`, `UPDATED`, `UNCHANGED` (nada mudou, nada gravado), `CONFIRMED` (só a data de disponibilidade), `STATUS_SET`, `DELETED`, `ALREADY_DELETED`… - `dryRun` (boolean): Foi um ensaio — nada foi gravado. - `conflicts` (array): Campos que a equipe editou na tela e que por isso não foram sobrescritos — a edição na tela vence. - `photos` (string; nullable): A galeria: `UNCHANGED`, `QUEUED`, `ALREADY_QUEUED` ou `CLEARED`. Nulo quando o pedido não falou de fotos. ### Phone Um telefone. - `number` (string): Só dígitos, com DDD (10 a 13). - `isWhatsApp` (boolean): É WhatsApp. - `label` (string; nullable): Rótulo livre (`celular`, `trabalho`…). ### Location Uma região de interesse. - `cityId` (string; nullable): Código do IBGE. - `citySlug` (string; nullable): Identificador da cidade. - `cityName` (string; nullable): Nome da cidade. - `uf` (string; nullable): Estado. - `neighborhoodSlug` (string; nullable): Bairro do catálogo (nulo = a cidade inteira). - `neighborhoodName` (string; nullable): Nome do bairro. - `preference` (string; PREFERRED | ACCEPTABLE): `PREFERRED` (preferido) ou `ACCEPTABLE` (aceitável) — pesa na nota da recomendação. ### Interest O perfil de busca — é ele que liga as recomendações. - `purposes` (array): Finalidades: `VENDA`, `LOCACAO` ou as duas. - `propertyTypes` (array): Tipos de imóvel procurados. - `locations` (array): Regiões de interesse. - `similarNeighborhoods` (boolean): Aceita bairros parecidos com os escolhidos. - `salePriceMin` (number; nullable): Compra: piso, em reais. - `salePriceMax` (number; nullable): Compra: teto, em reais. - `rentPriceMin` (number; nullable): Aluguel: piso, em reais. - `rentPriceMax` (number; nullable): Aluguel: teto, em reais. - `bedrooms` (integer; nullable): Quartos, no mínimo. - `bathrooms` (integer; nullable): Banheiros, no mínimo. - `parkingSpots` (integer; nullable): Vagas, no mínimo. - `areaMin` (number; nullable): Área mínima, em m². ### LeadRadar A situação do cliente nas recomendações. - `eligible` (boolean): Recebe recomendações agora (ativo e sem pendência). - `pending` (array): O que falta no perfil de busca. - `labels` (array): As mesmas pendências, por extenso. ### Lead Um cliente da conta. Nome, telefone e e-mail são dado pessoal — a imobiliária é a controladora. - `id` (string): Id do cliente. - `externalRef` (string; nullable): O código do cliente no SEU sistema. - `ownerAccountId` (string; nullable): O corretor responsável (ou a própria imobiliária). - `state` (string; ACTIVE | ARCHIVED | DELETED): `ACTIVE`, `ARCHIVED` ou `DELETED` (lixeira). - `status` (string; nullable; NEW | ATTENDING | PROPOSAL | WON | LOST): Etapa do atendimento. - `name` (string; nullable): Nome. - `phones` (array): Telefones. - `email` (string; nullable): E-mail. - `source` (string): Por onde chegou: `MANUAL`, `IMPORT_CSV`, `EMAIL`, `WEBHOOK`, `META_ADS`, `PORTAL_API`, `CRM_API` (pela API)… - `sourceDetail` (string; nullable): Detalhe da origem (o portal, o nome do sistema). - `sourcePropertyId` (string; nullable): O imóvel que trouxe o cliente, quando houver. - `preApproved` (boolean): Crédito pré-aprovado. - `sharedToNetwork` (boolean): O perfil (sem nome nem contato) pode receber imóveis de parceiros. - `notes` (string; nullable): Anotações. - `interest` (Interest): Perfil de busca. - `radar` (LeadRadar): Situação nas recomendações. - `lastActivityAt` (string; nullable): Última movimentação — anda pela data que o seu sistema manda e pelos atendimentos, nunca pela sincronização. - `archivedAt` (string; nullable): Quando foi arquivado. - `archivedReason` (string; nullable): Por que foi arquivado (`MANUAL`, `INACTIVITY`, `IMPORT`…). - `deletedAt` (string; nullable): Quando foi para a lixeira. - `createdAt` (string): Quando foi criado (UTC). - `updatedAt` (string): Última alteração (UTC). ### PhoneInput Um telefone. Também aceita só o número, em texto. - `number` (string): Com DDD; só os dígitos contam. - `isWhatsApp` (boolean): É WhatsApp (padrão: sim). - `label` (string): Rótulo livre. ### LocationInput Uma região de interesse. - `cityId` (string): Código do IBGE. - `cityName` (string): Nome da cidade (com `uf`). - `uf` (string): Estado. - `neighborhoodSlug` (string): Bairro do catálogo. - `neighborhoodName` (string): Bairro em texto. Área de mercado ("Ecoville") vira os bairros do catálogo que ela cobre. - `preference` (string; PREFERRED | ACCEPTABLE): `PREFERRED` (padrão) ou `ACCEPTABLE`. ### InterestInput O perfil de busca. É mesclado campo a campo: mandar só o teto não apaga as regiões. - `purposes` (array): Finalidades. - `propertyTypes` (array): Tipos procurados. - `locations` (array): Regiões (até 20). Quando vem, vem inteira. - `similarNeighborhoods` (boolean): Aceita bairros parecidos. - `salePriceMin` (number; nullable): Compra: piso. - `salePriceMax` (number; nullable): Compra: teto. Abaixo do piso é recusado. - `rentPriceMin` (number; nullable): Aluguel: piso. - `rentPriceMax` (number; nullable): Aluguel: teto. Abaixo do piso é recusado. - `bedrooms` (integer; nullable): Quartos, no mínimo. - `bathrooms` (integer; nullable): Banheiros, no mínimo. - `parkingSpots` (integer; nullable): Vagas, no mínimo. - `areaMin` (number; nullable): Área mínima, em m². ### LeadInput Os campos que a API aceita no cliente. Campo desconhecido é erro; campo ausente não apaga. - `externalRef` (string): O código do cliente no seu sistema (só no POST). - `name` (string): Nome. Obrigatório na criação. - `phones` (array): Até 5 telefones. Na criação, telefone ou e-mail. - `email` (string; nullable): E-mail. - `status` (string; NEW | ATTENDING | PROPOSAL | WON | LOST): Etapa do atendimento. - `notes` (string): Anotações. - `preApproved` (boolean): Crédito pré-aprovado. - `sharedToNetwork` (boolean): O perfil pode receber imóveis de parceiros. - `interest` (InterestInput): Perfil de busca. - `ownerAccountId` (string): O corretor responsável, pelo id. - `ownerEmail` (string): O corretor responsável, pelo e-mail — é como o seu sistema o conhece. Sem responsável, vale a distribuição da imobiliária. - `lastActivityAt` (string): A última movimentação no SEU sistema. Só anda para a frente. Mais de 60 dias atrás na criação = o cliente entra arquivado (base histórica). - `consentGiven` (boolean): Obrigatório `true` na criação: a imobiliária declara ter a base legal para tratar o dado (Termos da API). ### LeadWriteResult O desfecho da escrita. - `outcome` (string): O que aconteceu: `CREATED`, `UPDATED`, `UNCHANGED`, `LINKED` (o código passou a apontar para um cliente que já existia pelo contato), `ARCHIVED` (criado arquivado, base histórica), `STATE_SET` (arquivado ou reativado), `ADDED` (atendimento registrado), `DELETED`, `ALREADY_DELETED`. - `dryRun` (boolean): Foi um ensaio — nada foi gravado. - `interaction` (object): O atendimento registrado (só em `POST /leads/{leadId}/interactions`). - `interaction.id` (string): Id do registro. - `interaction.type` (string): Tipo. - `interaction.note` (string; nullable): Anotação. - `interaction.at` (string; nullable): Quando aconteceu. ### PropertySnapshot O retrato do imóvel no par — o mesmo do card. Campos que a tela esconde saem nulos. - `title` (string; nullable): Título. - `type` (string; nullable): Subtipo. - `purpose` (string; nullable): Finalidade do par. - `purposes` (array): Finalidades do imóvel. - `price` (number; nullable): Preço (venda, ou aluguel quando o par é de locação). - `priceFrom` (boolean): O preço é "a partir de" (lançamento). - `rentPrice` (number; nullable): Aluguel. - `city` (string; nullable): Cidade. - `neighborhood` (string; nullable): Bairro. - `bedrooms` (integer; nullable): Quartos. - `bathrooms` (integer; nullable): Banheiros. - `parkingSpots` (integer; nullable): Vagas. - `area` (number; nullable): Área, em m². - `coverPhoto` (string; nullable): Capa. - `listingUrl` (string; nullable): Anúncio (nulo quando a tela também esconde). - `commissionPercent` (number; nullable): Comissão de venda, em %. - `rentCommissionMonths` (number; nullable): Comissão de locação, em aluguéis. - `splitListingPercent` (number; nullable): Parte de quem captou, em %. - `lastConfirmedAt` (string; nullable): Última confirmação de disponibilidade. - `deliveryDate` (string; nullable): Entrega (lançamento). - `developmentId` (string; nullable): Empreendimento. - `developmentName` (string; nullable): Nome do empreendimento. ### ClientSnapshot O retrato do cliente no par. - `masked` (boolean): O cliente é de parceiro e está mascarado. - `status` (string; nullable): Etapa do atendimento. - `preApproved` (boolean): Crédito pré-aprovado. - `purposes` (array): Finalidades procuradas. - `propertyTypes` (array): Tipos procurados. - `regions` (array): Regiões, por extenso. - `priceMin` (number; nullable): Piso. - `priceMax` (number; nullable): Teto. - `bedrooms` (integer; nullable): Quartos. - `parkingSpots` (integer; nullable): Vagas. - `areaMin` (number; nullable): Área mínima. - `name` (string; nullable): Nome — só com a permissão `leads:read` na chave e só quando a tela também mostra. Telefone, nunca. ### Counterpart O parceiro do outro lado. - `accountId` (string): Id da conta do parceiro. - `name` (string; nullable): Nome. - `type` (string; nullable): Tipo de conta. - `organization` (string; nullable): Imobiliária do parceiro. - `creci` (string; nullable): CRECI. - `creciVerified` (boolean): CRECI conferido. - `phone` (string; nullable): Telefone. ### Match Uma oportunidade: um imóvel que serve a um cliente. - `id` (string): Id da oportunidade (`m#{imóvel}#{cliente}#{lado}`). Tem `#`: mande codificado (`%23`) no caminho. - `scope` (string; INTERNAL | NETWORK | LAUNCH): `INTERNAL` (da própria carteira), `NETWORK` (com parceiros) ou `LAUNCH` (lançamento). - `status` (string): `NEW`, `FAVORITED`, `ARCHIVED` ou `REQUESTED` (virou pedido de parceria). - `score` (integer): Nota de 0 a 100. - `reasons` (array): Por que combina. - `gaps` (array): O que não combina. - `propertyId` (string; nullable): Imóvel. - `leadId` (string; nullable): Cliente. - `ownerAccountId` (string; nullable): O corretor da casa que recebe a oportunidade. - `ownerName` (string; nullable): Nome dele. - `locked` (boolean): Oportunidade de parceiro sem assinatura ativa — o parceiro fica escondido, como na tela. - `lostRelevance` (boolean): Deixou de combinar depois de uma mudança. - `property` (PropertySnapshot; nullable): O imóvel. - `client` (ClientSnapshot; nullable): O cliente. - `counterpart` (Counterpart; nullable): O parceiro (nulo quando é da casa ou está escondido). - `createdAt` (string): Quando foi criado (UTC). - `updatedAt` (string): Última alteração (UTC). ### MatchWriteResult O desfecho. - `outcome` (string): `APPLIED`; em ensaio, `WOULD_APPLY`. - `dryRun` (boolean): Foi um ensaio. ### Party Uma ponta da parceria. - `accountId` (string; nullable): Id da conta. - `name` (string; nullable): Nome. - `type` (string; nullable): Tipo de conta. ### Partnership Uma parceria. - `id` (string): Id da parceria. - `status` (string; PENDING | ACCEPTED | DECLINED | CANCELLED | LEAD_REGISTERED | CONTACTED | NEGOTIATING | PROPOSAL | WON | LOST): Etapa. - `kind` (string; nullable): `CLIENT_FOR_PROPERTY` ou `PROPERTY_FOR_CLIENT`. - `propertyId` (string; nullable): Imóvel. - `leadId` (string; nullable): Cliente. - `matchId` (string; nullable): A oportunidade de origem. - `developmentId` (string; nullable): Empreendimento (registro em lançamento). - `developmentTitle` (string; nullable): Nome do empreendimento. - `score` (integer; nullable): Nota da oportunidade. - `summary` (string; nullable): Resumo. - `reasons` (array): Por que combina. - `message` (string; nullable): Mensagem do pedido. - `ourSide` (string; nullable): O lado da conta: `REQUESTER` (pediu) ou `ADDRESSEE` (recebeu). - `ourBrokerId` (string; nullable): O corretor da casa na parceria. - `canMoveFunnel` (boolean): A conta pode mover a etapa — só o lado que captou o cliente pode. - `requester` (Party; nullable): Quem pediu. - `addressee` (Party; nullable): Quem recebeu. - `counterpart` (object): O parceiro do outro lado. - `counterpart.name` (string; nullable): Nome. - `counterpart.type` (string; nullable): Tipo de conta. - `counterpart.organization` (string; nullable): Imobiliária. - `counterpart.contactName` (string; nullable): Contato. - `counterpart.phone` (string; nullable): Telefone. - `counterpart.email` (string; nullable): E-mail. - `counterpart.creci` (string; nullable): CRECI. - `counterpart.creciVerified` (boolean): CRECI conferido. - `property` (PropertySnapshot; nullable): O imóvel. - `client` (ClientSnapshot; nullable): O cliente. - `lastProgressAt` (string; nullable): Último avanço de etapa. - `protectedUntil` (string; nullable): Até quando o cliente fica protegido (lançamento). - `propertyOffMarketAt` (string; nullable): Quando o imóvel saiu do ar. - `createdAt` (string): Quando foi criado (UTC). - `updatedAt` (string): Última alteração (UTC). ### PartnershipWriteResult O desfecho. - `outcome` (string): O que aconteceu. - `dryRun` (boolean): Foi um ensaio. ### Member Uma pessoa da equipe. - `accountId` (string): Id da pessoa na plataforma. - `name` (string; nullable): Nome. - `email` (string; nullable): E-mail — é por ele que o seu sistema reconhece o corretor. - `phone` (string; nullable): Telefone. - `photoUrl` (string; nullable): Foto. - `creci` (string; nullable): CRECI (quem tem — a equipe também tem estagiários e administrativos). - `creciVerified` (boolean): CRECI conferido. - `status` (string): `active` ou `suspended`. - `canCaptureProperties` (boolean): Pode cadastrar imóvel e ser o responsável por ele. - `isSupervisor` (boolean): Supervisiona parte da equipe. - `supervisorId` (string; nullable): O supervisor desta pessoa. - `receivesLeadDistribution` (boolean): Entra na distribuição de clientes. - `firstAccessAt` (string; nullable): Primeiro acesso. ### FeedSync A sincronização do feed do CRM. Nunca traz o link nem o token. - `configured` (boolean): O link do feed do CRM está cadastrado na conta. - `connector` (string; nullable): O CRM do link (o formato do feed). - `autoSync` (boolean): A sincronização de 6 em 6 horas está ligada. - `status` (string; nullable): Como terminou a última sincronização (a mesma situação da tela) — `QUEUED` enquanto ela anda. - `message` (string; nullable): A frase da última sincronização, a mesma da tela. - `lastSyncAt` (string; nullable): Quando a última terminou. - `feedCount` (integer; nullable): Imóveis no feed na última leitura. - `counts` (object): O que a última sincronização fez. - `counts.created` (integer; nullable): Criados. - `counts.updated` (integer; nullable): Atualizados. - `counts.archived` (integer; nullable): Arquivados (saíram do feed e passaram da carência). - `counts.skipped` (integer; nullable): Pulados (incompletos ou fora da cota). - `counts.unchanged` (integer; nullable): Conferidos sem mudança (nada gravado). - `counts.confirmed` (integer; nullable): Confirmados (só a data de disponibilidade renovada). - `conflicts` (integer): Imóveis com campo editado na tela que o feed quis mudar — esperam a decisão em Imóveis › Importar. - `scheduledFor` (string; nullable): A sincronização agendada por `POST /v1/feed/sync` para o fim da janela (nulo = nenhuma). ### FeedSyncResult O desfecho. - `outcome` (string; QUEUED | SCHEDULED | ALREADY_SCHEDULED): `QUEUED` (sincroniza já) · `SCHEDULED` (agendada para o fim da janela de 10 minutos) · `ALREADY_SCHEDULED` (já havia uma agendada — nada novo). - `dryRun` (boolean): Foi ensaio (nada enfileirado). ### Typology Uma tipologia do empreendimento. - `id` (string): Id da tipologia. - `title` (string; nullable): Nome. - `type` (string; nullable): Subtipo. - `status` (string): Situação. - `salePrice` (number; nullable): Preço. - `bedrooms` (integer; nullable): Quartos. - `suites` (integer; nullable): Suítes. - `bathrooms` (integer; nullable): Banheiros. - `parkingSpots` (integer; nullable): Vagas. - `area` (number; nullable): Área privativa, em m². - `privateArea` (number; nullable): Área coberta, em m². - `coverPhoto` (string; nullable): Capa. - `floorPlans` (array): Plantas. - `unitFeatures` (array): Itens da unidade. - `unitsAvailable` (integer; nullable): Unidades disponíveis. - `unitsTotal` (integer; nullable): Unidades no total. ### Launch Um empreendimento do catálogo de lançamentos. - `id` (string): Id do empreendimento. - `title` (string; nullable): Nome. - `developer` (string; nullable): Construtora. - `address` (AddressArea): Endereço até o bairro (a rua não sai no catálogo). - `constructionStage` (string; nullable; LAUNCH | OFF_PLAN | NEW | READY): Estágio da obra. - `deliveryDate` (string; nullable): Previsão de entrega. - `constructionProgress` (integer; nullable): Andamento da obra, em %. - `coverPhoto` (string; nullable): Capa. - `amenities` (array): Itens do empreendimento. - `commissionPercent` (number; nullable): Comissão para o corretor, em %. - `priceMin` (number; nullable): Menor preço entre as tipologias. - `priceMax` (number; nullable): Maior preço. - `typologyCount` (integer): Quantas tipologias. - `typologies` (array): As tipologias. ### CaptacaoOffer Um proprietário da Captação. Os campos depois de `createdAt` só existem depois do aceite. - `id` (string): Id do proprietário na mesa. - `status` (string; nullable): Situação. - `purpose` (string; nullable): Venda ou locação. - `propertyType` (string; nullable): Subtipo. - `city` (string; nullable): Cidade. - `citySlug` (string; nullable): Identificador da cidade. - `neighborhood` (string; nullable): Bairro. - `bedrooms` (integer; nullable): Quartos. - `suites` (integer; nullable): Suítes. - `bathrooms` (integer; nullable): Banheiros. - `parkingSpots` (integer; nullable): Vagas. - `usableAreaDeclared` (number; nullable): Área útil que o proprietário declarou. - `areaDeclared` (number; nullable): Área total que o proprietário declarou. - `priceExpected` (number; nullable): Valor que o proprietário espera. - `sellTimeframe` (string; nullable): Prazo para vender: `AGORA`, `TRES_MESES`, `SEIS_MESES` ou `PESQUISANDO`. - `occupancy` (string; nullable): Ocupação: `PROPRIO` (o dono mora), `ALUGADO` ou `VAZIO`. - `ownerRelation` (string; nullable): Quem cadastrou: `DONO`, `COPROPRIETARIO`, `REPRESENTANTE` ou `OUTRO` (não é o proprietário). - `exclusivityOpenness` (string; nullable): Aceita exclusividade: `SIM` ou `NAO`. - `alreadyListedDeclared` (boolean): Disse que já anuncia em outro lugar. - `priceCents` (integer; nullable): O preço do contato, em centavos — o que o aceite debita. - `deadline` (string; nullable): Até quando dá para aceitar (o prazo corre só das 9h às 17h, nos dias de atendimento). - `matchingClients` (object): Quantos clientes da conta combinam. - `matchingClients.city` (integer; nullable): Clientes da conta que procuram algo assim na cidade (nulo = não deu para calcular). - `matchingClients.neighborhood` (integer; nullable): Os mesmos, no bairro. - `demand` (object; nullable): A procura medida pela plataforma. - `demand.available` (boolean): Há procura medida. - `demand.people` (integer; nullable): Pessoas procurando. - `demand.scope` (string; nullable): Abrangência. - `demand.scopeName` (string; nullable): Nome da abrangência. - `demand.asOf` (string; nullable): Data da medida. - `demand.label` (string; nullable): O que foi medido, por extenso. - `stockNeighborhood` (integer; nullable): Imóveis parecidos à venda no bairro. - `ownerNameMasked` (string; nullable): Nome mascarado (antes do aceite). - `ownerPhoneVerifiedVia` (string; nullable): Como o telefone do proprietário foi confirmado. - `ownerPhoneVerifiedAt` (string; nullable): Quando. - `revealed` (boolean): O contato já foi liberado para a conta (aceito). Antes disso, `owner` e `address` NÃO existem na resposta. - `createdAt` (string): Quando foi criado (UTC). - `owner` (object): O proprietário (só depois do aceite). - `owner.name` (string; nullable): Nome. - `owner.phone` (string; nullable): Telefone. - `owner.email` (string; nullable): E-mail. - `address` (object): O endereço (só depois do aceite). - `address.street` (string; nullable): Rua. - `address.number` (string; nullable): Número. - `address.complement` (string; nullable): Complemento. - `address.neighborhood` (string; nullable): Bairro. - `address.city` (string; nullable): Cidade. - `acceptedAt` (string; nullable): Quando foi aceito. - `acceptedVia` (object; nullable): Como foi aceito: pela tela ou pela API (com a chave, o IP e a versão do termo). - `refundUntil` (string; nullable): Até quando cabe pedir devolução. - `refundedAt` (string; nullable): Quando foi devolvido. - `soldAt` (string; nullable): Quando o imóvel foi vendido. - `stage` (string; nullable): Etapa na mesa. - `stageLabel` (string; nullable): Etapa por extenso. - `lostReason` (string; nullable): Motivo da perda. - `note` (string; nullable): Anotação. - `tab` (string; nullable): Aba da mesa: `ACTIVE`, `CAPTURED` ou `ARCHIVED`. ### CaptacaoSummary O resumo da mesa. - `pendingCount` (integer): Proprietários na vez da conta agora. - `balanceCents` (integer): Crédito, em centavos. - `subscriptionActive` (boolean): Assinatura do módulo em dia. - `platformActive` (boolean): O módulo está valendo na plataforma. - `paused` (boolean): A conta pausou o recebimento. - `pausedAuto` (boolean): Pausa automática (prazos vencidos em sequência). - `expiredStreak` (integer): Prazos vencidos em sequência. - `autoPauseAfter` (integer; nullable): A pausa automática vem depois de quantos. - `inActivation` (boolean): Em ativação (antes da 1ª recarga). - `leadsToFirstCharge` (integer; nullable): Aceites até a 1ª recarga. - `rechargePending` (boolean): Recarga em andamento. - `operatingCities` (array): Cidades atendidas. - `purposes` (array): Finalidades atendidas. - `serviceDays` (array): Dias de atendimento. ### CaptacaoAcceptResult O desfecho do aceite. - `outcome` (string): `ACCEPTED`, `ALREADY_ACCEPTED` (sem segundo débito) ou, em ensaio, `WOULD_ACCEPT`. - `dryRun` (boolean): Foi um ensaio — nada foi debitado. - `priceCents` (integer; nullable): O valor debitado (ou que seria), em centavos. ### Event Um evento. - `id` (string): Id do evento (`evt_…`) — o mesmo `webhook-id` da entrega. Use-o para não processar duas vezes. - `type` (string; property.created | property.updated | property.deleted | property.restored | property.purged | lead.created | lead.updated | lead.deleted | lead.restored | lead.purged | radar.client_summary | partnership.created | partnership.updated | captacao.offer_received | captacao.offer_accepted | captacao.offer_withdrawn): Tipo. - `createdAt` (string): Quando foi registrado (UTC). - `data` (object): O que mudou, enxuto: ids, o estado e `changedFields` (os NOMES dos campos que mudaram). Nunca nome, telefone, e-mail ou endereço — busque o detalhe pela leitura do recurso. ### Webhook Um endereço de webhook. O segredo nunca sai aqui. - `id` (string): Id do endereço (`wh_…`). - `url` (string): O endereço (só HTTPS). - `types` (array): Os tipos que ele recebe (vazio = todos os que a conta lê). - `description` (string; nullable): Descrição. - `status` (string; ACTIVE | DISABLED): `ACTIVE` ou `DISABLED`. - `disabledAt` (string; nullable): Quando foi desligado. - `disabledReason` (string; nullable): `GONE_410` (o seu sistema respondeu 410), `FAILURE_RATE` (metade ou mais das entregas falhou em 48 h) ou `MANUAL`. - `secretRotatedAt` (string; nullable): Última troca do segredo. - `previousSecretValidUntil` (string; nullable): Até quando o segredo anterior ainda assina junto (24 h depois da troca). - `createdAt` (string): Quando foi criado (UTC). - `updatedAt` (string): Última alteração (UTC). ### WebhookCreate Um endereço novo. - `url` (string): O endereço, só HTTPS e público. Credencial na URL é recusada. - `types` (array): Os tipos (ausente = todos os que a conta lê). - `description` (string; nullable): Descrição. ### WebhookUpdate O que mudar no endereço. - `url` (string): O endereço. - `types` (array): Os tipos. - `description` (string; nullable): Descrição. - `status` (string; ACTIVE | DISABLED): `ACTIVE` religa (limpa o motivo do desligamento) e `DISABLED` desliga. ### Delivery Uma entrega de evento a um endereço. - `id` (string): Id da entrega (`dlv_…`). - `eventId` (string; nullable): O evento entregue. - `type` (string; nullable): Tipo do evento. - `status` (string): `PENDING`, `RETRYING`, `DELIVERED`, `FAILED` (esgotou as tentativas) ou `SKIPPED` (o endereço estava desligado). - `attempts` (integer): Tentativas feitas. - `lastStatusCode` (integer; nullable): Último código HTTP do seu sistema. - `lastError` (string; nullable): Último erro. - `lastAttemptAt` (string; nullable): Última tentativa. - `nextAttemptAt` (string; nullable): Próxima tentativa (1 min, 5 min, 30 min, 2 h, 6 h e 12 h). - `deliveredAt` (string; nullable): Quando foi entregue. - `createdAt` (string; nullable): Quando a entrega foi aberta. ### WebhookTestResult O resultado do evento de teste (`webhook.test`). - `delivered` (boolean): O seu sistema respondeu 2xx. - `statusCode` (integer; nullable): O código que ele respondeu. - `error` (string; nullable): O motivo da falha. - `ms` (integer; nullable): Tempo da entrega, em ms. ### BatchCreated O lote recebido. - `id` (string): Id do lote (`b-…`). - `type` (string; properties | leads): `properties` ou `leads`. - `status` (string; QUEUED | RUNNING | DONE): `QUEUED`, ou `DONE` quando nenhum item era válido. - `total` (integer): Itens recebidos. - `accepted` (integer): Itens que seguiram para o processamento. - `rejected` (integer): Itens recusados na forma (veja o resultado). - `dryRun` (boolean): O lote inteiro é um ensaio. ### BatchItem O resultado de um item. - `index` (integer): Posição no pedido. - `externalRef` (string; nullable): O código do item. - `outcome` (string): O desfecho do item — os mesmos do PUT pelo código, mais `PENDING` (ainda na fila) e `REJECTED`. - `id` (string; nullable): O id do imóvel ou cliente. - `code` (string; nullable): O código de erro, quando recusado. - `detail` (string; nullable): Detalhe. - `invalidParams` (array; nullable): Os problemas de forma. - `photos` (string; nullable): A galeria (imóveis). ### Batch Um lote, com o desfecho de cada item. - `id` (string): Id do lote. - `type` (string; properties | leads): `properties` ou `leads`. - `status` (string; QUEUED | RUNNING | DONE): `QUEUED`, `RUNNING` ou `DONE`. - `dryRun` (boolean): Ensaio. - `total` (integer; nullable): Itens. - `processed` (integer; nullable): Itens com desfecho. - `counts` (object): Contagem por desfecho (`CREATED`, `UPDATED`, `REJECTED`…). - `createdAt` (string; nullable): Quando foi recebido. - `startedAt` (string; nullable): Quando começou. - `finishedAt` (string; nullable): Quando terminou. - `results` (array): O desfecho de cada item, na ordem do pedido. ### ConfirmItem O desfecho de um imóvel na confirmação. - `id` (string): O id pedido (quando o pedido veio por `ids`). - `ref` (string): O código pedido (quando o pedido veio por `refs`). - `propertyId` (string; nullable): O imóvel achado (nulo quando não achou). - `outcome` (string; CONFIRMED | ALREADY_CONFIRMED | NOT_FOUND): `CONFIRMED`, `ALREADY_CONFIRMED` (há menos de 24 h — não regrava) ou `NOT_FOUND`. ## Eventos `GET /v1/events`: em ordem, 30 dias de memória; guarde o `nextCursor` (sempre vem) e siga o cursor, nunca o relógio. O evento é enxuto: ids, estado e `changedFields` (os NOMES dos campos), nunca dado pessoal — leia o recurso para o valor novo. Cada tipo exige também a permissão de leitura do recurso. - `property.created` (`properties:read`): Imóvel cadastrado. data: `id`, `externalRef`, `status`, `updatedAt` - `property.updated` (`properties:read`): Imóvel alterado (campos em changedFields). data: `id`, `externalRef`, `status`, `changedFields`, `updatedAt` - `property.deleted` (`properties:read`): Imóvel na lixeira. data: `id`, `externalRef`, `status`, `updatedAt` - `property.restored` (`properties:read`): Imóvel tirado da lixeira. data: `id`, `externalRef`, `status`, `updatedAt` - `property.purged` (`properties:read`): Imóvel excluído de vez. data: `id`, `externalRef`, `status`, `updatedAt` - `lead.created` (`leads:read`): Cliente cadastrado. data: `id`, `externalRef`, `state`, `status`, `ownerAccountId`, `updatedAt` - `lead.updated` (`leads:read`): Cliente alterado (campos em changedFields). data: `id`, `externalRef`, `state`, `status`, `ownerAccountId`, `changedFields`, `updatedAt` - `lead.deleted` (`leads:read`): Cliente na lixeira. data: `id`, `externalRef`, `state`, `status`, `ownerAccountId`, `updatedAt` - `lead.restored` (`leads:read`): Cliente tirado da lixeira. data: `id`, `externalRef`, `state`, `status`, `ownerAccountId`, `updatedAt` - `lead.purged` (`leads:read`): Cliente excluído de vez. data: `id`, `externalRef`, `state`, `status`, `ownerAccountId`, `updatedAt` - `radar.client_summary` (`radar:read`): Oportunidades novas de um cliente, reunidas em alguns minutos. data: `leadId`, `newMatches`, `topScore`, `since`, `until` - `partnership.created` (`partnerships:read`): Parceria criada. data: `id`, `status`, `kind` - `partnership.updated` (`partnerships:read`): Parceria mudou de etapa ou de prazo. data: `id`, `status`, `previousStatus`, `changedFields` - `captacao.offer_received` (`captacao:read`): Proprietário chegou à vez da conta, com o prazo. data: `id`, `deadline` - `captacao.offer_accepted` (`captacao:read`): Proprietário aceito pela conta. data: `id`, `acceptedAt`, `via` - `captacao.offer_withdrawn` (`captacao:read`): Proprietário saiu da vez da conta (prazo vencido ou aceito por outra). data: `id` ## Webhooks - Cada entrega: `POST` JSON `{type, timestamp, data}` com os cabeçalhos `webhook-id` (o id do evento — o mesmo em toda tentativa; use-o para não processar duas vezes), `webhook-timestamp` (segundos desde 1970) e `webhook-signature`. - Assinatura (Standard Webhooks): `v1,` + base64 do HMAC-SHA256 de `{webhook-id}.{webhook-timestamp}.{corpo cru}`, com a chave = o segredo depois de `whsec_`, decodificado do base64. Pode vir mais de uma, separadas por espaço (troca de segredo): aceite se qualquer uma bater. Compare em tempo constante. - Recuse mensagem com mais de 5 minutos de diferença do relógio. Responda 2xx em até 10 s (processe depois, numa fila). - Sem 2xx, novas tentativas depois de 1 min, 5 min, 30 min, 2 h, 6 h, 12 h. A ordem não é garantida. `410` desliga o endereço; também desliga com 5+ entregas encerradas em 48 h e 50% ou mais falhando depois de todas as tentativas. - Trocar o segredo: o anterior segue assinando junto por 24 h. ## Erros - `unauthorized` (401) — Chave ausente, inválida, revogada ou vencida. O pedido chegou sem a chave, com uma chave que não existe, revogada no painel ou vencida. Mande a chave no cabeçalho `Authorization: Bearer imob_live_…`. Nunca na URL. Se ela venceu ou foi revogada, crie outra no painel, em Minha conta › Integração por API. - `access_not_active` (403) — A API desta conta não está ativa. A chave existe, mas a liberação da conta não está valendo neste instante. O dono da conta vê o motivo no painel, em Integração por API. - `access_denied` (403) — Acesso negado. A borda recusou o pedido antes de chegar à API. Confira a chave e o caminho. Se persistir, fale com a ImobyFlow com o `requestId`. - `IP_NOT_ALLOWED` (403) — Endereço de origem fora da lista da chave. A chave tem uma lista de IPs, e o pedido veio de um endereço fora dela. Inclua o endereço na lista da chave, no painel — ou chame a API do servidor que já está nela. - `ACCOUNT_INACTIVE` (403) — Conta inativa. A conta dona da chave não está ativa na plataforma. Fale com a ImobyFlow. - `NOT_REQUESTED` (403) — API não pedida para esta conta. A conta nunca pediu acesso à API. O dono pede em Minha conta › Integração por API. A liberação é feita conta a conta pela ImobyFlow. - `PENDING` (403) — Pedido de acesso em análise. O pedido de acesso ainda está sendo analisado. Espere a liberação. O dono recebe um e-mail quando ela sai. - `INFO_REQUESTED` (403) — Pedido de acesso aguardando informações. A ImobyFlow pediu mais informações sobre o pedido. O dono responde no painel, em Integração por API. - `DENIED` (403) — Pedido de acesso recusado. O pedido de acesso foi recusado. O motivo aparece no painel. Dá para pedir de novo depois de resolver. - `SUSPENDED` (403) — Acesso à API suspenso. A ImobyFlow suspendeu o acesso desta conta. Nada foi apagado. O motivo aparece no painel. Fale com a ImobyFlow para reativar. - `REVOKED` (403) — Acesso à API encerrado. O acesso foi encerrado e todas as chaves foram revogadas. Fale com a ImobyFlow. - `PLAN_NOT_ELIGIBLE` (403) — Plano sem acesso à API. O plano atual não inclui a API (imobiliária a partir de 2.000 imóveis, ou qualquer plano de construtora). Mude de plano em Minha conta › Assinatura. As chaves voltam a valer na hora, sem nada apagado. - `SUBSCRIPTION_INACTIVE` (403) — Assinatura em atraso. A assinatura não está em dia. A API exige assinatura em dia (o período de teste conta). Regularize em Minha conta › Assinatura. As chaves voltam a valer na hora. - `PILOT_EXPIRED` (403) — Período de piloto encerrado. A conta foi liberada por um período de piloto, e ele terminou. Fale com a ImobyFlow para seguir. - `scope_missing` (403) — A chave não tem a permissão desta rota. A rota exige uma permissão que esta chave não tem. `invalidParams` diz qual. Crie uma chave com a permissão no painel. Se ela não aparece para escolher, a liberação da conta não a inclui — fale com a ImobyFlow. - `rate_limited` (429) — Limite de chamadas por segundo atingido. Chamadas demais por segundo para a faixa da conta. Espere e tente de novo, com intervalo crescente (1 s, 2 s, 4 s…). Para muitos itens, use os lotes. - `monthly_quota_exceeded` (429) — Cota do mês esgotada. A conta usou todas as chamadas do mês. O dono foi avisado ao passar de 80%. A cota volta no dia 1º (UTC). Para aumentar, fale com a ImobyFlow. Sincronizar pelos eventos, em vez de reler a carteira inteira, gasta muito menos. - `route_not_found` (404) — Rota não encontrada. O caminho não existe. Confira o caminho: as rotas começam em `/v1/`. A referência lista todas. - `method_not_allowed` (405) — Método não permitido nesta rota. O caminho existe, mas não com este método. Confira o método na referência. - `bad_request` (400) — Requisição recusada. A borda recusou o pedido antes de chegar à API (pedido mal formado). Confira o método, o caminho e os cabeçalhos. - `invalid_param` (400) — Parâmetro inválido. Um ou mais campos do pedido estão errados. `invalidParams` traz TODOS de uma vez, com o caminho e o motivo (`required`, `unknown_field`, `one_of` com a lista `allowed`, `not_in_catalog` com `suggestions`…). Corrija cada item de `invalidParams`. Campo desconhecido é erro de propósito: um `bedroom` no lugar de `bedrooms` não pode passar calado. - `invalid_cursor` (400) — Cursor inválido — recomece a listagem sem ele. O cursor foi alterado, é de outra rota ou de outra conta. Recomece a listagem sem o `cursor` e siga o `nextCursor` de cada resposta, sem mexer nele. - `invalid_body` (400) — Corpo inválido — envie um objeto JSON. O corpo veio vazio ou não é JSON. Mande um objeto JSON com `Content-Type: application/json`. - `payload_too_large` (413) — Corpo grande demais. O corpo passou do teto: 256 KB por pedido, 4 MB por lote. Divida o lote em partes menores. - `not_found` (404) — Não encontrado. O id ou o código não existe nesta conta. Item de outra conta também responde 404 — nem confirma que existe. Confira o id. Para buscar pelo código do seu sistema, use as rotas `by-ref`. - `not_available` (403) — Recurso indisponível para este tipo de conta. O recurso não existe para este tipo de conta (por exemplo: equipe e clientes não existem para construtora). Use só os recursos do tipo da conta — `GET /v1/me` mostra o tipo e as permissões. - `invalid_idempotency_key` (400) — Idempotency-Key inválida (até 100 caracteres visíveis). A chave de idempotência tem espaço, caractere fora do ASCII visível ou mais de 100 caracteres. Use um identificador como um UUID. - `idempotency_key_reused` (422) — Idempotency-Key já usada com outro pedido. A mesma chave foi usada nas últimas 24 horas com outro corpo, método ou caminho. Gere uma chave nova para cada pedido diferente. Repita a MESMA chave só na re-tentativa do mesmo pedido. - `idempotency_in_progress` (409) — Um pedido com esta Idempotency-Key ainda está em andamento. A re-tentativa chegou antes de o pedido original terminar. Espere alguns segundos e repita — a resposta virá a mesma do original, com `Idempotent-Replayed: true`. - `concurrent_write` (409) — Outra gravação deste código está em andamento — tente de novo. Dois pedidos para o MESMO código chegaram juntos. A trava existe para não criar o imóvel em dobro. Tente de novo em alguns segundos. Evite mandar o mesmo código em paralelo. - `feed_sync_active` (409) — A sincronização automática do CRM está ligada nesta conta. Uma origem por conta: com o feed ligado, ele é a origem dos imóveis, e o que não estiver no XML seria arquivado no ciclo seguinte. Status e confirmação continuam liberados. Desligue o feed em Imóveis › Importar para a API assumir — ou siga pelo feed. - `feed_not_configured` (409) — O link do feed do CRM não está configurado nesta conta. `POST /v1/feed/sync` busca o link do feed que a conta cadastrou — e esta conta não tem link cadastrado. Cadastre o link em Imóveis › Importar › Sincronização do CRM, ou grave os imóveis pela API (`PUT /v1/properties/by-ref/{código}`). - `plan_limit_reached` (409) — Limite de imóveis ativos do plano atingido. Criar ou ativar este imóvel passaria do teto de imóveis ativos do plano. Atualizar quem já existe nunca é barrado. Arquive os que saíram do ar (`SOLD`, `RENTED`, `INACTIVE` não ocupam cota) ou mude de plano. - `property_in_trash` (409) — Imóvel na lixeira. O imóvel deste código está na lixeira. Recriar faria dois imóveis com o mesmo código. Restaure pela tela para voltar a atualizar. - `external_ref_exists` (409) — Já existe um imóvel com este código. O código (`externalRef`) já é de outro imóvel — ou, em clientes, de outro cliente. `invalidParams` traz o id. Use o PUT pelo código (`/by-ref/{código}`) para atualizar. - `invalid_property` (422) — Imóvel incompleto ou incoerente. Depois de juntar o pedido com o que já estava gravado, faltou o mínimo: tipo, finalidade, o preço de cada finalidade e a cidade. Complete os campos indicados no `detail`. - `shrink_guard` (409) — Trava de encolhimento: exclusões demais em 24 horas. A API já mandou para a lixeira 20% da carteira (e pelo menos 10 itens) nas últimas 24 horas. A trava existe para um laço ou um filtro invertido no seu sistema não esvaziar a carteira. Confira a integração. Se a exclusão for intencional, faça pela tela, onde há uma pessoa olhando. - `consent_required` (422) — Consentimento do cliente não declarado. Na criação, a imobiliária precisa declarar a base legal para tratar o dado do cliente (ela é a controladora). Mande `consentGiven: true`. A plataforma grava a data, a versão dos Termos e o canal. - `lead_exists` (409) — Já existe um cliente com este telefone ou e-mail. O contato já é de um cliente da conta (veio de um portal, da planilha). `invalidParams` traz o id. Use o PUT pelo código: ele VINCULA o seu código ao cliente que já existe (`LINKED`), sem duplicar. - `lead_linked_to_other_ref` (409) — O cliente com este contato já tem outro código do CRM. O contato pertence a um cliente que já está ligado a OUTRO código do seu sistema. Confira se são a mesma pessoa no seu sistema e use um código só. - `lead_in_trash` (409) — Cliente na lixeira. O cliente está na lixeira. Restaure pela tela para voltar a atualizar. - `captacao_not_active` (409) — A Captação não está ligada nesta conta. O módulo de Captação é para imobiliárias e é ligado pela ImobyFlow. Fale com a ImobyFlow para participar. - `captacao_terms_required` (403) — Aceite pela API sem o termo específico aceito no painel. Aceitar pela API gasta crédito e exige o termo do item 13 dos Termos da API, aceito pelo dono no painel. O dono aceita em Minha conta › Integração por API. - `offer_unavailable` (409) — Este proprietário não está mais disponível para a sua conta. O prazo terminou ou ele seguiu adiante. Quem levou não é dito — é informação de outra conta. Nada foi cobrado. Siga para os próximos da mesa. - `captacao_insufficient_credit` (409) — Crédito da Captação insuficiente. O crédito não cobre o preço deste contato. `invalidParams` traz o preço e o saldo, em centavos. Recarregue em Minha conta › Assinatura. - `webhook_url_refused` (422) — Endereço de webhook recusado. O endereço não é HTTPS, tem credencial embutida, não resolve, ou resolve para um IP interno. Use um endereço HTTPS público, sem usuário e senha na URL. - `webhook_limit_reached` (409) — Limite de webhooks da conta atingido. A conta já tem o número máximo de endereços da faixa. Apague um endereço sem uso — um endereço pode receber todos os tipos. - `request_refused` (422) — A plataforma recusou o pedido. Uma regra da plataforma recusou o pedido — a mesma que a tela aplicaria. O `detail` traz a frase da tela (em português). Leia o `detail`: ele diz o que ajustar. - `upstream_busy` (503) — Muitas requisições ao mesmo tempo — tente de novo em instantes. A plataforma está atendendo pedidos demais desta e de outras contas. Tente de novo com intervalo crescente. Mande menos pedidos em paralelo. - `upstream_timeout` (504) — A consulta demorou demais — tente uma página menor. A leitura passou do tempo. Use um `limit` menor ou um filtro mais estreito. - `upstream_unavailable` (503) — Serviço temporariamente indisponível. Uma peça da plataforma não respondeu. Tente de novo em instantes. Com `Idempotency-Key`, a re-tentativa de uma escrita é segura. - `authorizer_failure` (500) — Falha temporária ao validar a chave. A validação da chave falhou do nosso lado. Tente de novo em instantes. Se persistir, fale com a ImobyFlow com o `requestId`. - `internal` (500) — Erro interno. Falha nossa. Ela já foi registrada. Tente de novo em instantes. Se persistir, fale com a ImobyFlow com o `requestId`. ## Mudanças ### 2026-10-04 - SDKs oficiais em TypeScript, Python e PHP, gerados deste contrato: um método por rota, as páginas percorridas sozinhas, nova tentativa que nunca duplica uma escrita e a conferência da assinatura do webhook. - Exemplos de resposta (sucesso e erros) na coleção do Postman e no OpenAPI. A coleção pública do Postman acompanha cada versão. - `POST /v1/feed/sync`: o seu sistema avisa que a carteira mudou e a ImobyFlow busca o link do feed na hora, sem esperar as 6 horas; `GET /v1/feed` mostra o resultado. - Servidor MCP em `https://api.imobyflow.com.br/mcp`: agentes de IA leem e atualizam a conta com a mesma chave. Toda escrita roda em ensaio e só grava com confirmação. ### 2026-10-03 — 1.0.0 - Portal do desenvolvedor em português e inglês, gerado do contrato OpenAPI 3.1. - Uma página por código de erro — o endereço que vem no `type` de cada erro. - Coleção do Postman, OpenAPI em JSON e YAML e `llms.txt` para assistentes de IA. - Botão "Experimente" em cada rota: chama a API do navegador com a sua chave (leitura de verdade, escrita sempre em modo ensaio) e explica cada campo da resposta — o JSON anotado. ### 2026-10-02 - Webhooks assinados (Standard Webhooks), com nova tentativa por cerca de 21 horas, desligamento automático, reenvio e evento de teste. - Eventos (`GET /v1/events`): o que mudou na conta, em ordem, com 30 dias de memória. - Avisos por e-mail: chave vencendo, cota do mês em 80% e 100%, endereço de webhook desligado. - Lotes de até 500 imóveis ou clientes. - Captação: a mesa, os aceitos e o aceite, com permissão e termo próprios. - Ações: descartar e restaurar oportunidade, mover parceria e a lixeira com a trava de encolhimento. - Escrita de clientes (código do seu sistema, vínculo pelo contato, consentimento) e de imóveis (fotos por endereço, modo ensaio, `Idempotency-Key`). - Leitura: imóveis, clientes, oportunidades, parcerias, equipe e lançamentos. ### 2026-10-01 - A fundação: chaves por conta, liberação conta a conta, `GET /v1/me`, listas de valores e o catálogo de cidades e bairros.