API do Horos
Coloque leads do seu site, sistema ou automação direto no funil do Horos e receba um aviso no seu sistema sempre que um lead entra, muda de etapa, vira venda ou é arquivado.
- Endereço base:
https://horos.sale/api/v1 - Formato: JSON em UTF-8, nos dois sentidos
- O lead entra no funil de quem é dono da chave. Se a chave for de um gestor com fila de distribuição, o lead passa pela fila igual aos leads do Meta Ads
- Telefone repetido não vira lead duplicado: a API devolve
409se já existe um lead ativo com o número, e reativa o lead se ele estava arquivado
Chave de API
- No Horos, abra Integrações → API e webhooks (ou o cartão Zapier / Make).
- Clique em Criar chave. Escolha se ela vale só para você ou para a imobiliária toda (só a diretoria cria chave da imobiliária).
- Copie a chave na hora: ela começa com
hrs_e aparece uma vez só. O Horos guarda só uma impressão dela.
Mande a chave em todo pedido, em um destes cabeçalhos:
Authorization: Bearer hrs_SUA_CHAVE
# ou
X-Api-Key: hrs_SUA_CHAVERespostas e erros
Deu certo: 200 (ou 201 ao criar). Deu errado: o corpo traz error.code e uma mensagem em português.
{ "error": { "code": "duplicate", "message": "Já existe um lead ativo com esse telefone (Maria Souza).", "lead_id": "API1A2B3C" } }| Status | code | Quando |
|---|---|---|
| 400 | invalid, invalid_phone, invalid_stage, invalid_temperature, empty | Faltou dado ou veio num formato que não dá para usar |
| 401 | invalid_key | Chave ausente, errada ou revogada |
| 402 | billing_inactive | A assinatura da imobiliária não está ativa |
| 404 | not_found | Lead não existe ou não é visível para esta chave |
| 409 | duplicate | Já existe um lead ativo com esse telefone (vem o lead_id dele) |
| 500 | internal | Erro do nosso lado. Tente de novo em alguns segundos |
Rotas
/v1/me
Confere se a chave funciona e diz de quem ela é. É o teste de conexão do Zapier e do Make.
curl https://horos.sale/api/v1/me -H "Authorization: Bearer hrs_SUA_CHAVE"{
"key": { "name": "Site", "scope": "me", "kind": "api" },
"user": { "id": "6f1c…", "name": "Ana Corretora" },
"workspace": { "id": "2a9e…", "name": "Imobiliária Exemplo" }
}/v1/stages
Etapas do funil do dono da chave, na ordem do Kanban. Use o id (ou o nome) ao criar ou mover um lead.
{ "data": [ { "id": "inbox", "name": "Inbox" }, { "id": "contato1", "name": "1º Contato" }, { "id": "fechado", "name": "Fechado" } ] }/v1/leads
Lista os leads, do mais novo para o mais antigo. Só os ativos, a não ser que peça os arquivados.
| Parâmetro | O que faz |
|---|---|
created_since | Criados a partir desta data (ISO 8601, ex. 2026-10-01T00:00:00Z) |
updated_since | Alterados a partir desta data (ordena pela última alteração) |
stage | Só uma etapa (id de /v1/stages) |
phone | Procura pelo telefone (com ou sem 55, com ou sem máscara) |
email | Procura pelo e-mail |
limit · offset | Paginação: até 100 por vez (padrão 50) |
include_archived=1 | Inclui os arquivados |
curl "https://horos.sale/api/v1/leads?phone=11999998888" -H "Authorization: Bearer hrs_SUA_CHAVE"/v1/leads/:id
Um lead pelo id. Devolve o objeto lead.
/v1/leads
Cria um lead. Mande pelo menos name, phone ou email; o telefone precisa ter DDD.
| Campo | Tipo | O que é |
|---|---|---|
name | texto | Nome do cliente |
phone | texto | Celular com DDD, em qualquer formato ((11) 99999-8888, 5511999998888…) |
email | texto | |
region | texto | Região ou bairro de interesse |
value | número ou texto | Valor do negócio em reais (450000 ou "R$ 450.000,00") |
temperature | texto | hot, warm ou cold (também aceita quente/morno/frio) |
stage | texto | Etapa inicial (id ou nome). Sem ela, entra no Inbox |
notes | texto | Observações |
origin | texto | Origem que aparece no lead. Padrão: api (ou zapier/make pela chave) |
utm | objeto | Parâmetros da campanha: source, medium, campaign… |
gclid | texto | Clique do Google Ads (liga as Conversões do Google Ads) |
custom_fields | objeto | Qualquer outra informação, guardada no lead |
curl -X POST https://horos.sale/api/v1/leads \
-H "Authorization: Bearer hrs_SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{
"name": "Maria Souza",
"phone": "(11) 99999-8888",
"email": "maria@exemplo.com",
"region": "Moema",
"value": 650000,
"temperature": "hot",
"notes": "Quer 3 quartos perto do metrô",
"utm": { "source": "site", "campaign": "lancamento-outubro" }
}'Respostas: 201 com o lead criado · 200 com "reactivated": true se o telefone era de um lead arquivado (ele volta para a etapa pedida) · 409 se já existe um lead ativo com esse telefone.
/v1/leads/:id
Altera só o que vier no corpo: stage, temperature, value, name, email, region, notes, custom_fields (soma aos que já existem).
curl -X PATCH https://horos.sale/api/v1/leads/API1A2B3C \
-H "Authorization: Bearer hrs_SUA_CHAVE" -H "Content-Type: application/json" \
-d '{ "stage": "fechado", "value": 640000 }'O objeto lead
{
"id": "API1A2B3C",
"name": "Maria Souza",
"phone": "11999998888",
"email": "maria@exemplo.com",
"region": "Moema",
"value": 650000,
"score": 42,
"temperature": "hot",
"stage": { "id": "contato1", "name": "1º Contato" },
"archived": false,
"origin": "api",
"owner_id": "6f1c…",
"utm": { "source": "site", "campaign": "lancamento-outubro" },
"notes": "Quer 3 quartos perto do metrô",
"custom_fields": null,
"created_at": "2026-10-14T13:05:22Z",
"updated_at": "2026-10-14T13:05:22Z",
"closed_at": null,
"url": "https://horos.sale/client?id=API1A2B3C"
}value vem null quando o lead está arquivado. closed_at é a data da venda. url abre a ficha no Horos (precisa estar logado).
Webhooks
O Horos manda um POST em JSON para o endereço que você cadastrar sempre que acontece um evento. Cadastre em Integrações → API e webhooks → Novo webhook (o botão Testar manda um evento de exemplo) ou por API.
POST https://seu-sistema.com/horos
Content-Type: application/json
X-Horos-Event: lead.stage_changed
X-Horos-Signature: sha256=5f2b…
{
"id": "18342",
"event": "lead.stage_changed",
"created_at": "2026-10-14T13:20:00Z",
"data": {
"lead": { …o objeto lead… },
"previous_stage": { "id": "inbox", "name": "Inbox" }
}
}- Responda com qualquer status
2xxem até 10 segundos. - Se falhar, o Horos tenta de novo depois de 1, 5, 15, 60 e 180 minutos.
- Depois de 50 falhas seguidas o webhook é desligado e você recebe um aviso no Horos (aparece também em Integrações → Situação das integrações).
- O mesmo evento pode chegar mais de uma vez: use o
idpara não processar duas vezes.
Eventos
| Evento | Quando |
|---|---|
lead.created | Um lead entra no funil (por qualquer caminho: anúncio, portal, site, WhatsApp, importação, cadastro manual) |
lead.stage_changed | O lead muda de etapa (traz previous_stage) |
lead.won | O lead foi para a etapa Fechado (venda) |
lead.archived | O lead foi arquivado |
Conferir a assinatura
Cada webhook tem um segredo (whsec_…, mostrado ao criar). O cabeçalho X-Horos-Signature é o HMAC-SHA256 do corpo exato do pedido com esse segredo. Confira antes de confiar no conteúdo:
import crypto from 'node:crypto';
// rawBody = o corpo exatamente como chegou (texto), antes de converter para JSON
function horosOk(rawBody, header, secret) {
const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
return header && header.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(header), Buffer.from(expected));
}import hmac, hashlib
def horos_ok(raw_body: bytes, header: str, secret: str) -> bool:
expected = 'sha256=' + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(header or '', expected)Assinar webhooks por API
É assim que o Zapier e o Make fazem sozinhos. Útil também para o seu sistema se cadastrar.
| Rota | O que faz |
|---|---|
GET /v1/hooks | Lista os webhooks criados por esta chave |
POST /v1/hooks | Cria: { "url": "https://…", "events": ["lead.created"] } (ou "event"). Responde com o id e o secret |
DELETE /v1/hooks/:id | Apaga |
O endereço precisa ser https://. Se ele responder 410 Gone, o Horos apaga a assinatura sozinho.
Zapier e Make
- Em Integrações, abra o cartão Zapier ou Make e crie uma chave.
- No Zapier/Make, use o app de Webhooks (ou HTTP) apontando para as rotas acima, com o cabeçalho
Authorization: Bearer hrs_…. - Para receber eventos do Horos: crie um gatilho “Catch Hook” (Zapier) ou “Custom webhook” (Make), copie o endereço que ele gera e cadastre em Integrações → Novo webhook.
- Para mandar leads ao Horos: use a ação “POST” para
/v1/leadscom os campos do formulário.
Formulário do seu site
Não chame a API direto do navegador (a chave ficaria exposta). Duas opções seguras:
- Sem programar: use o formulário pronto do Horos (no CRM, botão Compartilhar → Compartilhar formulário), ou mande o formulário para o Zapier/Make e de lá para a API.
- Com programação: o formulário envia para o seu servidor, e o servidor chama
POST /v1/leadscom a chave. Guarde ogclidda URL da página e mande junto para ligar as Conversões do Google Ads.
// No seu servidor (ex.: rota que recebe o formulário)
const r = await fetch('https://horos.sale/api/v1/leads', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.HOROS_API_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ name: form.nome, phone: form.telefone, email: form.email, origin: 'site', gclid: form.gclid }),
});
if (r.status === 409) { /* já é lead — tudo bem */ }Dúvidas ou precisa de algo que a API ainda não faz? Fale com a gente.