Negociações (Deals)
Esta seção documenta os endpoints para gerenciamento de negociações no CRM.
📖 Visão Geral
Seção intitulada “📖 Visão Geral”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
📊 Endpoints
Seção intitulada “📊 Endpoints”Listar Negociações
Seção intitulada “Listar Negociações”GET /api/v1/crm/dealsParâmetros de Query:
| Parâmetro | Tipo | Descrição |
|---|---|---|
page | number | Número da página (default: 1) |
pageSize | number | Itens por página (default: 50, max: 100) |
dealType | string | Filtrar por tipo: rental ou sale |
stage | string | Filtrar por etapa do funil |
status | string | Filtrar por status: open, won, lost |
assignedToId | uuid | Filtrar por responsável |
marketingChannelInstanceId | uuid | Filtrar por canal de marketing |
customFilters | json | Filtrar por campos customizados (URL encoded) |
Exemplo:
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", "phone": "+5511999999999", "role": "buyer" } ], "createdAt": "2024-01-15T10:30:00Z", "updatedAt": "2024-01-15T10:30:00Z" } ], "total": 150, "page": 1, "pageSize": 20}Buscar Negociação por ID
Seção intitulada “Buscar Negociação por ID”GET /api/v1/crm/deals/{id}Exemplo:
curl -X GET "https://app.garagem.ai/api/v1/crm/deals/uuid-do-deal" \ -H "Authorization: Bearer sua_api_key"Criar Negociação
Seção intitulada “Criar Negociação”POST /api/v1/crm/dealsBody:
{ "title": "Lead do Site - João Silva", "dealType": "rental", "stage": "lead", "status": "open", "currency": "BRL", "contacts": [ { "name": "João Silva", "phone": "+5511999999999", "role": "buyer" } ]}Atribuir um corretor na criação
Seção intitulada “Atribuir um corretor na criação”Para já criar a negociação com um corretor responsável, use um destes campos
(precedência: assignedToId > assignedToEmail > assignedToPhone):
| Campo | Tipo | Descrição |
|---|---|---|
assignedToId | uuid | ID do usuário (corretor) responsável. |
assignedToEmail | string | E-mail do corretor. Resolvido para o assignedToId no servidor. |
assignedToPhone | string | Telefone 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).
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:
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"}Atualizar Negociação
Seção intitulada “Atualizar Negociação”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:
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:
datatambém aceitaassignedToId,assignedToEmaileassignedToPhone(mesma precedência e regras da criação — e-mail/telefone são resolvidos paraassignedToIdno servidor e falham com 400 se não corresponderem a um corretor ativo).
Deletar Negociação
Seção intitulada “Deletar Negociação”DELETE /api/v1/crm/deals/{id}📋 Campos da Negociação
Seção intitulada “📋 Campos da Negociação”Campos Principais
Seção intitulada “Campos Principais”| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
title | string | Sim | Título da negociação |
dealType | enum | Sim | rental ou sale |
stage | string | Enviar | Etapa do funil (ex: lead). Se omitido, o default é draft. |
status | enum | Não | open, won, lost |
currency | string | Não | Moeda. Default BRL. |
amount | decimal | Não | Valor da negociação |
contacts | array | Sim | Lista de contatos (mínimo 1). Aceite name, role e email ou phone. |
Campos de Contato
Seção intitulada “Campos de Contato”| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
name | string | Sim | Nome do contato |
email | string | Não* | Email (* obrigatório se não tiver phone) |
phone | string | Não* | Telefone (* obrigatório se não tiver email) |
role | enum | Sim | buyer, seller, tenant, landlord, etc. |
cpf | string | Não | CPF do contato |
Campos de Marketing Attribution
Seção intitulada “Campos de Marketing Attribution”Enviados no nível superior (não em custom):
| Campo | Tipo | Descrição |
|---|---|---|
utmSource | string | Fonte do tráfego (google, facebook) |
utmMedium | string | Meio (cpc, organic, social) |
utmCampaign | string | Nome da campanha |
source | string | Origem legível |
campaign | string | Campanha legível |
marketingChannelInstanceId | uuid | ID do canal de marketing |
📖 Veja Campos Customizados para mais detalhes sobre marketing attribution.
Campos de Preferências de Busca
Seção intitulada “Campos de Preferências de Busca”Enviados dentro de custom:
| Campo | Tipo | Descrição |
|---|---|---|
maxPrice | number | Preço máximo |
minPrice | number | Preço mínimo |
locations | string[] | Localizações preferidas |
propertyTypes | string[] | Tipos de imóvel |
bedrooms | number | Número mínimo de quartos |
bathrooms | number | Número mínimo de banheiros |
minArea | number | Área mínima em m² |
maxArea | number | Área máxima em m² |
budget | number | Orçamento |
additionalNotes | string | Narrativa da busca. Não há campo nativo de prazo de compra; use este texto. |
Cidade e bairros vão em locations (array de strings).
Imóvel relacionado
Seção intitulada “Imóvel relacionado”Dentro de custom (persistido como customData):
"leadListings": [{ "listingId": "uuid-do-anuncio" }]listingId precisa ser UUID. Código de anúncio nesse campo é descartado.
O que este endpoint não faz
Seção intitulada “O que este endpoint não faz”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.
🔄 Etapas do Funil (Stages)
Seção intitulada “🔄 Etapas do Funil (Stages)”As etapas são configuráveis por tenant. Valores comuns:
| Etapa | Descrição |
|---|---|
lead | Novo lead (entrada no funil) |
qualificacao | Em qualificação |
visita | Visita agendada/realizada |
proposta | Proposta enviada |
negociacao | Em negociação |
fechamento | Em processo de fechamento |
ganho | Negócio fechado (etapa terminal) |
perdido | Negócio perdido (etapa terminal) |
🔍 Filtrar por Campos Customizados
Seção intitulada “🔍 Filtrar por Campos Customizados”Use o parâmetro customFilters para filtrar por campos dentro de custom:
# Filtrar por aceita_financiamento = truecurl -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 <= 4000curl -X GET "https://app.garagem.ai/api/v1/crm/deals?customFilters=%7B%22maxPrice%22%3A4000%7D" \ -H "Authorization: Bearer sua_api_key"Nota: O
customFiltersdeve ser uma string JSON codificada em URL.
📚 Mais Informações
Seção intitulada “📚 Mais Informações”- Tarefas - Criar tarefas vinculadas a negociações
- Campos Customizados - Marketing attribution e preferências
- Webhooks - Receber eventos de negociações
- Exemplos Práticos - Mais exemplos de uso