Skip to content

Integração utilizando Webphone API4COM ​

Essa integração permite que os usuários façam chamadas telefônicas de dentro do seu CRM ou aplicação, atendendo no Webphone da API4COM, a extensão para o Google Chrome. A sua aplicação pede a chamada pela API e recebe o resultado de cada chamada no seu webhook, sem precisar carregar um Webphone.

O Webphone da API4COM já entrega o atendimento automático das chamadas pedidas pela API, a transferência, o histórico de chamadas e as atualizações, sem desenvolvimento do seu lado.

Um token por usuário ​

Cada usuário que faz chamadas cadastra na sua aplicação o próprio token de acesso. Tudo o que a aplicação faz em nome dele (buscar o ramal, configurar o webhook e realizar chamadas) usa o token dele.

A API4COM confere o plano, a situação e os limites de requisições do usuário dono do token, e envia o webhook para o endereço cadastrado por esse usuário. Por isso, cada usuário precisa ligar com o próprio token: assim, cada um liga dentro do próprio plano e os resultados chegam separados por usuário.

Resumo do que a integração guarda para cada usuário:

  • O token de acesso do usuário
  • O ramal do usuário
  • A configuração do webhook do usuário

Criação da conta e dos usuários ​

  1. Crie a conta da empresa no Portal da API4COM e ative-a pelo link enviado por e-mail. Quem cria a conta é o administrador.
  2. No portal, o administrador convida os usuários que vão fazer chamadas, informando e-mail, senha e plano de cada um.
  3. Cada usuário ativa o próprio acesso pelo e-mail de convite. O e-mail só ativa o usuário: a senha é a que o administrador definiu no convite.

Importante:

  • O ramal de cada usuário é criado pela API4COM junto com o usuário, quando ele é convidado com plano. A sua aplicação não cria ramais: ela busca o ramal do usuário (veja Buscando o ramal do usuário).
  • O administrador também é um usuário: se ele também for fazer chamadas, cadastra o próprio token como os demais.
  • Para um usuário novo, repita os passos 2 e 3 e cadastre o token dele na sua aplicação. Os usuários já cadastrados não mudam.

Gerando o token de cada usuário ​

Cada usuário gera o próprio token no Portal da API4COM no menu Tokens de acesso → Novo Token de Acesso, com validade Nunca expira, e cola o token na tela de integrações da sua aplicação. O administrador da conta não gera token por outro usuário.

O token também pode ser criado pela API, com o login do próprio usuário. Faça o Login com o e-mail e a senha do usuário e, com o token retornado, crie um token que nunca expira:

JavaScript
const axios = require('axios');
const url = 'https://api.api4com.com/api/v1/users/accessTokens';
const config = {
  headers: {
    'Authorization': '<token do login do usuário>'
  }
};
const payload = {
  ttl: -1
};
axios.post(url, payload, config).then(response => {
  console.log(response.data);
}).catch(error => {
  console.error(error);
});

Resposta de sucesso:

JSON
{
  "id": "YggyHfrLEHAWmKiUFbXsT93Tkw2xjwHUbwJ6mgw4Vz5YGubReFGw34HmhrhZDUBM",
  "ttl": -1,
  "created": "2025-01-01T00:00:00.000Z"
}

O id retornado é o token de acesso do usuário.

Para confirmar que o token é válido, consulte o usuário dono do token e mostre na sua aplicação a quem ele pertence:

JavaScript
const axios = require('axios');
const url = 'https://api.api4com.com/api/v1/users/me';
const config = {
  headers: {
    'Authorization': '<token do usuário>'
  }
};
axios.get(url, config).then(response => {
  console.log(response.data);
}).catch(error => {
  console.error(error);
});

Resposta de sucesso:

JSON
{
  "uuid": "356b20ce-143f-4847-8cf1-a79959f4b390",
  "name": "Marina Alves",
  "email": "marina@empresa.com.br",
  "role": "USER"
}

Importante:

  • Guarde o token só no seu backend. Ele não expira e permite ligar em nome do usuário: nunca o envie para o navegador nem o coloque em URL, log ou mensagem de erro.
  • O token deixa de valer quando é removido no portal, quando vence ou quando o usuário troca a senha. A partir daí, qualquer requisição responde 401: marque o token do usuário como inválido e peça um token novo.
  • Se o usuário for trocar a senha que recebeu do administrador, ele deve trocar antes de gerar o token, pois a troca invalida os tokens já gerados.
  • Mais detalhes em Autenticação.

