Principal APIs Como criar tickets via API no Cloud Chat

Como criar tickets via API no Cloud Chat

Última atualização em Jan 21, 2026

📌 O que essa funcionalidade permite?

Essa API permite que você crie um ticket no Cloud Chat a partir de qualquer sistema externo, como:

  • Um sistema de telefonia (ex: quando uma ligação chega)

  • Um formulário preenchido no seu site

  • Uma integração com CRM, ERP ou qualquer ferramenta personalizada

Ao usar essa rota, você pode:

  • Criar um novo ticket com status em aberto, pendente, ou fechado

  • Associar o ticket a um contato via e-mail, telefone ou identificador

  • Incluir uma mensagem inicial (inbound ou outbound)

  • Definir atributos customizados da conversa no momento da criação


🧭 Quando usar essa API?

Use quando for necessário iniciar uma conversa no Cloud Chat sem que o cliente tenha mandado uma mensagem por um canal ativo.

Exemplos:

  • Recebeu uma ligação fora do Cloud Chat? → Gere um ticket com o resumo da chamada.

  • Alguém preencheu um formulário? → Crie o ticket automaticamente e inicie a tratativa por e-mail.

  • Quer centralizar comunicações que vêm de outras fontes? → Use essa API como ponto de entrada.


Pré‑requisitos

  • api_access_token válido do usuário (ou agent bot), com acesso à conta

  • ACCOUNT_ID e INBOX_ID da mesma conta

  • Para alguns canais, a Inbox precisa estar com "Criar conversa via API" habilitado

  • Para canal E‑mail: existir o vínculo ContactInbox entre o contato e a Inbox com source_id correto

🔗 Endpoint

POST https://{{CLOUDCHAT_DOMAIN}}/api/v1/accounts/{{ACCOUNT_ID}}/conversations

🔐 Headers obrigatórios

{
  "content-type": "application/json",
  "api_access_token": "SEU_TOKEN_DE_API"
}

🧾 Corpo da requisição

{
  "inbox_id": "1",
  "contact_identifier": "id_123",
  "contact_email": "[email protected]",
  "contact_phone_number": "+12345",
  "message": {
    "content": "Olá, acabei de preencher o formulário no site e preciso de ajuda.",
    "message_type": "incoming"
  },
  "status": "open", // Optional
  "private": false, // Optional
  "custom_attributes": {  // Optional
    "example1": "valueXPTO"
  },
  "additional_attributes": { // optional
    "mail_subject": "Protocolo de atendimento ABCD"
  },
  "assignee_id": "1" // optional
}

Como definir source_id por tipo de canal

  • Canal E‑mail (Channel::Email): o e‑mail do contato (ex.: [email protected])

  • Canal Telefone (Twilio/WhatsApp): número em formato E.164 (ex.: +5511999998888)

  • Canal Website (Channel::WebWidget): identificador gerado pelo Chatwoot (obtido via webhooks/contactable inboxes)

  • Canal API (Channel::Api): qualquer string estável única (ex.: SHEET-<sheetId>-ROW-<row>, TICKET-12345)


🧠 Explicação dos campos principais

inbox_id: Identificador da Inbox que pode ser obtido da barra do navegador (URI/rota) ao acessar a configuração de caixa de entrada.

assignee_id(opcional): Identificador do agente que será atribuído no momento da criação.

Para referenciar o contato envie um dos três campos abaixo:

  • contact_identifier: Identificador único do contato

  • contact_email: Email do contato

  • contact_phone_number: Número do contato

message: A mensagem contendo seus campos:

  • content: que é o conteúdo da mensagem

  • message_type:

    • "incoming": mensagem vinda do cliente

    • "outgoing": enviada pelo agente

    • "activity": nota interna

  • private: se a mensagem é visível ao cliente (false) ou interna (true)

additional_attributes -> mail_subject (opcional)

Caso o ticket seja tratado via canal de email, você pode utilizar esse campo para customizar o assunto no email enviado ao contato quando a conversa se iniciar.

custom_attributes (opcional, mas poderoso)

Você pode adicionar qualquer campo customizado de conversa, já existente na sua configuração, direto aqui. Para saber como criar atributos customizados, veja essa FAQ.


🎯 O ticket já nasce como “em aberto”?

Sim. O ticket será criado com status “open” por padrão, a menos que seja informado o campo status na requisição, o que o torna visível e pronto para atendimento imediato na caixa de entrada (inbox) especificada.


🧪 Como testar?

  1. Acesse seu api_access_token no painel de configurações

  2. Copie o ACCOUNT_ID, INBOX_ID e CLOUDCHAT_DOMAIN conforme descrito nesta FAQ de import

  3. Envie a requisição via Postman ou script

  4. Verifique no Cloud Chat se o ticket apareceu na Inbox correta, com as informações completas


⚠️ Erros Comuns

Uso incorreto de identificadores únicos

Os campos identifier, phone_number e email são atributos únicos do contato. Não devem ser fixados em requisições de criação de tickets.

