Official SDK — stevo-sdk
stevo-sdk is the official TypeScript/JavaScript SDK for Stevo. One package with everything the platform offers, cleanly split by area:
| Area | Access via | What it does |
|---|---|---|
| Account management | stevo.instances, stevo.links, stevo.ghl, stevo.billing, stevo.ghlAgency | instances, access links, GHL, purchases, GHL Agency |
| Stevo AI (v2) | stevo.ai | agents, funnel, provider keys, FAQ, tools, follow-up, RAG, memory |
| Messaging | stevo.smv2(id) · stevo.oficial(id) | talk DIRECTLY to the instance server (114 SM v2 operations) or the Meta Cloud API gateway |
| Bulk campaigns | stevo.dispatch | WhatsApp campaigns with instance rotation, scheduling and variations |
| StevoVoice | stevo.voice | voice calls and access to instance recordings |
📦 npm: npm.im/stevo-sdk · Node.js 18+ · ESM + CommonJS + types
This package used to be stevo-gestao. Now that it covers everything, it's called stevo-sdk. Switch with npm install stevo-sdk.
The same API ships an MCP server at https://openapi.stevo.chat/mcp. Plug it into n8n, Claude or Cursor with your API key and the AI manages the account, sends messages, creates campaigns and schedules calls without a line of code.
1. Create your API Key
In the Stevo panel: profile menu → API Keys → New API Key. Pick the scopes. The key is shown only once — store it safely and never expose it in a browser/front-end.
2. Install and connect
npm install stevo-sdk
import { Stevo } from 'stevo-sdk';
const stevo = new Stevo('stevo_sk_...');
const instances = await stevo.instances.list();
3. Account management
const inst = await stevo.instances.create({ name: 'my-instance' });
await stevo.instances.restart(id);
await stevo.instances.recreateTotalBatch([id1, id2]); // up to 50
// Instance webhook (same as Settings → Webhook in the panel)
await stevo.instances.setWebhook(id, { url: 'https://my-system.com/webhook/stevo', events: ['MESSAGE', 'CONNECTION'] }); // SM v2
await stevo.instances.setWebhook(officialId, { url: 'https://my-system.com/webhook/official' }); // Official API
const webhook = await stevo.instances.getWebhook(id); // { engine, url, events }
await stevo.instances.deleteWebhook(id);
const link = await stevo.links.whiteLabel(id, { permanent: true });
const catalog = await stevo.billing.plans();
if (catalog.has_saved_card) await stevo.billing.purchase({ plan: 'stevo3' });
4. Messaging
Each instance runs on its own server with its own token — the SDK resolves that from the instanceId:
// SM v2 — 114 server operations
const wa = await stevo.smv2(instanceId);
await wa.sendText({ body: { number: '5511999999999', text: 'Hi!' } });
// Official Meta API — Cloud API format + HSM templates
const meta = await stevo.oficial(instanceIdOfficial);
await meta.sendMessage({ to: '5511999999999', type: 'text', text: { body: 'Hi!' } });
// RECEIVED media (the webhook only carries the id: image.id, audio.id...) — no Meta token needed
const media = await meta.downloadMedia('1436196501752591'); // { data, mimeType, fileSize, sha256, fileName }
5. Bulk campaigns
Pass the instance_ids that will dispatch — server credentials are resolved internally (you never send a token):
const camp = await stevo.dispatch.createCampaign({
instance_ids: [instanceId],
name: 'July Promo',
messages: ['Hi! We have news for you 🎉'],
recipients: [{ phone: '5511999999999', name: 'Mary' }],
config: { minDelay: 5, maxDelay: 15 },
start: true,
});
await stevo.dispatch.pause(camp.campaign_id);
6. StevoVoice — AI voice calls
Requires StevoVoice subscribed on the instance:
await stevo.voice.scheduleCall(instanceId, { to_number: '5511999999999', agent_id: 'agent_xyz' });
await stevo.voice.batchCalls(instanceId, { numbers: ['5511...', '5511...'], agent_id: 'agent_xyz', interval_seconds: 60 });
// Native call recordings — requires voice:read
const page = await stevo.voice.listRecordings(instanceId, {
limit: 50,
direction: 'outbound',
has_audio: true,
});
const recording = await stevo.voice.getRecording(instanceId, page.recordings[0].id);
const response = await stevo.voice.downloadRecording(instanceId, recording.id);
const mp3 = await response.arrayBuffer();
// Post-call shortcut: accepts UUID, display name, or instance_name
const latest = await stevo.voice.getLatestRecording('well-pessoal-teste', {
call_id: 'call-id', // optional, but recommended for simultaneous calls
});
Ready-to-use recipe: download the latest recording via REST
You do not need the instance UUID or recording ID beforehand. Create an API Key
with the voice:read scope and pass the instance name:
curl --get 'https://openapi.stevo.chat/v1/voice/recordings/latest' \
--header 'Authorization: Bearer stevo_sk_YOUR_KEY' \
--data-urlencode 'instance=instance-name'
The response includes the resolved instance, latest recording, and its
authenticated download_url. Copy that URL and make a second GET with the same
key. -L is required because the API returns a 307 redirect to the MP3:
curl -L \
--header 'Authorization: Bearer stevo_sk_YOUR_KEY' \
'https://openapi.stevo.chat/v1/instances/INSTANCE_UUID/voice/recordings/RECORDING_UUID/download' \
--output call.mp3
To list the history, use the data.instance.id returned by the first request:
curl --get 'https://openapi.stevo.chat/v1/instances/INSTANCE_UUID/voice/recordings' \
--header 'Authorization: Bearer stevo_sk_YOUR_KEY' \
--data-urlencode 'limit=20' \
--data-urlencode 'has_audio=true'
For automations, also pass call_id to latest when multiple calls may end at
the same time. A recording appears after the call ends and its upload completes;
briefly retry on 404. If the name is ambiguous, use the UUID.
7. Stevo AI (v2)
await stevo.ai.setProviderKeys(instanceId, { openai: 'sk-...' }); // write-only
const agent = await stevo.ai.agents.create(instanceId, { name: 'Agent', provider: 'openai', model: 'gpt-4o-mini', is_primary: true });
await stevo.ai.stages.create(agent.id, { name: 'Welcome', objective: 'Collect the name' });
8. Error handling
Every failure is a StevoError with the HTTP status and a business code (no_saved_card, insufficient_scope, not_found...). The SDK retries automatically on 429 and server errors, and never exposes secrets.
9. Hand it to your AI
Use the npm package
stevo-sdk(TypeScript, types included, Node 18+). Instantiatenew Stevo(apiKey)with thestevo_sk_...key from the Stevo panel's API Keys tab. Resources:instances,links,ghl,billing,ghlAgency,ai(management);stevo.smv2(instanceId)andstevo.oficial(instanceId)to SEND messages (the SDK resolves the instance server credentials itself);stevo.dispatch(bulk campaigns via instance_ids) andstevo.voice(AI voice calls). Errors areStevoErrorwith.statusand.code. Full reference: https://tutorial.stevo.chat/public-api-reference
References
- 📖 Management API reference · SM v2 · Official API
- 📦 Package on npm
- 🤖 MCP server:
https://openapi.stevo.chat/mcp