> For the complete documentation index, see [llms.txt](https://ajuda.livechat360.com.br/crm/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ajuda.livechat360.com.br/crm/api-docs/convencoes.md).

# Convencoes

## Envelopes de resposta

Recurso único:

```json
{ "data": { ... } }
```

Listagem:

```json
{
  "data": [ ... ],
  "meta": { "page": 1, "per_page": 30, "total": 432, "total_pages": 15 }
}
```

Erro (qualquer 4xx/5xx):

```json
{ "errors": [ { "field": "sort", "detail": "Ordenação inválida. ..." } ] }
```

`field` aparece apenas quando o erro está ligado a um parâmetro ou campo específico. Quando há vários problemas na mesma requisição, **todos** são relatados em uma única resposta.

## Códigos de status

| Código | Significado                                                                            |
| ------ | -------------------------------------------------------------------------------------- |
| 200    | Sucesso (GET, PUT)                                                                     |
| 201    | Recurso criado (POST). O corpo é o envelope `{ data }` do novo recurso                 |
| 204    | Excluído (DELETE), sem corpo                                                           |
| 400    | Parâmetro inválido, JSON malformado ou corpo acima do limite. Veja `errors[].field`    |
| 401    | Chave ausente, malformada, desconhecida, revogada ou desativada. Corpo sempre idêntico |
| 403    | Chave válida, mas sem o escopo/operação necessário                                     |
| 404    | Recurso inexistente (ou pertencente a outra conta), ou rota desconhecida               |
| 422    | Corpo reprovado na validação. **Todos** os problemas em uma única resposta             |
| 429    | Limite de requisições excedido. Consulte os cabeçalhos `RateLimit-*`                   |
| 500    | Erro interno                                                                           |

Detalhamento de cada caso em [Erros](broken://pages/cde018dc25581942f392d3771c446c96e2dba5c7).

## Convenções de escrita (POST / PUT / DELETE)

* Corpos em JSON (`Content-Type: application/json`), exceto o upload de arquivo (`multipart/form-data`). JSON malformado retorna 400 `{ "errors": [{ "detail": "JSON inválido" }] }`; corpos JSON acima de **512 KB** retornam 400.
* **PUT é atualização parcial**: campos ausentes permanecem como estão; um `null` explícito (ou `""` em campos de texto anuláveis) **limpa** o campo. Campos desconhecidos ou somente leitura são ignorados.
* Problemas de validação retornam **422** com todos os campos reprovados em um único array `errors`.

### Semântica de substituição

O valor enviado passa a ser o conjunto completo:

* `tags` do contato
* `company_id` do contato (valor único: substitui os vínculos; `null` desvincula)
* `contact_ids` da negociação
* `follower_ids` da empresa
* `owner_id` da tarefa (substitui todos os responsáveis)

### Semântica de mesclagem

`custom_fields` do contato: apenas as chaves enviadas são alteradas (o valor é gravado ou atualizado; `null`/`""` limpa a chave); as demais permanecem intactas. As chaves correspondem ao **nome** do campo personalizado, sem diferenciar maiúsculas de minúsculas; chaves desconhecidas retornam 422.

{% hint style="warning" %}
Campos personalizados são cadastrados no painel, nunca criados pela API.
{% endhint %}

### Criação automática por nome

Sem diferenciar maiúsculas/minúsculas e ignorando espaços nas extremidades: `tags` do contato, `category` da tarefa e `category` do produto. Se o nome não existir, o registro é criado.

### Reflexo no CRM

Toda escrita relacionada a negociações fica registrada na **linha do tempo** da negociação e aparece **em tempo real** no painel, exatamente como as ações feitas por usuários do dashboard.