Buscando o ramal do usuário ​

Ao cadastrar o token do usuário, busque uma vez o ramal dele com o token dele e guarde junto do token:

JavaScript
const axios = require('axios');
const url = 'https://api.api4com.com/api/v1/integrations';
const config = {
  headers: {
    'Authorization': '<token do usuário>'
  },
  params: {
    'filter[where][gateway]': 'sippulse'
  }
};
axios.get(url, config).then(response => {
  console.log(response.data);
}).catch(error => {
  console.error(error);
});

Resposta de sucesso:

JSON
[
  {
    "id": 5821,
    "gateway": "sippulse",
    "metadata": {
      "domain": "empresa.api4com.com",
      "username": "1012",
      "password": "Xk3pQ7rTm2"
    }
  }
]

Importante:

  • O username é o ramal do usuário, usado nos campos extension e caller ao realizar uma chamada.
  • Use o ramal guardado nas chamadas; não consulte a cada chamada.
  • Se a lista vier vazia, o ramal ainda não foi vinculado ao usuário. No convite com plano, o ramal só é criado depois do pagamento. Tente novamente mais tarde.
  • Busque o ramal de novo quando uma chamada responder 404: o ramal mudou ou foi removido.

Configuração do Webhook ​

O webhook é configurado uma vez por usuário, com o token do usuário, por meio de uma Integração de Usuário. A API4COM envia para o endereço configurado um aviso quando a chamada é atendida (channel-answer) e outro quando a chamada termina (channel-hangup).

Escolha um identificador para a sua integração, em letras minúsculas e sem espaços (nos exemplos, minha-integracao). Ele é usado no campo gateway da integração e no metadata de cada chamada.

Antes de criar, verifique se o usuário já tem a integração:

JavaScript
const axios = require('axios');
const url = 'https://api.api4com.com/api/v1/integrations';
const config = {
  headers: {
    'Authorization': '<token do usuário>'
  },
  params: {
    'filter[where][gateway]': 'minha-integracao'
  }
};
axios.get(url, config).then(response => {
  console.log(response.data);
}).catch(error => {
  console.error(error);
});

Em seguida, crie ou atualize a integração:

JavaScript
const axios = require('axios');
const url = 'https://api.api4com.com/api/v1/integrations';
const config = {
  headers: {
    'Authorization': '<token do usuário>'
  }
};
const payload = {
  // id: 5822, // somente se a consulta acima retornou a integração
  gateway: 'minha-integracao',
  webhook: true,
  webhookConstraint: {
    metadata: {
      gateway: 'minha-integracao'
    }
  },
  metadata: {
    webhookUrl: 'https://seu-webhook.com/callback',
    webhookVersion: 'v1.8',
    webhookTypes: ['channel-answer', 'channel-hangup']
  }
};
axios.patch(url, payload, config).then(response => {
  console.log(response.data);
}).catch(error => {
  console.error(error);
});

Resposta de sucesso:

JSON
{
  "id": 5822,
  "gateway": "minha-integracao",
  "webhook": true,
  "webhookConstraint": {
    "metadata": {
      "gateway": "minha-integracao"
    }
  },
  "metadata": {
    "webhookUrl": "https://seu-webhook.com/callback",
    "webhookVersion": "v1.8",
    "webhookTypes": ["channel-answer", "channel-hangup"]
  }
}

