Use este guia quando o gestor pedir controle de grupos via IA. Cada “terminal” = um endpoint HTTP. Spec: /specs/whatsapp-groups-api.yml.
Contrato global
| Item | Valor |
|---|---|
| Base prod | https://app.siteup.com.br |
| Base path | /api/v1/accounts/{account_id} |
| Auth | Header api_access_token |
| JSON | Content-Type: application/json |
| Telefones | E.164 sem + |
| Capacidade | 1024 |
| Idempotência | Nunca retry cego após 201 de create |
Antes de mutar: confirme account_id, inbox WORKING (available_waha_sessions / inbox_status), e que o gestor autorizou envio real.
Ordem canônica
GET .../whatsapp_groups/available_waha_sessionsPOST .../whatsapp_groups(criar sala)POST .../whatsapp_group_campaignscomgroup_idsPOST .../whatsapp_group_broadcasts(conteúdo)- Opcional:
POST .../broadcasts/{id}/cancelse agendado
Terminais
T1 — Sessões WAHA
GET /whatsapp_groups/available_waha_sessionsGET /whatsapp_groups/inbox_status
Quando: abrir operação; escolher inbox_id.
OK: status WORKING. Bloquear envio se desconectado.
T2 — Grupos
| Método | Path | Função |
|---|---|---|
| GET | /whatsapp_groups |
listar/filtrar |
| POST | /whatsapp_groups |
criar |
| GET | /whatsapp_groups/{id} |
detalhe |
| PUT | /whatsapp_groups/{id} |
atualizar |
| DELETE | /whatsapp_groups/{id} |
excluir/leave |
| GET | /whatsapp_groups/{id}/invite_code |
convite |
| POST | /whatsapp_groups/{id}/sync_members |
sync roster |
POST create exemplo:
{
"whatsapp_group": {
"name": "Turma Maio #1",
"inbox_id": 13,
"max_members": 1024,
"initial_members": ["5551989769026"],
"admin_members": ["5551989769026"]
}
}
Este POST só cria grupo — não aceita chat_kind. Canal só sai pelo
provisionamento em lote (T2b). Não invente um campo chat_kind aqui.
T2b — Provisionar em lote (grupo ou canal)
POST /whatsapp_group_launches/provision
{
"launch_id": "lancamento-x",
"inbox_id": 13,
"count": 3,
"name_prefix": "Turma Maio",
"chat_kind": "channel",
"create_campaign": true,
"campaign_name": "Turma Maio"
}
chat_kind: "group" (padrão) ou "channel". Canal ignora max_members e
admin_members mesmo se enviados (canal não tem esse conceito).
T3 — Membros
| Método | Path | Função |
|---|---|---|
| GET | /whatsapp_groups/{gid}/members |
listar |
| POST | /whatsapp_groups/{gid}/members |
adicionar { "phones": ["55..."] } |
| DELETE | /whatsapp_groups/{gid}/members/{id} |
remover |
| POST | .../members/{id}/promote |
admin |
| POST | .../members/{id}/demote |
rebaixar |
T4 — Campanhas
| Método | Path | Função |
|---|---|---|
| GET | /whatsapp_group_campaigns |
listar |
| POST | /whatsapp_group_campaigns |
criar (group_ids obrigatório) |
| GET | /whatsapp_group_campaigns/{id} |
detalhe |
| GET | /whatsapp_group_campaigns/{id}/health |
saúde |
| GET | /whatsapp_group_campaigns/{id}/broadcasts |
disparos |
| PUT | /whatsapp_group_campaigns/{id} |
update (cuidado 500) |
| DELETE | /whatsapp_group_campaigns/{id} |
excluir |
POST create exemplo:
{
"whatsapp_group_campaign": {
"name": "Campanha Turma Maio",
"status": "active",
"group_ids": [10],
"settings": {
"default_inbox_id": 13,
"admin_inbox_ids": [13],
"max_members": 1024,
"auto_provision": false,
"name_prefix": "Turma Maio"
}
}
}
T5 — Disparos (broadcasts)
| Método | Path | Função |
|---|---|---|
| GET | /whatsapp_group_broadcasts |
listar (bucket=scheduled|completed) |
| POST | /whatsapp_group_broadcasts |
criar envio |
| GET | /whatsapp_group_broadcasts/{id} |
status |
| POST | /whatsapp_group_broadcasts/{id}/cancel |
cancelar |
Tipos (media_type): omitir = texto · image · video · document · audio · poll · contact · event · location.
Texto agora:
{
"whatsapp_group_broadcast": {
"content": "Olá turma!",
"whatsapp_group_campaign_id": 6,
"target_group_ids": [10],
"remove_members_after": false
}
}
Imagem com legenda: content + media_type: image + media_url (URL pública).
Enquete: media_type: poll, content = pergunta, poll_options: ["A","B"].
Localização: media_type: location, extras: { latitude, longitude, title?, address? }.
Agendar: scheduled_at: "2026-08-02T15:00:00-03:00".
Após POST 201: poll GET até completed|failed|cancelled. Não reenvie.
T6 — Atividades
GET /whatsapp_group_activities — auditoria (joined, broadcast, etc.).
T7 — Webhooks de entrada
CRUD em /whatsapp_group_webhooks.
Create body aninhado whatsapp_group_webhook. Retorna webhook_url + token.
T8 — Sequências
CRUD em /whatsapp_group_sequences.
Envie steps (whatsapp_group_sequence_steps_attributes). Create vazio pode falhar.
T9 — Adotar grupo, canal ou comunidade existente
POST /whatsapp_groups/adopt
Quando: o grupo/canal já existe no WhatsApp (criado à mão ou por outra via) e só precisa entrar na conta — sobretudo comunidade, que a API do WhatsApp não deixa criar. O caminho é a pessoa criar a comunidade à mão e adotar o grupo de avisos dela.
{
"whatsapp_group": {
"inbox_id": 13,
"jid": "[email protected]",
"name": "Avisos — Lançamento X",
"max_members": 1024,
"is_community": true
}
}
| Campo | Obrigatório | Nota |
|---|---|---|
inbox_id |
sim | Número precisa participar do grupo/canal e (exceto canal) ser admin |
jid |
sim | @g.us (grupo/comunidade) ou @newsletter (canal) |
name |
não | Vazio usa o nome atual no WhatsApp |
max_members |
não | Ignorado em canal |
is_community |
não | Só true quando jid é o grupo de avisos — a API confere isso no WhatsApp antes de aceitar |
422 específicos deste terminal (além dos genéricos): invalid_jid,
already_adopted, not_visible_to_session, not_admin (não se aplica a
canal), community_must_be_group, community_is_parent_jid (colou o JID da
comunidade, não do grupo de avisos), not_community_group.
Respostas que a IA deve interpretar
| HTTP | Ação |
|---|---|
| 200/201 | sucesso; guarde id |
| 401 | token inválido |
| 403 | usuário não admin |
| 404 | id inexistente nesta conta |
| 422 | payload inválido — leia errors |
| 500 | bug/edge — não loop; reporte path + body sanitizado |
Proibições
- Inventar endpoint ou campo
- Retry após 201 de create (duplica grupo/disparo)
- Expor token/telefone completo em logs públicos
- Disparo em massa sem confirmação do gestor
- Usar produção como playground sem OK
Checklist pré-envio (IA)
- account_id correto
- inbox WORKING
- group_id e campaign_id existem
- mídia URL pública e tipo certo
- gestor confirmou texto/agendamento
-
remove_members_after=falsesalvo se pedido
Evidência mínima ao reportar
method path → http → ids → status final do broadcast