SDKs.
Official Node and Python SDKs wrap the REST API with typed methods, or you can call the API directly with any HTTP client. The REST API is the source of truth; the SDKs are thin wrappers over it — anything you can do here, you can do with a plain fetch.
Install#
# Node
npm install @whizz/voice
# Python
pip install whizz-voiceBoth read the key from WHIZZ_KEY by default; pass it explicitly if you keep it elsewhere. Use a wz_test_ key against test resources and swap to wz_live_ in production.
Node#
The client mirrors the quickstart flow — create an agent, publish it, place a call — with typed methods and return types:
import { Whizz } from "@whizz/voice";
const whizz = new Whizz({ apiKey: process.env.WHIZZ_KEY });
// Create an agent
const agent = await whizz.agents.create({
name: "Support · AR/EN",
languages: ["ar", "en"],
dialect: "saudi",
voice: "noura",
first_message: "حياك الله في خدمة عملاء وِز، كيف أقدر أخدمك؟",
persona: "Warm, concise support agent. Confirm the order before acting.",
tools: ["lookup_order", "expedite_shipment"],
});
// Publish it, then place an outbound call
await whizz.agents.publish(agent.id);
const call = await whizz.calls.create({
agentId: agent.id,
phoneNumberId: "pn_5b8f0d21",
to: "+9665XXXXXXXX",
vars: { name: "سلطان", order: "49207" },
});
console.log(call.id, call.status); // → call_… queuedPython#
Same flow, synchronous by default:
from whizz_voice import Whizz
whizz = Whizz(api_key=os.environ["WHIZZ_KEY"])
# Create an agent
agent = whizz.agents.create(
name="Support · AR/EN",
languages=["ar", "en"],
dialect="saudi",
voice="noura",
first_message="حياك الله في خدمة عملاء وِز، كيف أقدر أخدمك؟",
persona="Warm, concise support agent. Confirm the order before acting.",
tools=["lookup_order", "expedite_shipment"],
)
# Publish it, then place an outbound call
whizz.agents.publish(agent.id)
call = whizz.calls.create(
agent_id=agent.id,
phone_number_id="pn_5b8f0d21",
to="+9665XXXXXXXX",
vars={"name": "سلطان", "order": "49207"},
)
print(call.id, call.status) # → call_… queuedVerifying webhooks#
Both SDKs ship a webhook verifier so you don't reimplement the signing scheme. whizz.webhooks.verify(rawBody, headers, secret) checks the signature and timestamp and returns the parsed event, or throws if the signature is invalid. Pass the raw request body — not re-serialized JSON. Full scheme on Webhooks.
// Express — mount with express.raw() so the body stays untouched
app.post("/hooks/whizz", express.raw({ type: "application/json" }), (req, res) => {
const event = whizz.webhooks.verify(
req.body, // raw request body (Buffer/string), not parsed JSON
req.headers, // webhook-id / webhook-timestamp / webhook-signature
process.env.WHIZZ_WEBHOOK_SECRET, // whsec_…
);
// event is the parsed, verified payload: { event, data }
if (event.event === "call.completed") {
// event.data is the call object with transcript, tool_calls, outcome…
}
res.status(200).end(); // ack fast, process async
});