Pular para o conteúdo

Negociações (Deals)

Esta seção documenta os endpoints para gerenciamento de negociações no CRM.


Negociações (deals) representam oportunidades de negócio no funil de vendas ou locação. Cada negociação pode conter:

  • Contatos - Pessoas envolvidas (compradores, vendedores, inquilinos)
  • Anúncios - Imóveis vinculados à negociação
  • Tarefas - Atividades de acompanhamento
  • Histórico - Timeline de eventos e interações

GET /api/v1/crm/deals

Parâmetros de Query:

ParâmetroTipoDescrição
pagenumberNúmero da página (default: 1)
pageSizenumberItens por página (default: 50, max: 100)
dealTypestringFiltrar por tipo: rental ou sale
stagestringFiltrar por etapa do funil
statusstringFiltrar por status: open, won, lost
assignedToIduuidFiltrar por responsável
marketingChannelInstanceIduuidFiltrar por canal de marketing
customFiltersjsonFiltrar por campos customizados (URL encoded)

Exemplo:

Janela do terminal
curl -X GET "https://app.garagem.ai/api/v1/crm/deals?dealType=rental&stage=lead&pageSize=20" \
-H "Authorization: Bearer sua_api_key"

Resposta:

{
"items": [
{
"id": "uuid-do-deal",
"title": "Lead do Site - João Silva",
"dealType": "rental",
"stage": "lead",
"status": "open",
"currency": "BRL",
"amount": "3500.00",
"contacts": [
{
"id": "uuid-do-contato",
"name": "João Silva",
"email": "[email protected]",
"phone": "+5511999999999",
"role": "buyer"
}
],
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-15T10:30:00Z"
}
],
"total": 150,
"page": 1,
"pageSize": 20
}
GET /api/v1/crm/deals/{id}

Exemplo:

Janela do terminal
curl -X GET "https://app.garagem.ai/api/v1/crm/deals/uuid-do-deal" \
-H "Authorization: Bearer sua_api_key"
POST /api/v1/crm/deals

Body:

{
"title": "Lead do Site - João Silva",
"dealType": "rental",
"stage": "lead",
"status": "open",
"currency": "BRL",
"contacts": [
{
"name": "João Silva",
"email": "[email protected]",
"phone": "+5511999999999",
"role": "buyer"
}
]
}

Para já criar a negociação com um corretor responsável, use um destes campos (precedência: assignedToId > assignedToEmail > assignedToPhone):

CampoTipoDescrição
assignedToIduuidID do usuário (corretor) responsável.
assignedToEmailstringE-mail do corretor. Resolvido para o assignedToId no servidor.
assignedToPhonestringTelefone do corretor (qualquer formato). Resolvido no servidor.

assignedToEmail e assignedToPhone são conveniências de entrada: o servidor os converte para assignedToId e não os persiste. Apenas membros ativos do tenant são considerados; se o e-mail/telefone não corresponder a nenhum corretor ativo, a requisição falha com 400 (a negociação não é criada). Quando nenhum desses campos é enviado, a negociação fica com quem criou (ou é distribuída automaticamente quando há marketingChannelInstanceId).

Janela do terminal
curl -X POST https://app.garagem.ai/api/v1/crm/deals \
-H "Authorization: Bearer sua_api_key" \
-H "Content-Type: application/json" \
-d '{
"title": "Compra Apto 101 - Maria",
"dealType": "sale",
"assignedToEmail": "[email protected]",
"contacts": [
{ "name": "Maria", "phone": "+5511988887777", "role": "buyer" }
]
}'

Exemplo Completo com Marketing e Preferências:

Janela do terminal
curl -X POST https://app.garagem.ai/api/v1/crm/deals \
-H "Authorization: Bearer sua_api_key" \
-H "Content-Type: application/json" \
-d '{
"title": "Lead do Google Ads - João Silva",
"dealType": "rental",
"stage": "lead",
"status": "open",
"currency": "BRL",
"contacts": [
{
"name": "João Silva",
"email": "[email protected]",
"phone": "+5511999999999",
"role": "buyer"
}
],
"utmSource": "google",
"utmMedium": "cpc",
"utmCampaign": "apartamentos-zona-sul",
"source": "Google Ads",
"campaign": "Apartamentos Zona Sul",
"custom": {
"maxPrice": 4000,
"minPrice": 2000,
"locations": ["Zona Sul", "Copacabana"],
"propertyTypes": ["apartment"],
"bedrooms": 2,
"observacoes": "Cliente prefere andar alto"
}
}'

Resposta:

