O modelo
Como organização, canal, contato, conversa e mensagem se encaixam.
A API expõe cinco entidades, e elas se encaixam numa cadeia. Entender essa cadeia é entender a API inteira — o resto é detalhe de campo.
A cadeia
Organization ─── a conta. Sua chave já pertence a uma; você nunca a informa.
│
├── Channel ─── por onde se fala: WhatsApp, chat do site, e o que vier.
│ Cada um tem CAPACIDADES próprias.
│
├── User ────── quem atende, dentro daquela organização.
├── Team ────── um grupo de atendentes.
│
└── Contact ─── a pessoa do outro lado.
│
└── Conversation ─── o atendimento com aquela pessoa, por um canal.
│
├── Message ──── o que foi dito, em qualquer direção.
├── Note ─────── anotação interna. NUNCA chega ao contato.
└── Assignment ─ quem é responsável agora.
A conversa é o centro. Ela liga um contato a um canal, e é por isso que enviar mensagem não pede canal: você diz em qual conversa, e o resto está decidido.
Identificadores
Todo objeto tem um id com prefixo, e o prefixo diz o que ele é:
org_ organização msg_ mensagem
chn_ canal att_ anexo
cnt_ contato usr_ atendente
conv_ conversa team_ time
tag_ etiqueta wh_ endpoint de webhook
note_ nota interna evt_ evento
cf_ campo personalizado req_ requisição
O prefixo não é enfeite: passar um conv_… onde se espera um cnt_… é recusado com 422 e o nome do campo — antes de virar consulta. Sem ele, trocar dois argumentos de lugar daria 404, e você procuraria um recurso que nunca existiu.
Os SEUS identificadores
Contatos e conversas aceitam external_id: o identificador que aquela entidade tem no seu sistema. É ele que dispensa uma tabela de-para do seu lado — e o que torna as criações seguras de repetir.
{
"external_id": "customer_8291",
"metadata": { "plano": "enterprise", "erp_id": "29819" }
}
metadata é para o que não justifica um campo próprio. A Amivu guarda e devolve — nenhuma regra do produto olha para lá, e é justamente por isso que você pode colocar o que quiser.
Para dado que precisa aparecer no atendimento e em filtros, use campos personalizados.
Datas e nulos
Toda data é ISO 8601 em UTC: 2026-08-26T21:42:19.238Z. Nunca timestamp numérico, nunca fuso local.
null e ausente são coisas diferentes, e a API os distingue. Um campo null significa “sabemos que não há valor”; status: null numa mensagem quer dizer que aquele canal não reporta recibo — é informação, não falta dela.
Escrevemos sobre operação de atendimento, canais e IA no blog da Amivu.