Importante:

  • Somente as chamadas que atenderem as restrições de webhookConstraint são enviadas para o webhook, ou seja, somente aquelas que tenham gateway: 'minha-integracao' no metadata da chamada.
  • Se a integração já existir e o id não for enviado, a API responde 422 com o código INTEGRATION_ALREADY_EXISTS.
  • O campo webhookUrl deve usar HTTPS. Uma URL por cliente ou conta (por exemplo, https://seu-webhook.com/callback/cliente-8841) ajuda a identificar de quem é cada aviso assim que ele chega.

Instalação do Webphone ​

Cada usuário instala o Webphone da API4COM no Google Chrome. No Portal da API4COM, acesse o menu "Webphone" e clique no link para instalar, ou instale a extensão direto na Chrome Web Store.

Após instalar, o usuário clica no ícone do Webphone na barra de ferramentas do Chrome e faz login com o próprio usuário da API4COM, o mesmo que gerou o token cadastrado na sua aplicação.

Para validar a instalação, verifique na parte superior do Webphone se o status está como "Você está online" (ícone circular verde). Caso haja algum problema, o ícone fica laranja ou vermelho.

Atendimento automático

Ao realizar uma chamada pela API, a API4COM primeiro liga para o ramal do usuário e só depois para o número de destino. A chamada para o ramal chega identificada pelo cabeçalho SIP X-Api4comintegratedcall: true, e o Webphone da API4COM a atende automaticamente. O Webphone não avisa a sua aplicação: use o aviso channel-answer do webhook para mostrar que a chamada foi atendida.

Importante:

  • Com o Webphone fechado ou offline, a chamada não é realizada e a API responde 424. Oriente o usuário a manter o Webphone aberto e com o status "Você está online" para ligar pela sua aplicação.
  • O Webphone deve estar aberto em apenas um navegador por usuário.

Realizando uma chamada ​

Endpoint descontinuado

A rota POST /dialer está descontinuada. Se a sua integração ainda utiliza /dialer, migre para POST /calls (documentado abaixo) assim que possível.

O botão de ligar da sua aplicação chama o seu backend, que realiza a chamada com o token e o ramal do mesmo usuário:

JavaScript
const axios = require('axios');
const url = 'https://api.api4com.com/api/v1/calls';
const config = {
  headers: {
    'Authorization': '<token do usuário>'
  },
  timeout: 90000
};
const payload = {
  extension: '1012',
  caller: '1012',
  called: '+5511987654321',
  metadata: {
    gateway: 'minha-integracao',
    clienteId: 'c_207',
    dealId: 'deal_48213',
    callRef: 'cr_000731'
  }
};
axios.post(url, payload, config).then(response => {
  console.log(response.data);
}).catch(error => {
  console.error(error);
});

Resposta de sucesso:

JSON
{
  "status": "200",
  "id": "1PkXhmBsYAvr9legLB2d7BimT0Q",
  "message": "successful request"
}

Importante:

  • O campo Authorization deve ser preenchido com o token do usuário dono do ramal informado em extension.
  • O campo extension deve ser preenchido com o ramal do usuário (o username obtido em Buscando o ramal do usuário).
  • O campo caller deve ser preenchido com o mesmo valor de extension.
  • O campo called deve ser preenchido com o número de telefone que você deseja ligar, com código do país + DDD + número (exemplo: +5511987654321).
  • O campo metadata deve conter o gateway configurado no webhook, para que a chamada seja enviada ao seu webhook. As demais chaves são devolvidas em todos os avisos da chamada: use identificadores simples, em texto, e não envie dados pessoais como nome ou telefone do cliente. Um identificador único por tentativa (como callRef) ajuda a localizar a chamada depois.
  • A resposta 200 é enviada quando o Webphone do usuário atende, o que leva menos de um segundo com o atendimento automático. Ela não indica que o destino atendeu: para isso, use o aviso channel-answer do webhook. Configure um timeout HTTP de 90 segundos.
  • O id retornado corresponde ao mesmo ID da chamada exibido na Lista de Chamadas e pode ser usado para encerrar a chamada com POST /calls/{id}/hangup.
  • Faça uma chamada por vez por usuário. O limite é de 15 chamadas por minuto por ramal (veja Rate Limit).

Respostas possíveis:

RespostaO que aconteceuO que a aplicação deve fazer
200O Webphone do usuário atendeuMostrar "Chamando" e guardar o id
401Token inválido, removido ou vencidoMarcar o token do usuário como inválido e pedir um token novo
402 · 403O plano ou a situação do usuário não permitem ligar agoraOrientar o usuário a falar com o administrador da conta
404Ramal não encontrado (EXTENSION_NOT_FOUND)Buscar o ramal de novo
422Número ou parâmetro inválidoPedir para corrigir o número
424Webphone fechado, offline ou não atendeuPedir ao usuário para deixar o Webphone aberto e online
429Mais de 15 chamadas por minuto no ramalAguardar o tempo indicado em RateLimit-Reset
503Indisponibilidade temporáriaTentar novamente em alguns segundos
Sem respostaTempo esgotadoNão repetir automaticamente: a chamada pode ter sido realizada

Recebendo o Webhook ​

O endereço configurado recebe uma requisição POST com um JSON em dois momentos de cada chamada: quando o destino atende (channel-answer) e quando a chamada termina (channel-hangup).

Somente chamadas feitas pela API geram webhook

Faça todas as chamadas por POST /calls. Uma chamada discada direto no teclado do Webphone não tem o metadata com o gateway da sua integração e não é enviada ao seu webhook.

Exemplo do aviso de chamada atendida:

JSON
{
  "version": "v1.8",
  "eventType": "channel-answer",
  "id": "2ee13fa4-975c-499d-bbb8-5177ff418316",
  "domain": "empresa.api4com.com",
  "direction": "outbound",
  "caller": "1012",
  "called": "+5511987654321",
  "startedAt": "2026-10-23 14:02:11",
  "recordUrl": "https://listener.api4com.com/files/listen/2ee13fa4-975c-499d-bbb8-5177ff418316.mp3",
  "metadata": {
    "gateway": "minha-integracao",
    "clienteId": "c_207",
    "dealId": "deal_48213",
    "callRef": "cr_000731"
  }
}

Exemplo do aviso de chamada finalizada:

JSON
{
  "version": "v1.8",
  "eventType": "channel-hangup",
  "id": "2ee13fa4-975c-499d-bbb8-5177ff418316",
  "domain": "empresa.api4com.com",
  "direction": "outbound",
  "caller": "1012",
  "called": "+5511987654321",
  "startedAt": "2026-10-23 14:02:05",
  "answeredAt": "2026-10-23 14:02:11",
  "endedAt": "2026-10-23 14:06:40",
  "duration": 269,
  "hangupCause": "NORMAL_CLEARING",
  "hangupCauseCode": "16",
  "recordUrl": "https://listener.api4com.com/files/listen/2ee13fa4-975c-499d-bbb8-5177ff418316.mp3",
  "metadata": {
    "gateway": "minha-integracao",
    "clienteId": "c_207",
    "dealId": "deal_48213",
    "callRef": "cr_000731"
  }
}

Os campos retornados são:

  • O campo version indica a versão do webhook.
  • O campo eventType indica o tipo de evento: channel-answer ou channel-hangup.
  • O campo id é o identificador da chamada.
  • O campo domain é o domínio da conta.
  • O campo direction indica se a chamada é de entrada ou saída.
  • O campo caller é o ramal que realizou a chamada.
  • O campo called é o número de telefone que recebeu a chamada, no formato internacional (E.164).
  • O campo startedAt é a data e hora de início da chamada. No channel-answer, é a data e hora em que o destino atendeu.
  • O campo answeredAt é a data e hora em que a chamada foi atendida (somente no channel-hangup).
  • O campo endedAt é a data e hora em que a chamada foi finalizada (somente no channel-hangup).
  • O campo duration é a duração da conversa em segundos (somente no channel-hangup).
  • O campo hangupCause é o motivo do desligamento da chamada (somente no channel-hangup). Consulte a tabela de códigos de status.
  • O campo hangupCauseCode é o código do motivo do desligamento da chamada (somente no channel-hangup).
  • O campo recordUrl é a URL do arquivo de áudio da chamada.
  • O campo metadata é um objeto com os dados enviados em metadata ao realizar a chamada.

Importante:

  • Responda 200 imediatamente e processe o aviso depois. Sem 200, a entrega é repetida uma vez, cerca de um minuto depois.
  • O mesmo aviso pode chegar mais de uma vez: use id + eventType para identificar cada aviso.
  • O recordUrl só tem áudio quando a chamada foi atendida, e o arquivo pode levar alguns minutos para ficar disponível.
  • Uma chamada finalizada com NORMAL_CLEARING e duração zero é enviada como NO_ANSWER.
  • Se o aviso de fim de uma chamada não chegar em alguns minutos, consulte as chamadas do usuário com o token dele em GET /calls e procure o identificador enviado no metadata.
  • Os avisos trazem o número discado e o link da gravação: não os grave em logs abertos.

Removendo um usuário da integração ​

Quando um usuário deixar de usar a sua aplicação, remova a integração do webhook dele com DELETE /integrations/{id}, usando o token dele, e apague o token e o ramal guardados. Isso não altera o Webphone nem o usuário na conta da API4COM.

Considerações finais ​

Neste guia, você aprendeu como integrar o Webphone da API4COM com o seu CRM ou aplicação, com cada usuário usando o próprio token.

A documentação completa da API4COM está disponível em https://developers.api4com.com.

Se você tiver alguma dúvida ou precisar de ajuda, entre em contato com o suporte da API4COM.

Released under the MIT License.