Inova SMS · API
SiteMinhas chaves

API do Inova SMS

Envie SMS pelos chips conectados à sua conta, gere códigos de verificação e receba respostas. Todas as chamadas usam JSON e o endereço base é .

Base: /api/v1

Autenticação

Crie uma chave no painel em Integração > API e OTP. Ela aparece uma única vez. Envie em todo pedido, de uma destas formas:

Authorization: Bearer isk_XXXXXXXXXXXXXXXX
X-API-Key: isk_XXXXXXXXXXXXXXXX

Limite padrão: 120 requisições por minuto por chave (resposta 429 com Retry-After).

Fila e ritmo de envio

A API não envia na hora: ela coloca na fila, e cada aparelho busca as mensagens no ritmo seguro do chip (limite por dia, por hora, intervalo e janela de horário configurados no painel). Códigos OTP passam na frente e podem sair fora da janela. Por isso o status começa como fila e muda para enviada, entregue ou falhou. Use os webhooks para saber na hora.

StatusSignificado
filaAguardando um chip livre ou o horário agendado
enviandoO aparelho pegou e está enviando
enviadaSaiu do chip
entregueA operadora confirmou a entrega (nem toda operadora envia esse aviso)
falhouErro no envio. Veja o campo erro
cancelada / expiradaCancelada, número descadastrado ou validade vencida antes de sair

Enviar SMS

POST/api/v1/sms
CampoTipoDescrição
paratexto ou listaNúmero com DDD, em qualquer formato: (88) 99999-0000, 88999990000, +5588999990000. Lista de até 100.
mensagemtextoO texto. Até 6 partes de SMS.
referenciatexto, opcionalSeu identificador (até 80). Repetir a mesma referência não duplica o envio: devolve a mensagem já criada.
agendar_paradata, opcional2026-11-12 08:00. Sai a partir desse horário, respeitando a janela do chip.
validade_minnúmero, opcionalSe não sair em X minutos, expira em vez de chegar atrasada.
dispositivo_idnúmero, opcionalForça um aparelho. Sem ele, qualquer chip livre (rodízio).
remover_acentossim/não, opcionalPadrão da conta (ligado). Sem acento cabe 160 caracteres por SMS; com acento, 70.
curl -X POST /api/v1/sms \
  -H "Authorization: Bearer SUA_CHAVE" -H "Content-Type: application/json" \
  -d '{"para":"(88) 99999-0000","mensagem":"Ola Ana, consulta amanha 14h. Responda 1 para confirmar.","referencia":"agenda-1234"}'

HTTP 201
{"mensagens":[{"id":5821,"para":"+5588999990000","status":"fila","segmentos":1,"codificacao":"gsm","referencia":"agenda-1234", ...}],
 "aceitas":1,"recusadas":[]}

Com lista em para, números inválidos ou descadastrados vão em recusadas e os outros seguem.

Consultar uma mensagem

GET/api/v1/sms/{id}
{"mensagem":{"id":5821,"status":"entregue","enviado_em":"2026-11-10 14:02:11","entregue_em":"2026-11-10 14:02:19","erro":null, ...}}

Listar mensagens

GET/api/v1/sms?status=&desde_id=&referencia=&limite=50

Mais recentes primeiro, até 200 por chamada. Use desde_id para buscar só as novas.

Cancelar

DELETE/api/v1/sms/{id}

Só funciona enquanto a mensagem está na fila. Depois disso devolve 409.

Respostas recebidas

GET/api/v1/recebidas?desde_id=&limite=50
{"recebidas":[{"id":77,"de":"+5588999990000","mensagem":"1","recebido_em":"2026-11-10 14:05:40","em_resposta_a":5821}]}

Respostas que são só SAIR, PARAR, CANCELAR, STOP (e outras configuradas) descadastram o número automaticamente.

Código de verificação: enviar

POST/api/v1/otp/enviar
CampoDescrição
paraNúmero da pessoa
tamanho4 a 8 dígitos (padrão 6)
validade_min1 a 30 minutos (padrão 10)
mensagemOpcional, precisa ter {codigo}. Pode usar {minutos}.
{"otp_id":42,"para":"+5588999990000","expira_em":"2026-11-10 14:12:00","mensagem_id":5822}

Máximo de 3 códigos por número a cada 10 minutos. Um código novo invalida o anterior. O código nunca volta na resposta: só a pessoa vê.

Código de verificação: conferir

POST/api/v1/otp/verificar
{"otp_id":42,"codigo":"482913"}     ou     {"para":"88999990000","codigo":"482913"}

{"valido":true,"para":"+5588999990000"}
{"valido":false,"motivo":"codigo_incorreto","tentativas_restantes":3}

Motivos: codigo_incorreto, expirado, ja_usado, tentativas_esgotadas (5 tentativas), nao_encontrado.

Aparelhos

GET/api/v1/dispositivos
{"dispositivos":[{"id":3,"nome":"Moto G recepção","online":true,"bateria":100,"carregando":1,"pausado":false}]}

Conta

GET/api/v1/conta
{"conta":{"id":12,"nome":"Clínica Vida","situacao":"ativa","vencimento":"2026-12-05","hoje":{"enviadas":130,"na_fila":12}}}

Webhooks

Cadastre a URL do seu sistema no painel em Integração > Webhooks e escolha os eventos. Cada evento chega como POST JSON:

{"evento":"sms.recebida","enviado_em":"2026-11-10T14:05:41-03:00",
 "dados":{"id":77,"de":"+5588999990000","mensagem":"1","em_resposta_a":5821,"referencia_original":"agenda-1234","descadastrou":false}}
EventoQuando
sms.enviadaSaiu do chip
sms.entregueOperadora confirmou
sms.falhouFalha no envio, com erro
sms.recebidaChegou SMS no chip (resposta)
linha.pausadaChip pausado após 5 falhas seguidas
dispositivo.offlineAparelho 10 min sem conexão com mensagens na fila

Conferir a assinatura

Cabeçalhos: X-Inova-Evento, X-Inova-Timestamp e X-Inova-Assinatura = sha256= + HMAC-SHA256 de timestamp + "." + corpo com o segredo do webhook.

<?php
$corpo = file_get_contents('php://input');
$ts = $_SERVER['HTTP_X_INOVA_TIMESTAMP'];
$certo = 'sha256=' . hash_hmac('sha256', $ts . '.' . $corpo, 'SEU_SEGREDO');
if (!hash_equals($certo, $_SERVER['HTTP_X_INOVA_ASSINATURA']) || abs(time() - (int)$ts) > 300) {
    http_response_code(401); exit;
}
echo 'ok'; // qualquer 2xx confirma

Sem resposta 2xx, tentamos de novo em 1, 5, 15 e 60 minutos, 3 horas e 12 horas.

Erros

HTTPQuando
401Chave ausente, inválida ou revogada
402Conta bloqueada por pendência
403Plano sem acesso à API
404Mensagem ou aparelho não encontrado nesta conta
409Número descadastrado ("optout": true) ou mensagem que não dá mais para cancelar
422Campo inválido. O corpo traz erro e campo
429Limite de requisições ou de códigos OTP
{"erro":"Número de telefone inválido: 1234","campo":"para"}
Envie só para quem conhece você e aceitou receber. Volume alto para números que não esperam a mensagem gera denúncia e é o caminho mais rápido para a operadora bloquear o chip.