/unstable/imoveis/home
Method: GET
Essa rota recebe os imóveis que foram selecionados no painel de integrações no campo “Site” com a tag “Home”
Ela aceita duas Query Strings opcionais:
limit?: number
availableFor?: "VENDA" | "LOCACAO"O parâmetro limit define a quantidade máxima de imóveis que será retornada.
Caso availableFor seja VENDA serão excluídos os imóveis que não estão disponíveis para venda.
Caso availableFor seja LOCACAO serão excluídos os imóveis que não estão disponíveis para locação.
Retorna uma lista de CardProperty
export async function getHomeProperties({
limit,
availableFor,
}: {
limit: number;
availableFor: AvailableFor;
}) {
const headers = new Headers();
headers.append("Authorization", `Bearer ${env.NONSTOP_TOKEN}`);
const response = await fetch(
`${BASE_URL}/${VERSION}/imoveis/home?limit=${limit}&availablefor=${availableFor}`,
{ headers, ...CONFIG },
);
if (response.ok) return (await response.json()) as CardProperty[];
return [];
}/unstable/imoveis/similar
Method: GET
Essa rota recebe os imóveis que foram selecionados no painel de integrações no campo “Site” e que tenham similaridade com o imóvel selecionado pela query string. A busca compara tipologia, distância, e o delta de preço e área.
Ela aceita três Query Strings:
id: string
limit?: number
availableFor: "VENDA" | "LOCACAO"O parâmetro id é obrigatório. Deve ser o id do imóvel com o qual se deseja comparar.
O parâmetro limit é opcional define a quantidade máxima de imóveis que será retornada.
O parâmetro availableFor é obrigatório.
Caso availableFor seja VENDA serão excluídos os imóveis que não estão disponíveis para venda.
Caso availableFor seja LOCACAO serão excluídos os imóveis que não estão disponíveis para locação.
Retorna uma lista de CardProperty
export async function getSimilar({
id,
limit,
availableFor,
}: {
id: string;
limit: number;
availableFor: AvailableFor;
}) {
const headers = new Headers();
headers.append("Authorization", `Bearer ${env.NONSTOP_TOKEN}`);
const response = await fetch(
`https://www.usenonstop.com/api/unstable/imoveis/similar?id=${id}&limit=${limit}&availableFor=${availableFor}`,
{ headers },
);
if (response.ok) return (await response.json()) as CardProperty[];
return [];
}/unstable/imoveis/[id]
Method: GET
Essa rota recebe as informações completas de um imóvel. Utilize o código nonStop como id (ex. PG5SM). Na URL criada pela nonStop o id é o último campo.
Por exemplo: apartamento-tipo-para-locacao-com-4-quartos-moema-sao-paulo-sp-id-PG5SM.
Retorna uma Property
export async function getProperty(base36Id: string) {
const headers = new Headers();
headers.append("Authorization", `Bearer ${env.NONSTOP_TOKEN}`);
const response = await fetch(`https://www.usenonstop.com/api/unstable/imoveis/${base36Id}`, {
headers
});
if (response.ok) return (await response.json()) as Property;
return null;
}/unstable/imoveis/estados
Method: GET
Essa rota recebe uma lista de todos os estados que contém imóveis selecionados no painel de integrações . Essa lista pode ser utilizada para alimentar um dropdown nos filtros de busca por exemplo.
Retorna uma lista de UF
export async function getStates() {
const headers = new Headers();
headers.append("Authorization", `Bearer ${env.NONSTOP_TOKEN}`);
const response = await fetch("https://www.usenonstop.com/api/unstable/imoveis/estados", {
headers
});
if (response.ok) return (await response.json()) as UF[];
return null;
}/unstable/imoveis/cidades
Method: GET
Essa rota recebe uma lista de todas as cidades que contém imóveis selecionados no
painel de integrações .
Essa lista pode ser utilizada para alimentar um autocomplete nos filtros de busca
por exemplo.
Ela aceita três Query Strings opcionais:
state?: UF | null
query?: string | null
limit?: numberO parâmetro state restringe a busca pelo estado selecionado.
O parâmetro query faz uma busca de texto pelo termo e retorna as cidades correspondentes.
Retorna uma lista de cidades como string.
export async function getCities({
state,
query,
limit = 10,
}: {
state?: string | null;
query?: string | null;
limit?: number;
}) {
const headers = new Headers();
headers.append("Authorization", `Bearer ${env.NONSTOP_TOKEN}`);
const response = await fetch(
`${BASE_URL}/${VERSION}/imoveis/cidades?state=${state}&query=${query}&limit=${limit}`,
{ headers, ...CONFIG },
);
if (response.ok) return (await response.json()) as string[];
return null;
}/unstable/imoveis/bairros
Method: GET
Essa rota recebe uma lista de todos os bairros que contém imóveis selecionados no painel de integrações . Eles vêm ordenados por relevância (os bairros com mais imóveis vêm primeiro).
Essa lista pode ser utilizada para criar links para as páginas dos imóveis mais relevantes ou para alimentar um dropdown/autocomplete com as opções para filtro.
Ela aceita cinco Query Strings opcionais:
state?: UF | null
city?: string | null
query?: string | null
limit?: number
areas?: string[]O parâmetro state restringe a busca pelo estado selecionado.
O parâmetro city restringe a busca pela cidade selecionada.
O parâmetro query faz uma busca de texto pelo termo e retorna os bairros correspondentes.
O parâmetro limit define a quantidade máxima de bairros que será retornada.
O parâmetro areas exclui da resposta os bairros da lista. Dessa forma você pode selecionar diversos bairros em um autocomplete e continuar recebendo uma quantidade de resultados na resposta compatível com o limit, desconsiderando os bairros que já foram selecionados.
Retorna uma lista de bairros como string.
export async function getAreas({
state,
city,
query,
areas = [],
}: {
state?: UF;
city?: string;
query?: string;
areas?: string[];
}) {
const headers = new Headers();
headers.append("Authorization", `Bearer ${env.NONSTOP_TOKEN}`);
const response = await fetch(
`https://www.usenonstop.com/api/unstable/imoveis/bairros?state=${state}&city=${city}&limit=${limit}
&query=${query}&areas=${areas.join(",")}`,
{ headers },
);
if (response.ok) return (await response.json()) as string[];
return [];
}/unstable/imoveis/todos
Method: GET
Essa rota recebe uma lista de todos os imóveis selecionados no painel de integrações .
Essa lista pode ser utilizada para criar a página de busca de imóveis do site de uma imobiliária.
Ela aceita as seguintes Query Strings:
availableFor: "VENDA" | "LOCACAO"
currentPage?: number //default: 1
perPage?: number //default: 10
sortBy?: PropertySort //default: "_id"
sortOrder?: 1 | -1 //default: 1
cursor?: string //_id do último item; ativa a paginação por seek
search?: string
minVal?: number
maxVal?: number
minPrivate?: number
maxPrivate?: number
minLand?: number
maxLand?: number
minFloor?: number
maxFloor?: number
minTax?: number
maxTax?: number
minCondo?: number
maxCondo?: number
minBaths?: number
minRooms?: number
minSuites?: number
minParkingLots?: number
accepts?: Accepts[]
status?: Status[]
type?: PropertyType[]
use?: Use[]
face?: Face[]
state?: UF
city?: string
areas?: string[]
condoFeatures?: FilterCondoFeature[]
features?: FilterFeature[]
userSlug?: string
collectionId?: string
selected?: string[]
paths?: string[]O parâmetro currentPage é opcional e define a página atual da paginação
(padrão: 1).
O parâmetro perPage é opcional e define a quantidade de resultados por página
(padrão: 10). Não há máximo.
⚠️ Os nomes são
perPageecurrentPage— nãolimitepage. A rota descarta em silêncio parâmetro que não reconhece, então?limit=100&page=2não dá erro: ela responde com os 10 primeiros imóveis, como se nada tivesse sido enviado. (limitexiste, mas em outras rotas:/imoveis/home,/imoveis/similare/imoveis/cidades.)
O parâmetro availableFor é opcional e irá remover os imóveis que não estejam
disponíveis para a transação selecionada. Quando omitido vale "VENDA".
⚠️ Para sincronizar o catálogo inteiro, faça duas passadas. Não existe valor “todos”: os únicos aceitos são
VENDAeLOCACAO. Com o padrão, os imóveis disponíveis apenas para locação nunca aparecem — e ototaltambém é só o de venda, então nada indica que estão faltando. Chame comavailableFor=VENDAe comavailableFor=LOCACAOe junte os resultados pelo campoid(um imóvel disponível para as duas transações aparece nas duas listas).
Os parâmetros sortBy e sortOrder são obrigatórios definem a ordenação dos resultados. sortBy é o campo e 1 para crescente ou -1 para decrescente.
O parâmetro cursor é opcional e ativa a paginação por seek (apenas com a
ordenação padrão por _id), recomendada para rolagem infinita: em vez de
currentPage, envie no cursor o _id do último imóvel da página anterior
(omita-o na primeira página). A resposta passa a trazer nextCursor — o _id
a enviar na próxima requisição, ou null quando não há mais páginas. O total
só é retornado na primeira página (sem cursor); guarde-o no cliente. Sem
cursor, a rota mantém a paginação clássica por currentPage.
O parâmetro search é obrigatório e é usado para realizar uma busca nos seguintes campos: endereço, condomínio, código nonStop, código imobiliária.
Os parâmetros minVal e maxVal são opcionais e irão definir os limites de preço de acordo com o tipo de transação selecionada (venda ou locação).
Os parâmetros minPrivate e maxPrivate são opcionais e irão definir os limites para área privativa dos imóveis.
Os parâmetros minLand e maxLand são opcionais e irão definir os limites para área de terreno dos imóveis.
Os parâmetros minFloor e maxFloor são opcionais e irão definir os limites para o andar dos imóveis.
Os parâmetros minTax e maxTax são opcionais e irão definir os limites para o valor do IPTU.
Os parâmetros minCondo e maxCondo são opcionais e irão definir os limites para o valor da taxa de condomínio.
O parâmetro minBaths é opcional e irá definir a quantidade mínima de banheiros.
O parâmetro minSuites é opcional e irá definir a quantidade mínima de suítes.
O parâmetro minParkingLots é opcional e irá definir a quantidade mínima de vagas de garagem.
O parâmetro accepts é opcional e irá filtrar por imóveis que aceitem permuta, financiamento, ou ambos.
O parâmetro status é opcional e irá filtrar por imóveis que estejam em um dos status selecionados.
O parâmetro type é opcional e irá filtrar por imóveis que sejam de uma das tipologias selecionadas.
O parâmetro use é opcional e irá filtrar por imóveis comerciais ou residenciais.
O parâmetro face é opcional e irá filtrar por imóveis com face para alguma das direções selecionadas.
O parâmetro state é opcional e irá filtrar os imóveis no estado selecionado.
O parâmetro city é opcional e irá filtrar os imóveis na cidade selecionada.
O parâmetro areas é opcional e irá filtrar os imóveis nos bairros selecionados.
O parâmetro condoFeatures é opcional e irá filtrar os imóveis que tenham todas as características selecionadas no condomínio.
O parâmetro features é opcional e irá filtrar os imóveis que tenham todas as características selecionadas.
O parâmetro userSlug é opcional e irá filtrar os imóveis onde o usuário em questão seja gestor primário ou secundário.
O parâmetro collectionId é opcional e restringe a resposta aos imóveis de uma coleção — o filtro salvo em /colecoes no painel da nonStop. É a forma de publicar um recorte do inventário (a carteira de um cliente, os imóveis de uma campanha, os lançamentos de um bairro) sem repetir critério nenhum na query string: todos os filtros salvos na coleção passam a valer de uma vez — inclusive os que não existem como parâmetro desta rota, como perímetro no mapa, exclusividade, gestor e “imóvel anunciado”.
Para descobrir o id, abra /colecoes, clique em compartilhar no card da coleção
e copie o valor de collectionId do link.
A coleção só estreita: o resultado é sempre a interseção com os imóveis
selecionados no painel de integrações, então ela nunca devolve um imóvel que não
esteja publicado no site. Paginação, total e ordenação seguem valendo
normalmente, já sobre o conjunto reduzido.
export async function getCollectionProperties(collectionId: string) {
const headers = new Headers();
headers.append("Authorization", `Bearer ${env.NONSTOP_TOKEN}`);
const response = await fetch(
`https://www.usenonstop.com/api/unstable/imoveis/todos?availableFor=VENDA&perPage=24¤tPage=1&collectionId=${collectionId}`,
{ headers },
);
if (response.ok) return (await response.json()) as { properties: CardProperty[]; total: number };
return { properties: [], total: 0 };
}⚠️ Coleção inexistente é erro, não lista cheia. Se o
collectionIdnão existir — ou não for um id válido — a resposta é 400 com{"error": "Coleção não encontrada"}(ou"Coleção inválida"). A rota nunca cai de volta para o inventário inteiro: quem filtra por coleção está justamente excluindo imóveis, e responder a lista completa em silêncio publicaria imóvel a mais.
⚠️ Os critérios se somam, não se substituem. O que vem na query string vale junto com o que está salvo na coleção. O caso que mais pega: esta rota assume
availableFor=VENDAquando o parâmetro é omitido, então uma coleção de locação chamada semavailableFor=LOCACAOdevolve apenas os imóveis que também estão à venda — uma lista curta, não vazia, e sem erro nenhum para avisar (numa conta real: 29 imóveis viraram 3). Se a coleção já define a transação, repita a mesma transação na query string.
O parâmetro selected é opcional e aceita uma lista de base36Ids. Essa informação é usada para retornar os imóveis selecionados no mapa.
O parâmetro paths é opcional e aceita uma lista de perímetros codificados pela função: google.maps.geometry.encoding.encodePath(). Podem ser convertidos novamente em LatLngTuple[][] pela função: google.maps.geometry.encoding.decodePath()
⚠️ O nome do parâmetro é
paths. Até 28/08/2026 esta página diziaperimeters, que a rota nunca aceitou: como ela descarta em silêncio parâmetro desconhecido, quem seguiu a documentação recebeu 200 com a lista inteira, sem o recorte do mapa e sem nenhum erro. Se a sua integração desenha polígono, confira o nome que está enviando.
Retorna um objeto com a lista de CardProperty que serão exibidas na paginação e o total de resultados.
Cada card traz rooms e suites — ambos null quando o imóvel não é
residencial —, então dá para exibir dormitórios e suítes direto na listagem, sem
uma segunda chamada na ficha do imóvel.
export async function getAllProperties(body: PropertiesApiBody, query: PropertiesQuery) {
const {
perPage,
currentPage,
availableFor,
sortBy,
sortOrder,
search,
minVal,
maxVal,
minPrivate,
maxPrivate,
minLand,
maxLand,
minFloor,
maxFloor
minBaths,
minRooms,
minSuites,
minParkingLots,
accepts,
use,
userSlug,
face,
status,
type,
state,
city,
areas,
condoFeatures,
features,
selected,
paths
} = query;
const headers = new Headers();
headers.append("Authorization", `Bearer ${env.NONSTOP_TOKEN}`);
const response = await fetch(`https://www.usenonstop.com/api/unstable/imoveis/todos?
perPage=${perPage}¤tPage=${currentPage}&availableFor=${availableFor}&sortBy=${sortBy}
&sortOrder=${sortOrder}&search=${search}&minVal=${minVal}&maxVal=${maxVal}
&minPrivate=${minPrivate}$maxPrivate=${maxPrivate}$minLand=${minLand}&maxLand=${maxLand}
&minFloor=${minFloor}&maxFloor=${maxFloor}&minBaths=${minBaths}&minRooms${minRooms}
&minSuites=${minSuites}&minParkingLots=${minParkingLots}&accepts=${accepts}&use=${use}
&userSlug=${useSlug}&face=${face}&status=${status}&type=${type}&state=${state}&city=${city}
&areas=${areas}&condoFeatures=${condoFeatures}&features=${features}&selected=${selected}
&paths=${paths}`, {
headers,
});
if (response.ok)
return (await response.json()) as {
properties: CardProperty[];
total?: number; // sempre com currentPage; só na 1ª página (sem cursor) no seek
nextCursor?: string | null; // apenas na paginação por cursor
advertiser: { id: string; slug: string; name: string | null } | null;
};
return {properties: [], total: 0};
}O campo advertiser diz de qual conta vieram esses imóveis — é a conta dona do
token enviado. Vale conferir na primeira integração e sempre que um número não
fechar: se o slug não for o do cliente que você espera, o token é de outra conta
e todos os números daquela chamada são da conta errada.
/unstable/imoveis/markers
Method: GET
Essa rota recebe uma lista de marcadores clusterizados para mostrar no mapa. Os clusters são criados com todos os imóveis filtrados na rota /imoveis/todos. O campo selected mostra quais marcadores estão ativos no filtro de selectedProperties.
Ela aceita as seguintes Query Strings:
availableFor: "VENDA" | "LOCACAO"
search?: string
minVal?: number
maxVal?: number
minPrivate?: number
maxPrivate?: number
minLand?: number
maxLand?: number
minFloor?: number
maxFloor?: number
minTax?: number
maxTax?: number
minCondo?: number
maxCondo?: number
minBaths?: number
minRooms?: number
minSuites?: number
minParkingLots?: number
accepts?: Accepts[]
status?: Status[]
type?: PropertyType[]
use?: Use[]
face?: Face[]
state?: UF
city?: string
areas?: string[]
condoFeatures?: FilterCondoFeature[]
features?: FilterFeature[]
userSlug?: string
collectionId?: string
selected?: string[]
paths?: string[]
zoom: number
bounds: stringO parâmetro zoom é obrigatório e recebe um número para configurar o zoom do mapa.
O parâmetro bounds é obrigatório e recebe uma string com uma string JSON no formato MapBounds.
O restante dos parâmetros daqui são os mesmos que são utilizados na rota /imoveis/todos —
inclusive o collectionId, que aqui vale para os marcadores exatamente como
vale para a lista (mesma interseção com os imóveis do site e mesmo 400 de
coleção inexistente). Mande o mesmo collectionId nas duas rotas para o mapa e
a listagem não divergirem.
Retorna uma lista de Marker que serão exibidas na paginação e o total de resultados.
export async function getMarkers(body: MarkersApiBody) {
const {
availableFor,
search,
minVal,
maxVal,
minPrivate,
maxPrivate,
minLand,
maxLand,
minFloor,
maxFloor,
minBaths,
minRooms,
minSuites,
minParkingLots,
accepts,
minTax,
maxTax,
minCondo,
maxCondo,
use,
face,
state,
city,
areas,
condoFeatures,
features,
status,
type,
userSlug,
selected,
paths
zoom,
bounds
} = query;
const headers = new Headers();
headers.append("Authorization", `Bearer ${env.NONSTOP_TOKEN}`);
const response = await fetch(`https://www.usenonstop.com/api/unstable/imoveis/markers?
availableFor=${availableFor}&search=${search}&minVal=${minVal}&maxVal=${maxVal}
&minPrivate=${minPrivate}$maxPrivate=${maxPrivate}$minLand=${minLand}&maxLand=${maxLand}
&minFloor=${minFloor}&maxFloor=${maxFloor}&minBaths=${minBaths}&minRooms${minRooms}
&minSuites=${minSuites}&minParkingLots=${minParkingLots}&accepts=${accepts}&use=${use}
&userSlug=${useSlug}&face=${face}&status=${status}&type=${type}&state=${state}&city=${city}
&areas=${areas}&condoFeatures=${condoFeatures}&features=${features}&selected=${selected}
&paths=${paths}&zoom=${zoom}&bounds=${bounds}`, {
headers,
});
if (response.ok) return (await response.json()) as Marker[];
return [];
}