Getting Started
This walkthrough gets you from zero to a live voice call and a first authenticated API request.
1. Get credentials
Create an organization and an API key from the dashboard. Every request is scoped to your organization; keys never cross organization boundaries.
Send the key as a bearer token on every request:
export VAGARY_API_KEY=... # your key, from the dashboard
curl https://api.vagaryvoice.cloud/product/v1/... \
-H "Authorization: Bearer $VAGARY_API_KEY"
Read the key from the environment rather than typing it into the command: a key pasted inline is written to your shell history and to any log that captures the command.
Keys are prefixed vgk_. A request without one is rejected with 401 unauthorized. A key also
carries a product, and the edge refuses a call to a capability that product does not grant — so a
key scoped to speech cannot reach a capability you have not bought, whatever the request says.
2. Hold a voice call from the browser
Neither package below is on npm or PyPI yet. The names are canonical (ADR-122) and the release pipeline is what will make them installable — until it runs, treat these as the identities to build against, not as commands that will succeed.
Install the Vagary Voice SDK:
npm install @vagary/voice-sdk
Connect, capture the mic, and receive audio:
import {VoiceClient, GatewayTransport} from '@vagary/voice-sdk';
const client = new VoiceClient({
transport: new GatewayTransport({url: 'wss://gateway.vagaryvoice.cloud/stream'}),
});
client.on('transcript', (t) => console.log('heard:', t.text));
client.on('audio', () => {/* audio is played automatically */});
await client.connect();
await client.enableMic();
See the Realtime Client SDK reference for the full API, the React hooks
package, and the analysis-only realtime-media transport. Those pages document the realtime
implementation — @vagary/voice-sdk is what a customer installs, and the realtime client reaches
them through it (ADR-122).
3. Call a capability from your backend
Every capability is reachable today over plain HTTP through the same edge and the same key — no
package required. Here it is calling text-to-speech (POST /product/v1/tts/generate, documented on
its own capability reference page):
curl https://api.vagaryvoice.cloud/product/v1/tts/generate \
-H "Authorization: Bearer $VAGARY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"text": "Hello from Vagary Voice"}' \
| jq -r '.audio_base64' | base64 -d > out.wav
Or from Python with requests — installable today, unlike the
package below:
import base64
import os
import requests
resp = requests.post(
"https://api.vagaryvoice.cloud/product/v1/tts/generate",
headers={"Authorization": f"Bearer {os.environ['VAGARY_API_KEY']}"},
json={"text": "Hello from Vagary Voice"},
)
resp.raise_for_status()
audio = base64.b64decode(resp.json()["audio_base64"])
open("out.wav", "wb").write(audio)
Every capability has a page shaped like the TTS one above — see the capability reference for the full list, each with its own endpoints, request/response schemas, and public path.
The typed Python SDK below is not on PyPI yet (ADR-122; same as the JS package in step 2) — the
requests example above is not a workaround, it is what to use until it is. The names are canonical
and the release pipeline is what will make them installable.
Once published, vagary-voice wraps the same HTTP calls in a generated, typed client instead of
hand-rolled requests:
pip install vagary-voice
import apimw
from clients.eval_harness_client.api.default import eval_candidate
# ... construct the typed client against the capability base URL and call it
The Python SDK also ships apimw — the FastAPI middleware library that implements the house
API conventions (idempotency, cursor pagination, versioning) so your own
capabilities behave consistently.
4. Speak the house conventions
Whether you call from TypeScript, Python, or raw HTTP, the platform follows one set of
API conventions: send an Idempotency-Key on mutating requests so retries are
safe, page with opaque keyset cursors, and pin an API version. These are documented once and apply
platform-wide.