Pular para o conteúdo principal

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:

ÁreaComo acessaO que faz
Gestão da contastevo.instances, stevo.links, stevo.ghl, stevo.billing, stevo.ghlAgencyinstâncias, links de acesso, GHL, compras e GHL Agência
Stevo IA (v2)stevo.aiagentes, funil, chaves de provedor, FAQ, tools, follow-up, RAG, memória
Envio de mensagemstevo.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 massastevo.dispatchcampanhas de WhatsApp com rotação de instâncias, agendamento e variações
StevoVoicestevo.voicechamadas de voz e acesso às gravações da instância

📦 npm: npm.im/stevo-sdk · Requer Node.js 18+ · ESM + CommonJS + tipos inclusos

Renomeado

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.

Prefere não escrever código? Use a IA + MCP

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 KeysNova 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+). Instancie new Stevo(apiKey) com a key stevo_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) e stevo.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) e stevo.voice (chamadas de voz com IA). Erros são StevoError com .status e .code. Referência completa: https://tutorial.stevo.chat/public-api-reference

Referências