{
"id": "uuid-do-deal-criado",
"title": "Lead do Google Ads - João Silva",
"dealType": "rental",
"stage": "lead",
"status": "open",
"currency": "BRL",
"createdAt": "2024-01-15T10:30:00Z"
}
PATCH /api/v1/crm/deals/{id}

Body:

{
"id": "uuid-do-deal",
"data": {
"stage": "proposta",
"status": "open",
"amount": "3200.00",
"custom": {
"valor_proposta": 3200,
"data_proposta": "2024-01-18"
}
}
}

Exemplo:

Janela do terminal
curl -X PATCH https://app.garagem.ai/api/v1/crm/deals/uuid-do-deal \
-H "Authorization: Bearer sua_api_key" \
-H "Content-Type: application/json" \
-d '{
"id": "uuid-do-deal",
"data": {
"stage": "proposta",
"amount": "3200.00"
}
}'

Reatribuir corretor: data também aceita assignedToId, assignedToEmail e assignedToPhone (mesma precedência e regras da criação — e-mail/telefone são resolvidos para assignedToId no servidor e falham com 400 se não corresponderem a um corretor ativo).

DELETE /api/v1/crm/deals/{id}

CampoTipoObrigatórioDescrição
titlestringSimTítulo da negociação
dealTypeenumSimrental ou sale
stagestringEnviarEtapa do funil (ex: lead). Se omitido, o default é draft.
statusenumNãoopen, won, lost
currencystringNãoMoeda. Default BRL.
amountdecimalNãoValor da negociação
contactsarraySimLista de contatos (mínimo 1). Aceite name, role e email ou phone.
CampoTipoObrigatórioDescrição
namestringSimNome do contato
emailstringNão*Email (* obrigatório se não tiver phone)
phonestringNão*Telefone (* obrigatório se não tiver email)
roleenumSimbuyer, seller, tenant, landlord, etc.
cpfstringNãoCPF do contato

Enviados no nível superior (não em custom):

CampoTipoDescrição
utmSourcestringFonte do tráfego (google, facebook)
utmMediumstringMeio (cpc, organic, social)
utmCampaignstringNome da campanha
sourcestringOrigem legível
campaignstringCampanha legível
marketingChannelInstanceIduuidID do canal de marketing

📖 Veja Campos Customizados para mais detalhes sobre marketing attribution.

Enviados dentro de custom:

CampoTipoDescrição
maxPricenumberPreço máximo
minPricenumberPreço mínimo
locationsstring[]Localizações preferidas
propertyTypesstring[]Tipos de imóvel
bedroomsnumberNúmero mínimo de quartos
bathroomsnumberNúmero mínimo de banheiros
minAreanumberÁrea mínima em m²
maxAreanumberÁrea máxima em m²
budgetnumberOrçamento
additionalNotesstringNarrativa da busca. Não há campo nativo de prazo de compra; use este texto.

Cidade e bairros vão em locations (array de strings).

Dentro de custom (persistido como customData):

"leadListings": [{ "listingId": "uuid-do-anuncio" }]

listingId precisa ser UUID. Código de anúncio nesse campo é descartado.

POST /api/v1/crm/deals não tem chave de idempotência. Reenviar o mesmo formulário cria outra negociação. Para lead de interesse em anúncio, com deduplicação, use o webhook de canal e originLeadId.

Não há campo nativo de consentimento LGPD. O aceite precisa ser um campo customizado já configurado no tenant, ou texto em additionalNotes.

GET /api/v1/crm/deals/{id} devolve assignedToId e não devolve nome, foto nem telefone do corretor. Para o cartão público, veja Sites API — Corretor responsável.


As etapas são configuráveis por tenant. Valores comuns:

EtapaDescrição
leadNovo lead (entrada no funil)
qualificacaoEm qualificação
visitaVisita agendada/realizada
propostaProposta enviada
negociacaoEm negociação
fechamentoEm processo de fechamento
ganhoNegócio fechado (etapa terminal)
perdidoNegócio perdido (etapa terminal)

Use o parâmetro customFilters para filtrar por campos dentro de custom:

Janela do terminal
# Filtrar por aceita_financiamento = true
curl -X GET "https://app.garagem.ai/api/v1/crm/deals?customFilters=%7B%22aceita_financiamento%22%3Atrue%7D" \
-H "Authorization: Bearer sua_api_key"
# Filtrar por maxPrice <= 4000
curl -X GET "https://app.garagem.ai/api/v1/crm/deals?customFilters=%7B%22maxPrice%22%3A4000%7D" \
-H "Authorization: Bearer sua_api_key"

Nota: O customFilters deve ser uma string JSON codificada em URL.