# Atualizar atributos personalizados do lead

`POST /chat/lead/attrs`

Pasta: **CRM**

## Autenticação

```http
token: {{token}}
```

## Descrição

# Atualizar atributos personalizados do lead

Alias de `POST /chat/editLead` focado em atribuição e `custom_attrs`. Ideal quando o formulário do seu site já sabe a origem e você só precisa gravar source/ref/attrs sem reenviar todo o CRM.

## Endpoint

`POST {{baseUrl}}/chat/lead/attrs`

## Autenticação

Envie o token da instância no header `token: {{token}}`.

## Corpo da requisição

| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| `id` | string | Condicional | ID interno do registro de chat. |
| `chatid` | string | Condicional | JID do chat. Informe `id`, `chatid` ou `number`. |
| `number` | string | Condicional | Número do contato. |
| `lead_source` | string | Não | Origem (ex.: `website`). |
| `lead_medium` | string | Não | Meio (ex.: `form`). |
| `lead_campaign` | string | Não | Campanha. |
| `lead_ref` | string | Não | Referência curta. |
| `custom_attrs` | object | Não | Atributos livres (merge). Valor `""` remove a chave. |
| `replace_custom_attrs` | boolean | Não | Substitui o mapa inteiro quando `true`. |
| `lead_fields` | object | Não | Campos fixos 01–20. |
| `lead_name` | string | Não | Também aceita os campos CRM de `/chat/editLead`. |
| `lead_email` | string | Não | E-mail do lead. |
| `lead_status` | string | Não | Status no funil. |
| `lead_tags` | string[] | Não | Tags do lead. |

## Exemplo de Requisição

```bash
curl --request POST '{{baseUrl}}/chat/lead/attrs' \
  --header 'token: {{token}}' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "chatid": "5511999999999@s.whatsapp.net",
  "lead_source": "website",
  "lead_ref": "form-orcamento",
  "custom_attrs": {
    "page": "/precos",
    "utm_term": "plano-pro"
  },
  "replace_custom_attrs": false
}'
```

## Resposta de Sucesso

```json
{
  "success": true,
  "chat": {
    "id": "5511999999999@s.whatsapp.net",
    "wa_chatid": "5511999999999@s.whatsapp.net",
    "lead_name": "João Silva",
    "lead_email": "joao@exemplo.com",
    "lead_status": "qualificado",
    "lead_tags": ["vip", "suporte"],
    "lead_source": "website",
    "lead_medium": "cta",
    "lead_campaign": "home",
    "lead_ref": "landing-home",
    "lead_ctwa_clid": "",
    "lead_custom_attrs": { "plano": "pro", "cidade": "sp" },
    "lead_field01": "valor-campo-1",
    "lead_field10": "valor-campo-10"
  },
  "lead": {
    "name": "João Silva",
    "email": "joao@exemplo.com",
    "status": "qualificado",
    "tags": ["vip", "suporte"],
    "source": "website",
    "medium": "cta",
    "campaign": "home",
    "ref": "landing-home",
    "fields": { "field01": "valor-campo-1", "field10": "valor-campo-10" },
    "custom_attrs": { "plano": "pro", "cidade": "sp" }
  }
}
```

## Erros comuns

- `401 Unauthorized`: header `token` ausente ou inválido.
- `400 Bad Request`: JSON malformado ou sem identificador do chat.
- `404 Not Found`: chat não encontrado.
- `500 Internal Server Error`: falha ao persistir.

## Observações

Mesmo handler de `/chat/editLead` — use esta rota quando o fluxo for “só tracking/attrs”.

### Rastreamento de origem (site, Ads, parceiros)

A atribuição é **first-touch** em mensagens inbound (DM): a API só preenche campos vazios. Grupos são ignorados.

| Origem | Como rastrear |
|---|---|
| **Ads Meta (CTWA)** | Automático: `ctwaClid`, título/corpo do anúncio e `ExternalAdReply` na primeira mensagem. |
| **Seu site / landing** | Link `wa.me` com UTM/`ref` na mensagem pré-preenchida, **ou** `POST /chat/editLead` / `/chat/lead/attrs` quando o backend já sabe a origem. |
| **Parceiro / QR / bio** | Mesma ideia: `ref=parceiro-x` (ou UTM) no texto do link. |
| **Tracking invisível (stego)** | `POST /chat/lead/stego` gera `text` + `wa_me_url` com trailer HMAC. Secret via `POST /admin/lead/stego` (admintoken). |

**Exemplo de botão no site (captura automática):**

Encode **todo** o texto do `text=` (incluindo `&` e `=`). Se deixar `&utm_medium=...` fora do encode, o navegador trata como query do `wa.me` e o WhatsApp só recebe até o primeiro `&`.

```
https://wa.me/5511999999999?text=Oi!%20utm_source%3Dsite%26utm_medium%3Dcta%26utm_campaign%3Dhome%26ref%3Dlanding-home
```

Mensagem que chega no chat: `Oi! utm_source=site&utm_medium=cta&utm_campaign=home&ref=landing-home`.

Isso grava `lead_source=site`, `lead_medium=cta`, `lead_campaign=home`, `lead_ref=landing-home`.

Em JavaScript: `https://wa.me/55...?text=${encodeURIComponent("Oi! utm_source=site&utm_medium=cta&utm_campaign=home&ref=landing-home")}`.

**Webhook / SSE:** eventos `messages` inbound incluem o objeto `data.lead` (CRM + atribuição + `fields` + `custom_attrs`) quando houver dados no chat.

**Consulta:** `POST /chat/details` devolve o chat completo com as colunas `lead_*`.

- `custom_attrs`: merge por padrão; use `replace_custom_attrs: true` para substituir o mapa inteiro.
- `lead_fields`: chaves `01`…`20`, `field01` ou `lead_field01` → `lead_field01`…`lead_field20`.
- Atribuição via API sobrescreve campos enviados (não-vazios); captura inbound não sobrescreve first-touch.

## Corpo (exemplo)

```json
{
  "chatid": "5511999999999@s.whatsapp.net",
  "lead_source": "website",
  "lead_ref": "form-orcamento",
  "custom_attrs": {
    "page": "/precos",
    "utm_term": "plano-pro"
  },
  "replace_custom_attrs": false
}
```

## cURL

```bash
curl -X POST "{{baseUrl}}/chat/lead/attrs" \
  -H "token: {{token}}" \
  -H "Content-Type: application/json" \
  -d '{
  "chatid": "5511999999999@s.whatsapp.net",
  "lead_source": "website",
  "lead_ref": "form-orcamento",
  "custom_attrs": {
    "page": "/precos",
    "utm_term": "plano-pro"
  },
  "replace_custom_attrs": false
}'
```

---

[Índice da pasta](./index.md) · [Índice geral](../index.md) · [UI](https://gozap.dev/docs?op=crm/atualizar-atributos-personalizados-do-lead)