Como a request utiliza upsert, caso sejam fixados, o resultado será sempre um único contato sendo atualizado a cada chamada, com todas as conversas vinculadas a ele.

Criação de Ticket não cria contato

A criação manual de tickets via API não gera novos contatos. O sistema apenas utiliza contatos já existentes.

Portanto, se o contato não existir, é necessário criá-lo previamente antes de iniciar uma conversa. Crie seguindo esta FAQ


Fluxo exemplo para criar um E-mail com mensagem do usuário

  1. Garantir/obter o contato
  • Buscar por e‑mail/telefone/identificador:

    GET /api/v1/accounts/{account_id}/contacts/search?q={chave}

  • Criar contato caso não exista:

    POST /api/v1/accounts/{account_id}/contacts

  1. Vincular o contato à Inbox (ContactInbox)
  • POST /api/v1/accounts/{account_id}/contacts/{id}/contact_inboxes

  • Body: { "inbox_id": "INBOX_ID", "source_id": "<conforme canal>" }

  1. Criar a conversa (sem mensagem inicial, se quiser registrar como cliente depois)
  • POST /api/v1/accounts/{account_id}/conversations

  • Body mínimo: { "source_id": "<...>", "inbox_id": "INBOX_ID", "status": "open" }

  1. Postar mensagem como cliente (incoming)
  • POST /api/v1/accounts/{account_id}/conversations/{conversation_id}/messages

  • Body: { "content": "Mensagem do cliente", "message_type": "incoming" }

  1. Opcional: responder como agente (outgoing)
  • Mesmo endpoint de mensagens, com message_type: "outgoing"

  • Para canal E‑mail, content_attributes pode aceitar to_emails, cc_emails, bcc_emails conforme sua configuração

Exemplo (Apps Script) — Fluxo exemplo para criar um E-mail com mensagem do usuário a partir do preenchimento de um Google Forms


function criarConversaEMensagemIncoming() {

  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Form_Responses");

  var lastRow = sheet.getLastRow();

  var nome = sheet.getRange(lastRow, 3).getValue();

  var email = sheet.getRange(lastRow, 4).getValue();

  var descricao = sheet.getRange(lastRow, 5).getValue();

  var assunto = sheet.getRange(lastRow, 2).getValue();

  var accountId = ACCOUNT_ID; // substitua pelo ID da conta

  var inboxId = INBOX_ID;     // substitua pelo ID da inbox

  var base = "https://CLOUDCHAT_DOMAIN/api/v1/accounts/" + accountId;

  var token = "SEU_API_ACCESS_TOKEN";

  // 1) Buscar/criar contato

  var resSearch = UrlFetchApp.fetch(base + "/contacts/search?q=" + encodeURIComponent(email), {

    method: "get",

    headers: { api_access_token: token, Accept: "application/json" },

    muteHttpExceptions: true

  });

  var s = JSON.parse(resSearch.getContentText());

  var contactId = (s && s.payload && s.payload[0] && s.payload[0].id) ? s.payload[0].id : null;

  if (!contactId) {

    var resCreate = UrlFetchApp.fetch(base + "/contacts", {

      method: "post",

      contentType: "application/json",

      payload: JSON.stringify({ name: nome, email: email }),

      headers: { api_access_token: token, Accept: "application/json" },

      muteHttpExceptions: true

    });

    var c = JSON.parse(resCreate.getContentText());

    contactId = (c && c.payload && c.payload.contact && c.payload.contact.id) ? c.payload.contact.id : null;

  }

  // 2) Vincular ContactInbox

  UrlFetchApp.fetch(base + "/contacts/" + contactId + "/contact_inboxes", {

    method: "post",

    contentType: "application/json",

    payload: JSON.stringify({ inbox_id: inboxId, source_id: String(email) }),

    headers: { api_access_token: token, Accept: "application/json" },

    muteHttpExceptions: true

  });

  // 3) Criar conversa (sem mensagem inicial)

  var resConv = UrlFetchApp.fetch(base + "/conversations", {

    method: "post",

    contentType: "application/json",

    payload: JSON.stringify({

      source_id: String(email),

      inbox_id: inboxId,

      status: "open",

      custom_attributes: { subject: assunto, requester_name: nome, requester_email: email }

    }),

    headers: { api_access_token: token, Accept: "application/json" },

    muteHttpExceptions: true

  });

  var conv = JSON.parse(resConv.getContentText());

  var conversationId = conv && conv.id ? conv.id : null;

  // 4) Postar mensagem como cliente (incoming)

  UrlFetchApp.fetch(base + "/conversations/" + conversationId + "/messages", {

    method: "post",

    contentType: "application/json",

    payload: JSON.stringify({

      content: "Assunto: " + assunto + "\n" +

               "Solicitante: " + nome + " <" + email + ">\n\n" +

               descricao,

      message_type: "incoming"

    }),

    headers: { api_access_token: token, Accept: "application/json" },

    muteHttpExceptions: true

  });

  sheet.getRange(lastRow, 7).setValue(conversationId);

}