# VD CRM para desenvolvedores > API REST do VD CRM para WhatsApp (API oficial da Meta): contatos, listas, Inbox, modelos, campanhas, fluxos, funis, embed e modelo para parceiros. URL base da API: https://crm.vdgestaobranding.com/api/v1. Autenticação: Authorization: Bearer . Especificação completa: https://developers.vdgestaobranding.com/openapi.json. Documentação completa em texto: https://developers.vdgestaobranding.com/llms-full.txt. ## Guias - [Introdução](https://developers.vdgestaobranding.com/): Documentação da API REST do VD CRM para WhatsApp: autenticação, modo teste, limites, erros, webhooks assinados, embed, modelo para parceiros e referência completa com exemplos. - [Autenticação](https://developers.vdgestaobranding.com/autenticacao): Chaves de API Bearer por operação, escopos, validade e IPs permitidos na API do VD CRM. - [Modo teste](https://developers.vdgestaobranding.com/modo-teste): Chaves vdk_test_ simulam envios, modelos e campanhas sem chamar a Meta nem gerar custo. - [Limites](https://developers.vdgestaobranding.com/limites): Planos com acesso à API, limite de 120 requisições por minuto por chave e cabeçalhos X-RateLimit. - [Erros](https://developers.vdgestaobranding.com/erros): Formato padrão de erros da API do VD CRM e lista de códigos, incluindo erros traduzidos da Meta. - [Paginação](https://developers.vdgestaobranding.com/paginacao): Paginação por cursor com limit e next_cursor nas listagens da API do VD CRM. - [Idempotência](https://developers.vdgestaobranding.com/idempotencia): Use Idempotency-Key para repetir envios e criações com segurança por 24 horas. - [Webhooks](https://developers.vdgestaobranding.com/webhooks): Eventos assinados com HMAC SHA-256, anti-replay, novas tentativas por 24 h e exemplos de verificação. - [Modelo para parceiros](https://developers.vdgestaobranding.com/parceiros): Chaves de conta para parceiros: uma operação por cliente final, chaves, embed, membros e conexão. - [Embed](https://developers.vdgestaobranding.com/embed): Embuta Inbox, campanhas, métricas e conexão do WhatsApp no seu sistema com SSO e embed.js. - [Integre com IA](https://developers.vdgestaobranding.com/ia): Prompts prontos para implementar a integração com ferramentas de IA. ## Referência da API - [Números](https://developers.vdgestaobranding.com/referencia/numeros): 1 endpoints. - [Contatos](https://developers.vdgestaobranding.com/referencia/contatos): 9 endpoints. - [Listas](https://developers.vdgestaobranding.com/referencia/listas): 9 endpoints. - [Inbox](https://developers.vdgestaobranding.com/referencia/inbox): 10 endpoints. - [Modelos](https://developers.vdgestaobranding.com/referencia/modelos): 4 endpoints. - [Mídia](https://developers.vdgestaobranding.com/referencia/midia): 2 endpoints. - [Campanhas](https://developers.vdgestaobranding.com/referencia/campanhas): 9 endpoints. - [Webhooks](https://developers.vdgestaobranding.com/referencia/webhooks): 7 endpoints. - [Embed](https://developers.vdgestaobranding.com/referencia/embed): 1 endpoints. - [Fluxos](https://developers.vdgestaobranding.com/referencia/fluxos): 10 endpoints. - [Pipelines](https://developers.vdgestaobranding.com/referencia/pipelines): 9 endpoints. - [Contas e números](https://developers.vdgestaobranding.com/referencia/contas-e-numeros): 9 endpoints. - [Métricas](https://developers.vdgestaobranding.com/referencia/metricas): 3 endpoints. - [Equipe e operações](https://developers.vdgestaobranding.com/referencia/equipe-e-operacoes): 6 endpoints. - [Respostas rápidas](https://developers.vdgestaobranding.com/referencia/respostas-rapidas): 4 endpoints. - [Tags](https://developers.vdgestaobranding.com/referencia/tags): 4 endpoints. - [Departamentos](https://developers.vdgestaobranding.com/referencia/departamentos): 5 endpoints. - [Conta parceira](https://developers.vdgestaobranding.com/referencia/conta-parceira): 15 endpoints. ## Optional - [OpenAPI 3.1](https://developers.vdgestaobranding.com/openapi.json): Especificação legível por máquina. # Regras gerais - Cada chave de operação age só na sua operação; chaves de conta parceira gerenciam as operações da própria conta. - Chaves de teste nunca chamam a Meta (respostas e webhooks simulados). - Limite de 120 requisições/min por chave (X-RateLimit-*, 429 com Retry-After). Idempotency-Key em POSTs por 24 h. - Erros: { error: { code, message, details, request_id } }. - Webhooks: HMAC SHA-256 de "." em X-VDCRM-Signature (t=..,v1=..), anti-replay de 5 min, novas tentativas após 30s, 2min, 10min, 30min, 1h, 2h, 4h, 8h, 8h. Eventos: message.received, message.status, conversation.assigned, conversation.closed, contact.opted_out, template.status, campaign.started, campaign.completed, campaign.paused, phone_number.quality_changed, phone_number.status_changed, phone_number.connected, connect_session.failed, flow.completed, deal.stage_changed, report.ready. - Códigos de erro: unauthorized (401): Cabeçalho Authorization ausente ou mal formatado. | invalid_key (401): Chave inexistente ou revogada. | key_expired (401): A chave passou da validade. | ip_not_allowed (403): IP fora da lista permitida da chave. | plan_not_allowed (403): O plano da conta não inclui API/webhooks. | key_owner_inactive (403): Quem criou a chave deixou de ser owner/admin. | insufficient_scope (403): A chave não tem o escopo exigido. | operation_read_only (403): Operação suspensa, arquivada ou com teste expirado. | plan_limit (403): Limite do plano atingido (contatos, listas, campanhas…). | not_found (404): Recurso inexistente nesta operação. | validation_error (422): Dados inválidos; veja details.issues. | rule_violation (422): Regra do CRM impediu a ação (opt-out, WABA de outra operação…). | contact_opted_out (422): O contato fez opt-out. | meta_error (502): A Meta recusou; details.meta_code, meta_message e action explicam. | idempotency_mismatch (422): Idempotency-Key reutilizada com outro corpo. | idempotency_in_progress (409): A primeira requisição com esta chave ainda não terminou. | rate_limited (429): Limite por minuto atingido; respeite Retry-After. | flow_invalid (422): Fluxo com problemas; veja details.issues. | shared_flow (409): Fluxo de acesso compartilhado: altere pelo CRM. | invalid_state (409): Ação não permitida no estado atual. | disconnected (409): Número desconectado do CRM; reconecte. | conflict (409): Registro duplicado. | internal_error (500): Erro inesperado; informe o request_id. # Números - **GET https://crm.vdgestaobranding.com/api/v1/phone-numbers** — Listar números Números WhatsApp conectados à operação, com WABA, qualidade, limite e status. Resposta 200: ```json { "data": [ { "id": "a0b1…", "phone_number_id": "1340490742483622", "display_phone_number": "+55 55 92482-1431", "verified_name": "Suporte Comercial", "waba_id": "1095419929937194", "quality_rating": "GREEN", "messaging_limit_tier": "TIER_1K", "status": "CONNECTED" } ] } ``` # Contatos - **GET https://crm.vdgestaobranding.com/api/v1/contacts** — Listar e buscar contatos (escopo `contacts:read`) Parâmetros: `q` (Busca por nome, telefone ou e-mail.); `tag` (Somente contatos com esta tag.); `wa_id` (Telefone exato.); `opted_out` (true/false.); `limit` (Itens por página (1–100, padrão 25).); `cursor` (Valor de next_cursor da página anterior.) Resposta 200: ```json { "data": [ { "id": "c1d2…", "wa_id": "5511999998888", "name": "Maria Silva", "phone": "+5511999998888", "email": "maria@exemplo.com", "tags": [ "vip" ], "custom_fields": { "cidade": "São Paulo" }, "opt_in": true, "opt_in_source": "Formulário do site", "opted_out_at": null, "created_at": "2026-11-03T15:00:00Z" } ], "next_cursor": "WyIyMDI2…" } ``` - **POST https://crm.vdgestaobranding.com/api/v1/contacts** — Criar contato (escopo `contacts:write`) · aceita `Idempotency-Key` Para marcar opt_in é obrigatório informar opt_in_source (origem do consentimento). Corpo de exemplo: ```json { "phone": "5511999998888", "name": "Maria Silva", "email": "maria@exemplo.com", "tags": [ "vip" ], "custom_fields": { "cidade": "São Paulo" }, "opt_in": true, "opt_in_source": "Formulário do site" } ``` Resposta 201: ```json { "id": "c1d2…", "wa_id": "5511999998888", "name": "Maria Silva", "phone": "+5511999998888", "email": "maria@exemplo.com", "tags": [ "vip" ], "custom_fields": { "cidade": "São Paulo" }, "opt_in": true, "opt_in_source": "Formulário do site", "opted_out_at": null, "created_at": "2026-11-03T15:00:00Z" } ``` - **POST https://crm.vdgestaobranding.com/api/v1/contacts/batch** — Criar/atualizar em lote (escopo `contacts:write`) · aceita `Idempotency-Key` Até 1.000 contatos por chamada. Retorna um relatório por linha. Corpo de exemplo: ```json { "upsert": true, "contacts": [ { "phone": "5511999998888", "name": "Maria" }, { "phone": "123" } ] } ``` Resposta 200: ```json { "created": 1, "updated": 0, "errors": 1, "results": [ { "index": 0, "status": "created", "id": "c1d2…" }, { "index": 1, "status": "error", "error": "Telefone inválido…" } ] } ``` - **GET https://crm.vdgestaobranding.com/api/v1/contacts/{id}** — Obter contato (escopo `contacts:read`) Resposta 200: ```json { "id": "c1d2…", "wa_id": "5511999998888", "name": "Maria Silva", "phone": "+5511999998888", "email": "maria@exemplo.com", "tags": [ "vip" ], "custom_fields": { "cidade": "São Paulo" }, "opt_in": true, "opt_in_source": "Formulário do site", "opted_out_at": null, "created_at": "2026-11-03T15:00:00Z" } ``` - **PATCH https://crm.vdgestaobranding.com/api/v1/contacts/{id}** — Atualizar contato (escopo `contacts:write`) custom_fields é mesclado com os campos existentes. Corpo de exemplo: ```json { "name": "Maria S.", "custom_fields": { "plano": "ouro" } } ``` Resposta 200: ```json { "id": "c1d2…", "wa_id": "5511999998888", "name": "Maria Silva", "phone": "+5511999998888", "email": "maria@exemplo.com", "tags": [ "vip" ], "custom_fields": { "cidade": "São Paulo" }, "opt_in": true, "opt_in_source": "Formulário do site", "opted_out_at": null, "created_at": "2026-11-03T15:00:00Z" } ``` - **DELETE https://crm.vdgestaobranding.com/api/v1/contacts/{id}** — Excluir contato (escopo `contacts:write`) - **POST https://crm.vdgestaobranding.com/api/v1/contacts/{id}/tags** — Adicionar/remover tags (escopo `contacts:write`) Corpo de exemplo: ```json { "add": [ "cliente" ], "remove": [ "lead" ] } ``` Resposta 200: ```json { "id": "c1d2…", "wa_id": "5511999998888", "name": "Maria Silva", "phone": "+5511999998888", "email": "maria@exemplo.com", "tags": [ "vip" ], "custom_fields": { "cidade": "São Paulo" }, "opt_in": true, "opt_in_source": "Formulário do site", "opted_out_at": null, "created_at": "2026-11-03T15:00:00Z" } ``` - **POST https://crm.vdgestaobranding.com/api/v1/contacts/{id}/opt-out** — Registrar opt-out (escopo `contacts:write`) O contato deixa de receber campanhas e modelos. Corpo de exemplo: ```json { "source": "Pediu pelo SAC" } ``` Resposta 200: ```json { "id": "c1d2…", "wa_id": "5511999998888", "name": "Maria Silva", "phone": "+5511999998888", "email": "maria@exemplo.com", "tags": [ "vip" ], "custom_fields": { "cidade": "São Paulo" }, "opt_in": false, "opt_in_source": "Formulário do site", "opted_out_at": "2026-11-03T15:10:00Z", "created_at": "2026-11-03T15:00:00Z" } ``` - **POST https://crm.vdgestaobranding.com/api/v1/contacts/{id}/opt-in** — Registrar opt-in (escopo `contacts:write`) Corpo de exemplo: ```json { "source": "Checkbox no checkout" } ``` Resposta 200: ```json { "id": "c1d2…", "wa_id": "5511999998888", "name": "Maria Silva", "phone": "+5511999998888", "email": "maria@exemplo.com", "tags": [ "vip" ], "custom_fields": { "cidade": "São Paulo" }, "opt_in": true, "opt_in_source": "Formulário do site", "opted_out_at": null, "created_at": "2026-11-03T15:00:00Z" } ``` # Listas - **GET https://crm.vdgestaobranding.com/api/v1/lists** — Listar listas (escopo `contacts:read`) Parâmetros: `limit` (Itens por página (1–100, padrão 25).); `cursor` (Valor de next_cursor da página anterior.) Resposta 200: ```json { "data": [ { "id": "l1…", "name": "Clientes VIP", "description": null, "created_at": "2026-11-03T15:00:00Z" } ], "next_cursor": null } ``` - **POST https://crm.vdgestaobranding.com/api/v1/lists** — Criar lista (escopo `lists:write`) · aceita `Idempotency-Key` Corpo de exemplo: ```json { "name": "Clientes VIP" } ``` Resposta 201: ```json { "id": "l1…", "name": "Clientes VIP" } ``` - **GET https://crm.vdgestaobranding.com/api/v1/lists/{id}** — Obter lista (escopo `contacts:read`) - **PATCH https://crm.vdgestaobranding.com/api/v1/lists/{id}** — Renomear lista (escopo `lists:write`) Corpo de exemplo: ```json { "name": "VIP 2026" } ``` - **DELETE https://crm.vdgestaobranding.com/api/v1/lists/{id}** — Excluir lista (escopo `lists:write`) Os contatos são preservados. - **POST https://crm.vdgestaobranding.com/api/v1/lists/{id}/contacts** — Adicionar contatos (escopo `lists:write`) Corpo de exemplo: ```json { "contact_ids": [ "c1d2…" ] } ``` Resposta 200: ```json { "affected": 1 } ``` - **DELETE https://crm.vdgestaobranding.com/api/v1/lists/{id}/contacts** — Remover contatos (escopo `lists:write`) Corpo de exemplo: ```json { "contact_ids": [ "c1d2…" ] } ``` Resposta 200: ```json { "affected": 1 } ``` - **POST https://crm.vdgestaobranding.com/api/v1/lists/{id}/imports** — Importar CSV/XLSX (escopo `lists:write`) · aceita `Idempotency-Key` Envie JSON com file_url (https) ou multipart com o campo file. Colunas reconhecidas: telefone/phone, nome/name, email, tags; as demais viram campos personalizados. source (origem do consentimento) é obrigatório. Corpo de exemplo: ```json { "file_url": "https://exemplo.com/contatos.csv", "source": "Cadastro na loja física" } ``` Resposta 202: ```json { "id": "i1…", "status": "completed", "total": 500, "imported": 480, "updated": 15, "invalid": 5 } ``` - **GET https://crm.vdgestaobranding.com/api/v1/lists/{id}/imports/{importId}** — Status da importação (escopo `contacts:read`) Resposta 200: ```json { "id": "i1…", "status": "processing", "imported": 120 } ``` # Inbox - **GET https://crm.vdgestaobranding.com/api/v1/conversations** — Listar conversas (escopo `inbox:read`) Parâmetros: `phone_number_ref` (ID do número no CRM.); `status` (open | closed.); `assignee_id` (Atendente.); `tag` (Tag do contato.); `unread` (true para não lidas.); `since` (ISO 8601 (última mensagem a partir de).); `until` (ISO 8601.); `limit` (Itens por página (1–100, padrão 25).); `cursor` (Valor de next_cursor da página anterior.) Resposta 200: ```json { "data": [ { "id": "9f1e…", "contact_id": "c1d2…", "phone_number_ref": "a0b1…", "status": "aberta", "assignee_id": null, "unread_count": 2, "last_message_at": "2026-11-03T15:02:00Z", "window_open": true } ], "next_cursor": null } ``` - **GET https://crm.vdgestaobranding.com/api/v1/conversations/{id}** — Obter conversa (escopo `inbox:read`) Resposta 200: ```json { "id": "9f1e…", "contact_id": "c1d2…", "phone_number_ref": "a0b1…", "status": "aberta", "assignee_id": null, "unread_count": 2, "last_message_at": "2026-11-03T15:02:00Z", "window_open": true } ``` - **GET https://crm.vdgestaobranding.com/api/v1/conversations/{id}/messages** — Listar mensagens (escopo `inbox:read`) Parâmetros: `limit` (Itens por página (1–100, padrão 25).); `cursor` (Valor de next_cursor da página anterior.) Resposta 200: ```json { "data": [ { "id": "m1…", "direction": "inbound", "type": "text", "content": { "text": "Olá!" }, "status": "received", "created_at": "2026-11-03T15:02:00Z" } ], "next_cursor": null } ``` - **POST https://crm.vdgestaobranding.com/api/v1/conversations/{id}/messages** — Enviar mensagem na conversa (escopo `inbox:write`) · aceita `Idempotency-Key` type: text | media | template. Texto e mídia só com a janela de 24h aberta; fora dela use um modelo aprovado. Corpo de exemplo: ```json { "type": "text", "text": "Olá, Maria! Seu pedido foi enviado." } ``` Resposta 201: ```json { "id": "m2…", "wamid": "wamid.HBg…", "status": "sent" } ``` - **POST https://crm.vdgestaobranding.com/api/v1/messages** — Enviar mensagem para um telefone (escopo `inbox:write`) · aceita `Idempotency-Key` Cria o contato e a conversa se necessário. Para iniciar conversa use um modelo aprovado. Corpo de exemplo: ```json { "phone_number_ref": "a0b1…", "to": "5511999998888", "type": "template", "name": "pedido_enviado", "language": "pt_BR", "variables": [ "Maria", "#1234" ] } ``` Resposta 201: ```json { "id": "m3…", "wamid": "wamid.HBg…", "status": "sent" } ``` - **POST https://crm.vdgestaobranding.com/api/v1/conversations/{id}/read** — Marcar como lida (escopo `inbox:write`) Resposta 200: ```json { "id": "9f1e…", "contact_id": "c1d2…", "phone_number_ref": "a0b1…", "status": "aberta", "assignee_id": null, "unread_count": 2, "last_message_at": "2026-11-03T15:02:00Z", "window_open": true } ``` - **POST https://crm.vdgestaobranding.com/api/v1/conversations/{id}/close** — Finalizar (escopo `inbox:write`) Resposta 200: ```json { "id": "9f1e…", "contact_id": "c1d2…", "phone_number_ref": "a0b1…", "status": "aberta", "assignee_id": null, "unread_count": 2, "last_message_at": "2026-11-03T15:02:00Z", "window_open": true } ``` - **POST https://crm.vdgestaobranding.com/api/v1/conversations/{id}/reopen** — Reabrir (escopo `inbox:write`) Resposta 200: ```json { "id": "9f1e…", "contact_id": "c1d2…", "phone_number_ref": "a0b1…", "status": "aberta", "assignee_id": null, "unread_count": 2, "last_message_at": "2026-11-03T15:02:00Z", "window_open": true } ``` - **POST https://crm.vdgestaobranding.com/api/v1/conversations/{id}/archive** — Arquivar (escopo `inbox:write`) Resposta 200: ```json { "id": "9f1e…", "contact_id": "c1d2…", "phone_number_ref": "a0b1…", "status": "aberta", "assignee_id": null, "unread_count": 2, "last_message_at": "2026-11-03T15:02:00Z", "window_open": true } ``` - **POST https://crm.vdgestaobranding.com/api/v1/conversations/{id}/assign** — Atribuir atendente (escopo `inbox:write`) Corpo de exemplo: ```json { "assignee_id": "u1…" } ``` Resposta 200: ```json { "id": "9f1e…", "contact_id": "c1d2…", "phone_number_ref": "a0b1…", "status": "aberta", "assignee_id": null, "unread_count": 2, "last_message_at": "2026-11-03T15:02:00Z", "window_open": true } ``` # Modelos - **GET https://crm.vdgestaobranding.com/api/v1/templates** — Listar modelos (escopo `templates:read`) Parâmetros: `waba_id` (WABA.); `status` (APPROVED, PENDING, REJECTED…); `category` (MARKETING, UTILITY, AUTHENTICATION.); `language` (pt_BR…); `name` (Nome exato.); `limit` (1–200.); `cursor` (Cursor.) Resposta 200: ```json { "data": [ { "id": "t1…", "name": "pedido_enviado", "language": "pt_BR", "category": "UTILITY", "status": "APPROVED" } ], "next_cursor": null } ``` - **GET https://crm.vdgestaobranding.com/api/v1/templates/{id}** — Obter modelo e status (escopo `templates:read`) - **POST https://crm.vdgestaobranding.com/api/v1/templates** — Criar modelo (escopo `templates:write`) · aceita `Idempotency-Key` template segue o mesmo formato do editor do CRM: kind (standard | carousel | lto | auth), category, languages, headerType, body, examples, footer, buttons, cards, lto, auth. Mídia de exemplo por header_media_url / header_media_id e card_media. Corpo de exemplo: ```json { "waba_id": "1095419929937194", "header_media_url": "https://exemplo.com/banner.jpg", "template": { "name": "promo_novembro", "category": "MARKETING", "languages": [ "pt_BR" ], "kind": "standard", "headerType": "IMAGE", "body": "Olá {{1}}, aproveite {{2}}% de desconto!", "examples": { "1": "Maria", "2": "20" }, "footer": "VD CRM", "buttons": [ { "id": "b1", "type": "URL", "text": "Ver ofertas", "url": "https://loja.com/{{1}}", "urlExample": "https://loja.com/promo" } ] } } ``` Resposta 201: ```json { "results": [ { "language": "pt_BR", "ok": true, "status": "PENDING", "meta_template_id": "1234567890" } ] } ``` - **DELETE https://crm.vdgestaobranding.com/api/v1/templates/{id}** — Excluir modelo (escopo `templates:write`) Resposta 200: ```json { "deleted": true } ``` # Mídia - **POST https://crm.vdgestaobranding.com/api/v1/media** — Enviar mídia (escopo `inbox:write`) · aceita `Idempotency-Key` multipart com o campo file (até 100 MB) ou JSON com url https. Corpo de exemplo: ```json { "url": "https://exemplo.com/catalogo.pdf" } ``` Resposta 201: ```json { "id": "md1…", "kind": "document", "mime": "application/pdf", "size_bytes": 120334 } ``` - **GET https://crm.vdgestaobranding.com/api/v1/media/{id}** — Obter mídia (escopo `inbox:read`) Inclui um link temporário (1 h). Resposta 200: ```json { "id": "md1…", "url": "https://…", "url_expires_in": 3600 } ``` # Campanhas - **GET https://crm.vdgestaobranding.com/api/v1/campaigns** — Listar campanhas (escopo `campaigns:read`) Parâmetros: `status` (rascunho, agendada, enviando, pausada, concluida, cancelada.); `limit` (Itens por página (1–100, padrão 25).); `cursor` (Valor de next_cursor da página anterior.) Resposta 200: ```json { "data": [ { "id": "7c3a…", "name": "Black Friday", "status": "rascunho", "waba_id": "1095419929937194", "totals": { "total": 1200, "sent": 0, "delivered": 0, "read": 0, "replied": 0, "failed": 0, "skipped": 0 } } ], "next_cursor": null } ``` - **POST https://crm.vdgestaobranding.com/api/v1/campaigns** — Criar campanha (escopo `campaigns:write`) · aceita `Idempotency-Key` Uma campanha usa uma única WABA da operação e números dessa mesma WABA. start=false cria como rascunho; use /dispatch para disparar. Suporta A/B (variants, soma 100%), agendamento (scheduled_at) e janela de envio (send_window). Corpo de exemplo: ```json { "name": "Black Friday", "waba_id": "1095419929937194", "phone_number_refs": [ "a0b1…" ], "template": { "name": "promo_novembro", "language": "pt_BR", "variables": [ { "source": "field", "field": "nome", "fallback": "cliente" }, { "source": "text", "value": "20" } ] }, "audience": { "include_lists": [ "l1…" ], "include_tags": [], "exclude_lists": [], "exclude_tags": [ "nao_enviar" ] }, "scheduled_at": null, "rate_per_second": 10, "send_window": { "start": 9, "end": 20, "days": [ 1, 2, 3, 4, 5 ] }, "start": false } ``` Resposta 201: ```json { "id": "7c3a…", "name": "Black Friday", "status": "rascunho", "waba_id": "1095419929937194", "totals": { "total": 1200, "sent": 0, "delivered": 0, "read": 0, "replied": 0, "failed": 0, "skipped": 0 }, "eligible_recipients": 1200 } ``` - **GET https://crm.vdgestaobranding.com/api/v1/campaigns/{id}** — Obter campanha (escopo `campaigns:read`) Resposta 200: ```json { "id": "7c3a…", "name": "Black Friday", "status": "rascunho", "waba_id": "1095419929937194", "totals": { "total": 1200, "sent": 0, "delivered": 0, "read": 0, "replied": 0, "failed": 0, "skipped": 0 } } ``` - **POST https://crm.vdgestaobranding.com/api/v1/campaigns/{id}/dispatch** — Disparar agora (escopo `campaigns:write`) Resposta 200: ```json { "id": "7c3a…", "name": "Black Friday", "status": "rascunho", "waba_id": "1095419929937194", "totals": { "total": 1200, "sent": 0, "delivered": 0, "read": 0, "replied": 0, "failed": 0, "skipped": 0 } } ``` - **POST https://crm.vdgestaobranding.com/api/v1/campaigns/{id}/pause** — Pausar (escopo `campaigns:write`) Resposta 200: ```json { "id": "7c3a…", "name": "Black Friday", "status": "rascunho", "waba_id": "1095419929937194", "totals": { "total": 1200, "sent": 0, "delivered": 0, "read": 0, "replied": 0, "failed": 0, "skipped": 0 } } ``` - **POST https://crm.vdgestaobranding.com/api/v1/campaigns/{id}/resume** — Retomar (escopo `campaigns:write`) Resposta 200: ```json { "id": "7c3a…", "name": "Black Friday", "status": "rascunho", "waba_id": "1095419929937194", "totals": { "total": 1200, "sent": 0, "delivered": 0, "read": 0, "replied": 0, "failed": 0, "skipped": 0 } } ``` - **POST https://crm.vdgestaobranding.com/api/v1/campaigns/{id}/cancel** — Cancelar (escopo `campaigns:write`) Resposta 200: ```json { "id": "7c3a…", "name": "Black Friday", "status": "rascunho", "waba_id": "1095419929937194", "totals": { "total": 1200, "sent": 0, "delivered": 0, "read": 0, "replied": 0, "failed": 0, "skipped": 0 } } ``` - **GET https://crm.vdgestaobranding.com/api/v1/campaigns/{id}/results** — Resultados (escopo `campaigns:read`) Funil, erros por motivo (com explicação) e contagem por variante. Resposta 200: ```json { "funnel": { "total": 1200, "sent": 1180, "delivered": 1150, "read": 900, "replied": 120, "failed": 20, "skipped": 0 }, "errors": [ { "meta_code": "131049", "count": 12, "title": "Meta limitou mensagens de marketing", "explanation": "…", "action": "…" } ], "variants": [ { "variant": 0, "template_name": "promo_novembro", "counts": { "lido": 900 } } ] } ``` - **GET https://crm.vdgestaobranding.com/api/v1/campaigns/{id}/recipients** — Destinatários (escopo `campaigns:read`) Parâmetros: `status` (pendente, enviado, entregue, lido, falhou…); `limit` (1–500.); `cursor` (Cursor.) # Webhooks - **GET https://crm.vdgestaobranding.com/api/v1/webhooks** — Listar webhooks (escopo `webhooks:manage`) - **POST https://crm.vdgestaobranding.com/api/v1/webhooks** — Cadastrar webhook (escopo `webhooks:manage`) · aceita `Idempotency-Key` O segredo de assinatura (secret) é exibido só nesta resposta. Corpo de exemplo: ```json { "url": "https://minha-api.com/vdcrm", "events": [ "message.received", "message.status" ] } ``` Resposta 201: ```json { "id": "w1…", "url": "https://minha-api.com/vdcrm", "events": [ "message.received", "message.status" ], "secret": "whsec_…" } ``` - **PATCH https://crm.vdgestaobranding.com/api/v1/webhooks/{id}** — Alterar webhook (escopo `webhooks:manage`) Corpo de exemplo: ```json { "active": false } ``` - **DELETE https://crm.vdgestaobranding.com/api/v1/webhooks/{id}** — Excluir webhook (escopo `webhooks:manage`) - **POST https://crm.vdgestaobranding.com/api/v1/webhooks/{id}/test** — Enviar evento de teste (escopo `webhooks:manage`) Resposta 200: ```json { "delivery_id": "d1…", "delivered": true, "status_code": 200 } ``` - **GET https://crm.vdgestaobranding.com/api/v1/webhooks/{id}/deliveries** — Registro de entregas (escopo `webhooks:manage`) Parâmetros: `limit` (Itens por página (1–100, padrão 25).); `cursor` (Valor de next_cursor da página anterior.) - **POST https://crm.vdgestaobranding.com/api/v1/webhook-deliveries/{id}/redeliver** — Reenviar entrega (escopo `webhooks:manage`) # Embed - **POST https://crm.vdgestaobranding.com/api/v1/embed/sessions** — Criar sessão de embed (SSO) (escopo `embed:create`) · aceita `Idempotency-Key` Chame do seu servidor. Devolve um token de troca de uso único (5 min) e a URL do embed. A sessão dura 30 min, é renovável até 12 h e só enxerga os números e módulos informados. Exige ao menos um domínio permitido em Configurações → Marca e embed. Corpo de exemplo: ```json { "user": { "external_id": "u-123", "name": "Ana", "email": "ana@cliente.com" }, "phone_number_refs": [ "a0b1…" ], "modules": [ "inbox", "metrics" ], "permissions": [ "inbox:read", "inbox:reply", "metrics:read" ] } ``` Resposta 201: ```json { "session_id": "es1…", "embed_user_id": "eu1…", "token": "vdex_…", "token_expires_at": "2026-11-03T15:05:00Z", "url": "https://crm.vdgestaobranding.com/embed?t=vdex_…", "modules": [ "inbox", "metrics" ], "test": false } ``` # Fluxos - **GET https://crm.vdgestaobranding.com/api/v1/flows** — Listar fluxos (escopo `flows:read`) Parâmetros: `status` (rascunho | ativo | inativo.); `limit` (Itens por página (1–100, padrão 25).); `cursor` (Valor de next_cursor da página anterior.) Resposta 200: ```json { "data": [ { "id": "f1…", "name": "Boas-vindas", "status": "ativo", "trigger_kind": "keyword", "priority": 0, "runs_count": 42, "published_version_id": "v1…", "shared": false, "created_at": "2026-11-03T15:00:00Z" } ], "next_cursor": null } ``` - **POST https://crm.vdgestaobranding.com/api/v1/flows** — Criar fluxo (escopo `flows:write`) · aceita `Idempotency-Key` draft é o JSON do fluxo (nodes/edges), o mesmo do editor do CRM. Corpo de exemplo: ```json { "name": "Boas-vindas", "draft": { "nodes": [], "edges": [] } } ``` Resposta 201: ```json { "id": "f1…", "name": "Boas-vindas", "status": "ativo", "trigger_kind": "keyword", "priority": 0, "runs_count": 42, "published_version_id": "v1…", "shared": false, "created_at": "2026-11-03T15:00:00Z" } ``` - **GET https://crm.vdgestaobranding.com/api/v1/flows/{id}** — Obter fluxo (JSON) (escopo `flows:read`) Inclui o rascunho (draft) e a versão publicada (published.graph). Resposta 200: ```json { "id": "f1…", "name": "Boas-vindas", "status": "ativo", "trigger_kind": "keyword", "priority": 0, "runs_count": 42, "published_version_id": "v1…", "shared": false, "created_at": "2026-11-03T15:00:00Z", "draft": { "nodes": [], "edges": [] }, "published": { "id": "v1…", "version": 3, "graph": { "nodes": [], "edges": [] } } } ``` - **PATCH https://crm.vdgestaobranding.com/api/v1/flows/{id}** — Atualizar fluxo (escopo `flows:write`) Altera o rascunho; publique para que passe a rodar. Corpo de exemplo: ```json { "name": "Boas-vindas v2" } ``` - **POST https://crm.vdgestaobranding.com/api/v1/flows/{id}/publish** — Publicar e ativar (escopo `flows:write`) Valida o fluxo (422 flow_invalid com details.issues) e respeita os limites do plano. Resposta 200: ```json { "id": "f1…", "name": "Boas-vindas", "status": "ativo", "trigger_kind": "keyword", "priority": 0, "runs_count": 42, "published_version_id": "v1…", "shared": false, "created_at": "2026-11-03T15:00:00Z", "version": 4 } ``` - **POST https://crm.vdgestaobranding.com/api/v1/flows/{id}/unpublish** — Despublicar (escopo `flows:write`) Desativa o fluxo e encerra as execuções em andamento. - **DELETE https://crm.vdgestaobranding.com/api/v1/flows/{id}** — Excluir fluxo (escopo `flows:write`) - **POST https://crm.vdgestaobranding.com/api/v1/flows/{id}/start** — Iniciar fluxo para um contato (escopo `flows:write`) · aceita `Idempotency-Key` Com a janela de 24h fechada, o primeiro envio do fluxo precisa ser um modelo aprovado. Contatos com opt-out são recusados. Chaves de teste não enviam nada. Corpo de exemplo: ```json { "contact_id": "c1d2…", "variables": { "pedido": "1234" } } ``` Resposta 202: ```json { "started": true, "run": { "id": "r1…", "state": "aguardando" } } ``` - **GET https://crm.vdgestaobranding.com/api/v1/flows/{id}/runs** — Listar execuções (escopo `flows:read`) Parâmetros: `limit` (1–100.); `before` (ISO 8601; use next_before para paginar.) Resposta 200: ```json { "data": [ { "id": "r1…", "flow_id": "f1…", "contact_id": "c1d2…", "state": "concluido", "outcome": "concluido", "current_node": "end", "started_at": "2026-11-03T15:00:00Z", "finished_at": "2026-11-03T15:03:00Z" } ], "next_before": null } ``` - **GET https://crm.vdgestaobranding.com/api/v1/flow-runs/{id}** — Execução e caminho percorrido (escopo `flows:read`) Resposta 200: ```json { "id": "r1…", "flow_id": "f1…", "contact_id": "c1d2…", "state": "concluido", "outcome": "concluido", "current_node": "end", "started_at": "2026-11-03T15:00:00Z", "finished_at": "2026-11-03T15:03:00Z", "variables": { "pedido": "1234" }, "path": [ { "node_id": "n1", "node_type": "message", "action": "sent", "created_at": "2026-11-03T15:00:01Z" } ] } ``` # Pipelines - **GET https://crm.vdgestaobranding.com/api/v1/pipelines** — Listar funis e etapas (escopo `pipelines:read`) Resposta 200: ```json { "data": [ { "id": "p1…", "name": "Vendas", "order": 0, "stages": [ { "id": "s1…", "name": "Novo", "type": "open" }, { "id": "s9…", "name": "Ganho", "type": "won" } ] } ] } ``` - **GET https://crm.vdgestaobranding.com/api/v1/deals** — Listar negócios (escopo `pipelines:read`) Parâmetros: `pipeline_id` (Funil.); `stage_id` (Etapa.); `contact_id` (Contato.); `status` (aberto | ganho | perdido.); `limit` (Itens por página (1–100, padrão 25).); `cursor` (Valor de next_cursor da página anterior.) Resposta 200: ```json { "data": [ { "id": "d1…", "pipeline_id": "p1…", "stage_id": "s1…", "contact_id": "c1d2…", "title": "Plano anual", "value": 4800, "owner_id": null, "expected_close": "2026-12-01", "tags": [], "notes": null, "status": "aberto", "created_at": "2026-11-03T15:00:00Z" } ], "next_cursor": null } ``` - **POST https://crm.vdgestaobranding.com/api/v1/deals** — Criar negócio (escopo `pipelines:write`) · aceita `Idempotency-Key` Sem stage_id, entra na primeira etapa do funil. contact_id vincula ao contato. Corpo de exemplo: ```json { "pipeline_id": "p1…", "title": "Plano anual", "value": 4800, "contact_id": "c1d2…" } ``` Resposta 201: ```json { "id": "d1…", "pipeline_id": "p1…", "stage_id": "s1…", "contact_id": "c1d2…", "title": "Plano anual", "value": 4800, "owner_id": null, "expected_close": "2026-12-01", "tags": [], "notes": null, "status": "aberto", "created_at": "2026-11-03T15:00:00Z" } ``` - **GET https://crm.vdgestaobranding.com/api/v1/deals/{id}** — Obter negócio (escopo `pipelines:read`) Resposta 200: ```json { "id": "d1…", "pipeline_id": "p1…", "stage_id": "s1…", "contact_id": "c1d2…", "title": "Plano anual", "value": 4800, "owner_id": null, "expected_close": "2026-12-01", "tags": [], "notes": null, "status": "aberto", "created_at": "2026-11-03T15:00:00Z" } ``` - **PATCH https://crm.vdgestaobranding.com/api/v1/deals/{id}** — Atualizar / vincular contato (escopo `pipelines:write`) Corpo de exemplo: ```json { "value": 5200, "contact_id": "c1d2…" } ``` Resposta 200: ```json { "id": "d1…", "pipeline_id": "p1…", "stage_id": "s1…", "contact_id": "c1d2…", "title": "Plano anual", "value": 4800, "owner_id": null, "expected_close": "2026-12-01", "tags": [], "notes": null, "status": "aberto", "created_at": "2026-11-03T15:00:00Z" } ``` - **POST https://crm.vdgestaobranding.com/api/v1/deals/{id}/move** — Mover de etapa (escopo `pipelines:write`) Dispara o webhook deal.stage_changed. Corpo de exemplo: ```json { "stage_id": "s2…" } ``` Resposta 200: ```json { "id": "d1…", "pipeline_id": "p1…", "stage_id": "s1…", "contact_id": "c1d2…", "title": "Plano anual", "value": 4800, "owner_id": null, "expected_close": "2026-12-01", "tags": [], "notes": null, "status": "aberto", "created_at": "2026-11-03T15:00:00Z" } ``` - **POST https://crm.vdgestaobranding.com/api/v1/deals/{id}/win** — Marcar como ganho (escopo `pipelines:write`) Resposta 200: ```json { "id": "d1…", "pipeline_id": "p1…", "stage_id": "s1…", "contact_id": "c1d2…", "title": "Plano anual", "value": 4800, "owner_id": null, "expected_close": "2026-12-01", "tags": [], "notes": null, "status": "ganho", "created_at": "2026-11-03T15:00:00Z" } ``` - **POST https://crm.vdgestaobranding.com/api/v1/deals/{id}/lose** — Marcar como perdido (escopo `pipelines:write`) Resposta 200: ```json { "id": "d1…", "pipeline_id": "p1…", "stage_id": "s1…", "contact_id": "c1d2…", "title": "Plano anual", "value": 4800, "owner_id": null, "expected_close": "2026-12-01", "tags": [], "notes": null, "status": "perdido", "created_at": "2026-11-03T15:00:00Z" } ``` - **DELETE https://crm.vdgestaobranding.com/api/v1/deals/{id}** — Excluir negócio (escopo `pipelines:write`) # Contas e números - **GET https://crm.vdgestaobranding.com/api/v1/accounts** — BMs, WABAs e números (escopo `accounts:read`) Árvore BM → WABA → número com qualidade, limite, uso nas últimas 24h, registro e verificação. Resposta 200: ```json { "data": [ { "id": "b1…", "business_id": "4511…", "name": "Minha empresa", "verification_status": "verified", "wabas": [ { "waba_id": "1095419929937194", "name": "Atendimento", "phone_numbers": [ { "id": "a0b1…", "phone_number_id": "1340490742483622", "display_phone_number": "+55 55 92482-1431", "verified_name": "Suporte Comercial", "quality_rating": "GREEN", "messaging_limit_tier": "TIER_1K", "status": "CONNECTED", "registration": { "registered": true, "requires_registration": false, "coexistence": false }, "verification": { "code_verification_status": "VERIFIED" }, "usage_24h": { "unique_contacts_24h": 120, "max_daily_7d": 380 } } ] } ] } ] } ``` - **GET https://crm.vdgestaobranding.com/api/v1/phone-numbers/{id}** — Detalhes do número (escopo `accounts:read`) Resposta 200: ```json { "id": "a0b1…", "phone_number_id": "1340490742483622", "display_phone_number": "+55 55 92482-1431", "verified_name": "Suporte Comercial", "quality_rating": "GREEN", "messaging_limit_tier": "TIER_1K", "status": "CONNECTED", "registration": { "registered": true, "requires_registration": false, "coexistence": false }, "verification": { "code_verification_status": "VERIFIED" }, "usage_24h": { "unique_contacts_24h": 120, "max_daily_7d": 380 } } ``` - **POST https://crm.vdgestaobranding.com/api/v1/phone-numbers/{id}/sync** — Sincronizar com a Meta (escopo `accounts:write`) Resposta 200: ```json { "synced": true, "phone": { "id": "a0b1…", "phone_number_id": "1340490742483622", "display_phone_number": "+55 55 92482-1431", "verified_name": "Suporte Comercial", "quality_rating": "GREEN", "messaging_limit_tier": "TIER_1K", "status": "CONNECTED", "registration": { "registered": true, "requires_registration": false, "coexistence": false }, "verification": { "code_verification_status": "VERIFIED" }, "usage_24h": { "unique_contacts_24h": 120, "max_daily_7d": 380 } } } ``` - **GET https://crm.vdgestaobranding.com/api/v1/phone-numbers/{id}/profile** — Obter foto e nome do perfil (escopo `accounts:read`) Resposta 200: ```json { "profile_picture_url": "https://…", "verified_name": "Suporte Comercial", "name_status": "APPROVED" } ``` - **POST https://crm.vdgestaobranding.com/api/v1/phone-numbers/{id}/profile/photo** — Atualizar foto do perfil (escopo `accounts:write`) JPG ou PNG (até 5 MB, mínimo 192×192). Envie file_url (https) ou media_id de POST /media. Corpo de exemplo: ```json { "file_url": "https://exemplo.com/logo.jpg" } ``` Resposta 200: ```json { "updated": true, "profile_picture_url": "https://…" } ``` - **GET https://crm.vdgestaobranding.com/api/v1/phone-numbers/{id}/display-name** — Ler o nome (escopo `accounts:read`) Resposta 200: ```json { "verified_name": "Suporte Comercial", "name_status": "APPROVED", "request": null, "notice": "A troca de nome é analisada pela Meta…" } ``` - **POST https://crm.vdgestaobranding.com/api/v1/phone-numbers/{id}/display-name** — Solicitar troca de nome (escopo `accounts:write`) A Meta analisa o novo nome (normalmente de 1 a 3 dias). O nome atual continua até a aprovação. Corpo de exemplo: ```json { "name": "Loja Exemplo" } ``` Resposta 202: ```json { "requested": true, "status": "PENDING_REVIEW", "notice": "A troca de nome é analisada pela Meta…" } ``` - **POST https://crm.vdgestaobranding.com/api/v1/connect-sessions** — Criar link de conexão (escopo `accounts:write`) · aceita `Idempotency-Key` Gera um link de uso único (30 min) para o cliente abrir o Embedded Signup da Meta numa página do VD CRM. Ao concluir, é enviado phone_number.connected; em caso de erro, connect_session.failed com a etapa. Com chave de teste, a página simula a conexão. mode: "new" (número novo, padrão) ou "coexistence" (conectar um número que já está no app WhatsApp Business; sem PIN/registro, até 6 meses de histórico, o app continua funcionando). Passo a passo para o cliente no modo coexistence: (1) na janela da Meta, digite no campo de telefone o número que está no app WhatsApp Business; (2) no app chegará uma mensagem da conta oficial do Facebook Business: toque em "Conectar" → "Conectar-se à Plataforma do WhatsApp Business" → confirme o compartilhamento do histórico; (3) copie o código de verificação e cole na janela da Meta; (4) conclua a janela; (5) mantenha o app aberto durante a sincronização. Se a janela avisar que o número será removido do app, pare e fale com o suporte. Corpo de exemplo: ```json { "redirect_url": "https://meu-sistema.com/conectado", "mode": "coexistence" } ``` Resposta 201: ```json { "session_id": "cs1…", "status": "pending", "url": "https://crm.vdgestaobranding.com/conectar/…", "expires_at": "2026-11-03T15:30:00Z" } ``` - **GET https://crm.vdgestaobranding.com/api/v1/connect-sessions/{id}** — Status da conexão (escopo `accounts:read`) status: pending | processing | completed | failed | expired. Resposta 200: ```json { "session_id": "cs1…", "status": "completed", "step": "done", "waba_id": "1095…", "phone_number_id": "1340…" } ``` # Métricas - **GET https://crm.vdgestaobranding.com/api/v1/metrics** — Indicadores do período (escopo `metrics:read`) Disparos (campanhas) e atendimento separados, os mesmos números do painel. Padrão: últimos 30 dias. Parâmetros: `from` (ISO 8601.); `to` (ISO 8601.); `phone_number_ref` (Filtrar por número.) Resposta 200: ```json { "period": { "from": "2026-10-01T00:00:00Z", "to": "2026-11-01T00:00:00Z" }, "metrics": { "campaigns": { "sent": 1200, "delivered": 1150 }, "attendance": { "conversations": 300 } } } ``` - **POST https://crm.vdgestaobranding.com/api/v1/reports** — Gerar relatório (escopo `metrics:read`) · aceita `Idempotency-Key` Assíncrono. Ao ficar pronto, envia report.ready; consulte GET /reports/{id} para a URL de download (válida por 1 h). Corpo de exemplo: ```json { "format": "xlsx", "from": "2026-10-01T00:00:00Z", "to": "2026-11-01T00:00:00Z" } ``` Resposta 202: ```json { "id": "rp1…", "status": "queued" } ``` - **GET https://crm.vdgestaobranding.com/api/v1/reports/{id}** — Status / download do relatório (escopo `metrics:read`) Resposta 200: ```json { "id": "rp1…", "status": "ready", "format": "xlsx", "download_url": "https://…" } ``` # Equipe e operações - **GET https://crm.vdgestaobranding.com/api/v1/operations** — Listar operações da conta (escopo `team:manage`) Resposta 200: ```json { "data": [ { "id": "o1…", "name": "Loja Centro", "slug": "loja-centro", "archived": false, "current": true } ], "quota": { "plan": "Profissional", "cap": 3, "used": 1, "allowed": true } } ``` - **POST https://crm.vdgestaobranding.com/api/v1/operations** — Criar operação (escopo `team:manage`) · aceita `Idempotency-Key` Respeita o limite de operações do plano (403 plan_limit). Corpo de exemplo: ```json { "name": "Loja Norte", "color": "cyan", "icon": "store" } ``` Resposta 201: ```json { "id": "o2…", "slug": "loja-norte", "name": "Loja Norte" } ``` - **GET https://crm.vdgestaobranding.com/api/v1/members** — Listar membros e convites (escopo `team:manage`) Resposta 200: ```json { "data": [ { "user_id": "u1…", "name": "Ana", "email": "ana@exemplo.com", "role": "atendente", "profile": "personalizado", "permissions": [ "inbox.assigned", "inbox.reply", "templates.view" ], "phone_ids": null, "operation_ids": [ "o1…" ] } ], "pending_invitations": [] } ``` - **POST https://crm.vdgestaobranding.com/api/v1/members** — Convidar membro (escopo `team:manage`) · aceita `Idempotency-Key` profile: admin | gerente | atendente | disparador | personalizado (role admin/atendente continua aceito). permissions: lista de permissões (ex.: inbox.all, inbox.assigned, inbox.reply, leads.view, templates.view, campaigns.dispatch…); sem permissions, o perfil pronto é aplicado. operation_ids: operações liberadas (padrão: a da chave). phone_ids: números liberados (null = todos). Respeita o limite de usuários do plano. Corpo de exemplo: ```json { "email": "ana@exemplo.com", "profile": "personalizado", "permissions": [ "inbox.assigned", "inbox.reply", "templates.view" ], "operation_ids": [ "o1…" ], "phone_ids": null } ``` - **PATCH https://crm.vdgestaobranding.com/api/v1/members/{id}** — Alterar perfil e permissões (escopo `team:manage`) Altera perfil, permissões, operações e números liberados; vale na hora e fica no histórico. Mudar permissões de um perfil pronto o torna Personalizado. O owner e o criador da chave não podem ser alterados. Corpo de exemplo: ```json { "profile": "gerente", "operation_ids": [ "o1…", "o2…" ], "phone_ids": null } ``` - **DELETE https://crm.vdgestaobranding.com/api/v1/members/{id}** — Remover membro (escopo `team:manage`) # Respostas rápidas - **GET https://crm.vdgestaobranding.com/api/v1/quick-replies** — Listar respostas rápidas (escopo `settings:manage`) Resposta 200: ```json { "data": [ { "id": "x1…", "shortcut": "/ola", "text": "Olá! Como posso ajudar?" } ] } ``` - **POST https://crm.vdgestaobranding.com/api/v1/quick-replies** — Criar (escopo `settings:manage`) · aceita `Idempotency-Key` Corpo de exemplo: ```json { "shortcut": "/ola", "text": "Olá! Como posso ajudar?" } ``` Resposta 201: ```json { "id": "x1…", "shortcut": "/ola", "text": "Olá! Como posso ajudar?" } ``` - **PATCH https://crm.vdgestaobranding.com/api/v1/quick-replies/{id}** — Atualizar (escopo `settings:manage`) Corpo de exemplo: ```json { "shortcut": "/ola", "text": "Olá! Como posso ajudar?" } ``` - **DELETE https://crm.vdgestaobranding.com/api/v1/quick-replies/{id}** — Excluir (escopo `settings:manage`) # Tags - **GET https://crm.vdgestaobranding.com/api/v1/tags** — Listar tags (escopo `settings:manage`) Resposta 200: ```json { "data": [ { "id": "x1…", "name": "vip", "color": "amber" } ] } ``` - **POST https://crm.vdgestaobranding.com/api/v1/tags** — Criar (escopo `settings:manage`) · aceita `Idempotency-Key` Corpo de exemplo: ```json { "name": "vip", "color": "amber" } ``` Resposta 201: ```json { "id": "x1…", "name": "vip", "color": "amber" } ``` - **PATCH https://crm.vdgestaobranding.com/api/v1/tags/{id}** — Atualizar (escopo `settings:manage`) Corpo de exemplo: ```json { "name": "vip", "color": "amber" } ``` - **DELETE https://crm.vdgestaobranding.com/api/v1/tags/{id}** — Excluir (escopo `settings:manage`) # Departamentos - **GET https://crm.vdgestaobranding.com/api/v1/departments** — Listar departamentos (escopo `settings:manage`) Resposta 200: ```json { "data": [ { "id": "x1…", "name": "Suporte" } ] } ``` - **POST https://crm.vdgestaobranding.com/api/v1/departments** — Criar (escopo `settings:manage`) · aceita `Idempotency-Key` Corpo de exemplo: ```json { "name": "Suporte" } ``` Resposta 201: ```json { "id": "x1…", "name": "Suporte" } ``` - **PATCH https://crm.vdgestaobranding.com/api/v1/departments/{id}** — Atualizar (escopo `settings:manage`) Corpo de exemplo: ```json { "name": "Suporte" } ``` - **DELETE https://crm.vdgestaobranding.com/api/v1/departments/{id}** — Excluir (escopo `settings:manage`) - **POST https://crm.vdgestaobranding.com/api/v1/departments/{id}/members** — Definir membros do departamento (escopo `settings:manage`) Substitui a lista. Somente usuários com acesso a esta operação. Corpo de exemplo: ```json { "user_ids": [ "u1…" ] } ``` # Conta parceira - **GET https://crm.vdgestaobranding.com/api/v1/operations** — Listar operações (clientes finais) (escopo `operations:manage`) Requer chave de conta (vdk_acct_live_… / vdk_acct_test_…), plano Agência ou Enterprise. A operação precisa pertencer à conta da chave. Filtre por external_id para achar a operação de um cliente do seu sistema. Parâmetros: `external_id` (ID do cliente no seu sistema.) Resposta 200: ```json { "data": [ { "id": "op1…", "name": "Cliente Exemplo Ltda", "external_id": "cli-42", "slug": "cliente-exemplo", "color": null, "icon": null, "cnpj": "12345678000190", "archived": false, "created_at": "2026-11-03T15:00:00Z" } ], "quota": { "used": 3, "limit": 50 } } ``` - **POST https://crm.vdgestaobranding.com/api/v1/operations** — Criar operação para um cliente final (escopo `operations:manage`) · aceita `Idempotency-Key` Requer chave de conta (vdk_acct_live_… / vdk_acct_test_…), plano Agência ou Enterprise. A operação precisa pertencer à conta da chave. external_id é único na conta (409 external_id_taken se repetido, com operation_id existente). Corpo de exemplo: ```json { "name": "Cliente Exemplo Ltda", "external_id": "cli-42", "cnpj": "12345678000190", "legal_name": "Cliente Exemplo Ltda" } ``` Resposta 201: ```json { "id": "op1…", "name": "Cliente Exemplo Ltda", "external_id": "cli-42", "slug": "cliente-exemplo", "color": null, "icon": null, "cnpj": "12345678000190", "archived": false, "created_at": "2026-11-03T15:00:00Z" } ``` - **GET https://crm.vdgestaobranding.com/api/v1/operations/{id}** — Obter operação (escopo `operations:manage`) Requer chave de conta (vdk_acct_live_… / vdk_acct_test_…), plano Agência ou Enterprise. A operação precisa pertencer à conta da chave. Resposta 200: ```json { "id": "op1…", "name": "Cliente Exemplo Ltda", "external_id": "cli-42", "slug": "cliente-exemplo", "color": null, "icon": null, "cnpj": "12345678000190", "archived": false, "created_at": "2026-11-03T15:00:00Z" } ``` - **PATCH https://crm.vdgestaobranding.com/api/v1/operations/{id}** — Atualizar operação (escopo `operations:manage`) Requer chave de conta (vdk_acct_live_… / vdk_acct_test_…), plano Agência ou Enterprise. A operação precisa pertencer à conta da chave. Corpo de exemplo: ```json { "name": "Cliente Exemplo", "external_id": "cli-42" } ``` Resposta 200: ```json { "id": "op1…", "name": "Cliente Exemplo Ltda", "external_id": "cli-42", "slug": "cliente-exemplo", "color": null, "icon": null, "cnpj": "12345678000190", "archived": false, "created_at": "2026-11-03T15:00:00Z" } ``` - **POST https://crm.vdgestaobranding.com/api/v1/operations/{id}/archive** — Arquivar operação (escopo `operations:manage`) Requer chave de conta (vdk_acct_live_… / vdk_acct_test_…), plano Agência ou Enterprise. A operação precisa pertencer à conta da chave. Chamadas a uma operação arquivada retornam 409 operation_archived. Resposta 200: ```json { "id": "op1…", "name": "Cliente Exemplo Ltda", "external_id": "cli-42", "slug": "cliente-exemplo", "color": null, "icon": null, "cnpj": "12345678000190", "archived": true, "created_at": "2026-11-03T15:00:00Z" } ``` - **POST https://crm.vdgestaobranding.com/api/v1/operations/{id}/restore** — Restaurar operação (escopo `operations:manage`) Requer chave de conta (vdk_acct_live_… / vdk_acct_test_…), plano Agência ou Enterprise. A operação precisa pertencer à conta da chave. Resposta 200: ```json { "id": "op1…", "name": "Cliente Exemplo Ltda", "external_id": "cli-42", "slug": "cliente-exemplo", "color": null, "icon": null, "cnpj": "12345678000190", "archived": false, "created_at": "2026-11-03T15:00:00Z" } ``` - **GET https://crm.vdgestaobranding.com/api/v1/operations/{id}/keys** — Listar chaves da operação (escopo `keys:manage`) Requer chave de conta (vdk_acct_live_… / vdk_acct_test_…), plano Agência ou Enterprise. A operação precisa pertencer à conta da chave. Resposta 200: ```json { "data": [ { "id": "k1…", "name": "Back-end JMR", "mode": "live", "prefix": "vdk_live_ab12", "scopes": [ "inbox:write" ], "expires_at": null, "created_at": "2026-11-03T15:00:00Z", "last_used_at": null, "revoked_at": null } ] } ``` - **POST https://crm.vdgestaobranding.com/api/v1/operations/{id}/keys** — Criar chave de operação (escopo `keys:manage`) · aceita `Idempotency-Key` Requer chave de conta (vdk_acct_live_… / vdk_acct_test_…), plano Agência ou Enterprise. A operação precisa pertencer à conta da chave. A chave completa aparece só nesta resposta; guarde-a em um cofre de segredos. Chave de conta de teste só emite chaves de teste. Máximo de 25 chaves ativas por operação. Corpo de exemplo: ```json { "name": "Back-end JMR", "mode": "live", "scopes": [ "inbox:read", "inbox:write", "contacts:write", "webhooks:manage" ], "expires_at": null, "allowed_ips": [] } ``` Resposta 201: ```json { "id": "k1…", "name": "Back-end JMR", "mode": "live", "prefix": "vdk_live_ab12", "scopes": [ "inbox:read", "inbox:write" ], "key": "vdk_live_…" } ``` - **DELETE https://crm.vdgestaobranding.com/api/v1/operations/{id}/keys/{keyId}** — Revogar chave de operação (escopo `keys:manage`) Requer chave de conta (vdk_acct_live_… / vdk_acct_test_…), plano Agência ou Enterprise. A operação precisa pertencer à conta da chave. Efeito imediato. - **POST https://crm.vdgestaobranding.com/api/v1/operations/{id}/embed/sessions** — Criar sessão de embed para um usuário final (escopo `embed:create`) · aceita `Idempotency-Key` Requer chave de conta (vdk_acct_live_… / vdk_acct_test_…), plano Agência ou Enterprise. A operação precisa pertencer à conta da chave. Mesmo corpo de POST /embed/sessions; external_user_id é um atalho para user.external_id. Corpo de exemplo: ```json { "user": { "external_id": "u-123", "name": "Ana", "email": "ana@cliente.com" }, "modules": [ "inbox" ], "permissions": [ "inbox:read", "inbox:reply" ], "phone_number_refs": [ "a0b1…" ] } ``` Resposta 201: ```json { "session_id": "es1…", "token": "vdex_…", "url": "https://crm.vdgestaobranding.com/embed?t=vdex_…", "modules": [ "inbox" ], "test": false } ``` - **POST https://crm.vdgestaobranding.com/api/v1/operations/{id}/connect-sessions** — Criar link de conexão do WhatsApp (escopo `connect:create`) · aceita `Idempotency-Key` Requer chave de conta (vdk_acct_live_… / vdk_acct_test_…), plano Agência ou Enterprise. A operação precisa pertencer à conta da chave. Link de uso único (30 min) para o cliente final abrir a janela da Meta. Ao concluir: webhook phone_number.connected; em erro: connect_session.failed. Corpo de exemplo: ```json { "redirect_url": "https://painel.parceiro.com/whatsapp/conectado" } ``` Resposta 201: ```json { "session_id": "cs1…", "status": "pending", "expires_at": "2026-11-03T15:30:00Z", "operation_id": "op1…", "url": "https://crm.vdgestaobranding.com/conectar/…" } ``` - **GET https://crm.vdgestaobranding.com/api/v1/operations/{id}/members** — Listar membros com acesso à operação (escopo `members:manage`) Requer chave de conta (vdk_acct_live_… / vdk_acct_test_…), plano Agência ou Enterprise. A operação precisa pertencer à conta da chave. Resposta 200: ```json { "data": [ { "user_id": "u1…", "email": "ana@cliente.com", "role": "atendente", "operation_ids": [ "op1…" ] } ] } ``` - **POST https://crm.vdgestaobranding.com/api/v1/operations/{id}/members** — Convidar membro para a operação (escopo `members:manage`) · aceita `Idempotency-Key` Requer chave de conta (vdk_acct_live_… / vdk_acct_test_…), plano Agência ou Enterprise. A operação precisa pertencer à conta da chave. Corpo de exemplo: ```json { "email": "ana@cliente.com", "role": "atendente" } ``` - **PATCH https://crm.vdgestaobranding.com/api/v1/operations/{id}/members/{userId}** — Alterar perfil do membro (escopo `members:manage`) Requer chave de conta (vdk_acct_live_… / vdk_acct_test_…), plano Agência ou Enterprise. A operação precisa pertencer à conta da chave. Corpo de exemplo: ```json { "role": "admin" } ``` Resposta 200: ```json { "user_id": "u1…", "role": "admin", "operation_id": "op1…" } ``` - **DELETE https://crm.vdgestaobranding.com/api/v1/operations/{id}/members/{userId}** — Remover acesso de atendente à operação (escopo `members:manage`) Requer chave de conta (vdk_acct_live_… / vdk_acct_test_…), plano Agência ou Enterprise. A operação precisa pertencer à conta da chave.