SDK oficial — stevo-sdk
O stevo-sdk é o SDK oficial (TypeScript/JavaScript) da Stevo. Um pacote só, com tudo que a plataforma oferece — bem separado por área:
| Área | Como acessa | O que faz |
|---|---|---|
| Gestão da conta | stevo.instances, stevo.links, stevo.ghl, stevo.billing, stevo.ghlAgency | instâncias, links de acesso, GHL, compras e GHL Agência |
| Stevo IA (v2) | stevo.ai | agentes, funil, chaves de provedor, FAQ, tools, follow-up, RAG, memória |
| Envio de mensagem | stevo.smv2(id) · stevo.oficial(id) | fala DIRETO com o servidor da instância (114 operações SM v2) ou o gateway Cloud API da Meta |
| Disparo em massa | stevo.dispatch | campanhas de WhatsApp com rotação de instâncias, agendamento e variações |
| StevoVoice | stevo.voice | chamadas de voz e acesso às gravações da instância |
📦 npm: npm.im/stevo-sdk · Requer Node.js 18+ · ESM + CommonJS + tipos inclusos
Este pacote era o stevo-gestao. Agora que cobre tudo (não só gestão), passou a se chamar stevo-sdk. Se você usa o antigo, troque para npm install stevo-sdk.
A mesma API tem um servidor MCP em https://openapi.stevo.chat/mcp. Plugue no n8n (nó MCP Client), Claude ou Cursor com a sua API key e a IA gerencia sua conta, envia mensagens, cria campanhas e agenda chamadas sem uma linha de código.
1. Crie sua API Key
No painel da Stevo: menu do perfil → API Keys → Nova API Key. Marque os scopes (permissões) que essa key vai ter — de instances:read (só leitura) até envio, disparo, voz, IA e billing. A key aparece uma única vez — guarde com segurança e nunca a exponha no navegador/front-end.
2. Instale e conecte
npm install stevo-sdk
import { Stevo } from 'stevo-sdk';
const stevo = new Stevo('stevo_sk_...'); // sua API key
const instancias = await stevo.instances.list();
console.log(`${instancias.filter((i) => i.connected).length} conectadas`);
3. Gestão da conta
// Criar instância numa vaga livre do plano (não compra vaga nova)
const nova = await stevo.instances.create({ name: 'minha-instancia' });
const oficial = await stevo.instances.create({ engine: 'official' }); // devolve onboarding_url
await stevo.instances.restart(id); // reconectar (ler QR depois)
await stevo.instances.recreateTotal(id); // DESTRUTIVO: zera tudo
await stevo.instances.recreateTotalBatch([id1, id2, id3]); // em massa (até 50)
// Webhook da instância (o mesmo de Configurações → Webhook no painel)
await stevo.instances.setWebhook(id, { url: 'https://meu-sistema.com/webhook/stevo', events: ['MESSAGE', 'CONNECTION'] }); // SM v2
await stevo.instances.setWebhook(idOficial, { url: 'https://meu-sistema.com/webhook/oficial' }); // API Oficial (todos os eventos; `events` é ignorado)
const webhook = await stevo.instances.getWebhook(id); // { engine, url, events }
await stevo.instances.deleteWebhook(id);
// Fusão: liga a instância API Oficial à SM v2 do MESMO número — STChat, transmissor e IA
// tratam as duas como um só contato (o "Fundir instâncias" do painel)
await stevo.instances.fuse(idOficial, idSmv2); // 400 phone_mismatch/engine_mismatch, 409 already_fused
const fusao = await stevo.instances.getFusion(idOficial); // { instance, fused, partner }
await stevo.instances.unfuse(idOficial); // limpa os dois lados
// Links, GHL e compras
const link = await stevo.links.whiteLabel(id, { permanent: true });
await stevo.ghl.connect(id, { mode: 'oauth' });
const catalogo = await stevo.billing.plans();
if (catalogo.has_saved_card) await stevo.billing.purchase({ plan: 'stevo3' }); // cobra o cartão salvo
// Sem cartão salvo (ou pra mandar o link pro cliente final): Stripe Checkout hospedado.
// Não cobra na hora — devolve checkout_url; após pagar, o provisionamento é automático.
const { checkout_url } = await stevo.billing.checkout({ plan: 'stevo3' });
4. Enviando mensagens
Cada instância roda no seu próprio servidor, com token próprio — mas o SDK resolve isso sozinho a partir do instanceId:
// SM v2 (WhatsApp não-oficial) — 114 operações do servidor
const wa = await stevo.smv2(instanceId);
await wa.sendText({ body: { number: '5511999999999', text: 'Olá!' } });
await wa.sendMedia({ body: { number: '5511999999999', url: 'https://...', caption: 'Segue!' } });
const grupos = await wa.getGroupList();
// API Oficial Meta — formato Cloud API + templates HSM
const meta = await stevo.oficial(instanceIdOficial);
await meta.sendMessage({ to: '5511999999999', type: 'text', text: { body: 'Olá!' } });
const templates = await meta.listTemplates();
// Mídia RECEBIDA (o webhook traz só o id: image.id, audio.id...) — sem token da Meta
const midia = await meta.downloadMedia('1436196501752591'); // { data, mimeType, fileSize, sha256, fileName }
// Prefere passar as credenciais na mão? Também dá:
const wa2 = await stevo.smv2({ serverUrl: 'https://sm-x.stevo.chat', token: 'apikey-da-instancia' });
O client SM v2 tem 114 operações geradas do swagger oficial (grupos: Send Message, Chat, Group, Label, Newsletter, User, Instance, Community, Call, Voice e Message), todas com autocomplete. Referência: API StevoManager v2 · API Oficial.
5. Disparo em massa
Você passa os instance_ids que vão disparar — as credenciais dos servidores são resolvidas internamente (você nunca envia token):
const camp = await stevo.dispatch.createCampaign({
instance_ids: [instanceId],
name: 'Promo Julho',
messages: ['Olá! Temos novidades para você 🎉'],
recipients: [{ phone: '5511999999999', name: 'Maria' }],
config: { minDelay: 5, maxDelay: 15 }, // segundos entre envios
start: true,
});
await stevo.dispatch.getCampaign(camp.campaign_id); // status/progresso
await stevo.dispatch.pause(camp.campaign_id);
await stevo.dispatch.resume(camp.campaign_id);
Com mais de uma instância em instance_ids, a rotação é automática. messages aceita variações com mídia e botões.
6. StevoVoice — chamadas de voz com IA
Requer o StevoVoice assinado na instância:
// Uma chamada com agente de IA (ElevenLabs)
await stevo.voice.scheduleCall(instanceId, {
to_number: '5511999999999',
agent_id: 'agent_xyz',
scheduled_at: '2026-07-20T14:00:00Z', // opcional (default: agora)
});
// Em lote, com intervalo entre chamadas
await stevo.voice.batchCalls(instanceId, {
numbers: ['5511999999999', '5511888888888'],
agent_id: 'agent_xyz',
interval_seconds: 60,
});
const agendadas = await stevo.voice.listScheduled(instanceId);
await stevo.voice.cancelCall(callId);
// Gravações das ligações nativas — requer scope voice:read
const page = await stevo.voice.listRecordings(instanceId, {
limit: 50,
direction: 'outbound',
has_audio: true,
});
const gravacao = await stevo.voice.getRecording(instanceId, page.recordings[0].id);
const resposta = await stevo.voice.downloadRecording(instanceId, gravacao.id);
const mp3 = await resposta.arrayBuffer();
// Atalho pós-ligação: aceita UUID, nome visível ou instance_name
const ultima = await stevo.voice.getLatestRecording('well-pessoal-teste', {
call_id: 'id-da-chamada', // opcional, mas recomendado em chamadas simultâneas
});
Receita pronta: baixar a última gravação pela API REST
Você não precisa descobrir o UUID da instância nem o ID da gravação antes de
começar. Crie uma API Key com o scope voice:read e informe o nome da instância:
curl --get 'https://openapi.stevo.chat/v1/voice/recordings/latest' \
--header 'Authorization: Bearer stevo_sk_SUA_CHAVE' \
--data-urlencode 'instance=nome-da-instancia'
A resposta já traz a instância resolvida, a última gravação e a URL autenticada de download:
{
"data": {
"instance": {
"id": "UUID_DA_INSTANCIA",
"name": "Minha instância",
"instance_name": "nome-da-instancia"
},
"recording": {
"id": "UUID_DA_GRAVACAO",
"duration_seconds": 42,
"format": "mp3",
"download_available": true,
"download_url": "/v1/instances/UUID_DA_INSTANCIA/voice/recordings/UUID_DA_GRAVACAO/download"
}
}
}
Copie o download_url e faça o segundo GET com a mesma chave. O -L é
obrigatório porque a API valida a posse e responde com um redirect 307 para o
MP3:
curl -L \
--header 'Authorization: Bearer stevo_sk_SUA_CHAVE' \
'https://openapi.stevo.chat/v1/instances/UUID_DA_INSTANCIA/voice/recordings/UUID_DA_GRAVACAO/download' \
--output ligacao.mp3
Para listar o histórico, use o data.instance.id devolvido no primeiro passo:
curl --get 'https://openapi.stevo.chat/v1/instances/UUID_DA_INSTANCIA/voice/recordings' \
--header 'Authorization: Bearer stevo_sk_SUA_CHAVE' \
--data-urlencode 'limit=20' \
--data-urlencode 'has_audio=true'
Em automações, passe também call_id no endpoint latest quando várias
ligações puderem terminar juntas. A gravação aparece somente após encerrar e
concluir o upload; repita brevemente se a primeira tentativa responder 404.
Se o nome corresponder a mais de uma instância, a API retorna
409 ambiguous_instance; nesse caso, use o UUID.
Ativar, configurar e embutir o webphone (widget)
// Status do StevoVoice na instância SM v2: motor disponível? ativado? cota/canais
const st = await stevo.voice.status(instanceId); // { voice_available, enabled, unlimited, remaining, channels, active_calls }
// Ativar SEM cobrar (regras do painel): conta comum ativa o trial de 50 ligações;
// conta com pacote StevoVoice usa uma vaga do pacote. Pra canais/ilimitado:
await stevo.voice.enable(instanceId);
await stevo.billing.purchase({ product: 'stevovoice', instance_id: instanceId, tier: 5 }); // cartão salvo
const { checkout_url } = await stevo.billing.checkout({ product: 'stevovoice', instance_id: instanceId, tier: 5 }); // link de pagamento
// Configurações da aba StevoVoice
await stevo.voice.updateSettings(instanceId, {
summary_enabled: true, summary_emails: ['gestor@empresa.com'], // resumo da ligação por e-mail
coach_enabled: true, // coach IA durante a ligação
receive_enabled: true, // receber ligações no webphone
});
// Widget: webphone embutível no site do cliente
const w = await stevo.voice.createWidget(instanceId, { name: 'Site', allowed_origins: ['https://meusite.com'] });
console.log(w.embed_snippet); // <script src="https://call.shurima.cloud/stevophone/widget.js" data-widget="wgt_..."></script>
await stevo.voice.updateWidget(w.id, { video_enabled: true });
await stevo.voice.deleteWidget(w.id);
7. Stevo IA (v2)
Configure agentes multi-provedor, funil de etapas, base de conhecimento e mais:
// Config base + chave do provedor (write-only: nunca é retornada)
await stevo.ai.updateSettings(instanceId, { enabled: true, timezone: 'America/Sao_Paulo' });
await stevo.ai.setProviderKeys(instanceId, { openai: 'sk-...' });
// Agente + funil
const agente = await stevo.ai.agents.create(instanceId, {
name: 'Atendente',
provider: 'openai',
model: 'gpt-4o-mini',
system_prompt: 'Você é um atendente cordial.',
is_primary: true,
});
await stevo.ai.stages.create(agente.id, { name: 'Boas-vindas', objective: 'Coletar o nome' });
// FAQ, follow-up e conhecimento (RAG)
await stevo.ai.faq.create(instanceId, { question: 'Qual o horário?', answer: 'Das 9h às 18h.' });
await stevo.ai.followup.set(instanceId, { enabled: true, max_followups: 3 });
8. Tratamento de erros
Toda falha vira um StevoError com o status HTTP e um código de negócio:
import { StevoError } from 'stevo-sdk';
try {
await stevo.billing.purchase({ plan: 'stevo3' });
} catch (e) {
if (e instanceof StevoError && e.code === 'no_saved_card') {
// conta sem cartão salvo — orientar a cadastrar no painel
}
}
O SDK tenta de novo sozinho em rate limit (429) e erros de servidor. Ele não expõe segredos: chaves de provedor são write-only e o token dos servidores é tratado internamente.
9. Entregando pra sua IA implementar
Se quem vai escrever a integração é uma IA (Claude, Cursor, Copilot, ChatGPT...), cole este bloco no contexto dela:
Use o pacote npm
stevo-sdk(TypeScript, tipos inclusos, Node 18+). Instancienew Stevo(apiKey)com a keystevo_sk_...da aba API Keys do painel Stevo. Recursos:instances,links,ghl,billing,ghlAgency,ai(gestão);stevo.smv2(instanceId)(servidor SM v2: sendText/sendMedia/getGroupList... 74 ops) estevo.oficial(instanceId)(Cloud API Meta: sendMessage/listTemplates/downloadMedia...) para ENVIAR mensagens — o SDK resolve as credenciais do servidor da instância sozinho;stevo.dispatch(campanhas de disparo com instance_ids) estevo.voice(chamadas de voz com IA). Erros sãoStevoErrorcom.statuse.code. Referência completa: https://tutorial.stevo.chat/public-api-reference
Referências
- 📖 Referência da API de Gestão (endpoints, erros e scopes)
- 📖 API StevoManager v2 e API Oficial
- 📦 Pacote no npm
- 🤖 Servidor MCP:
https://openapi.stevo.chat/mcp(mesma API key)