Skip to main content
Two official SDKs, both covering every /v1 endpoint: Two more pieces draw an agent’s mascot, its animated face, in your own web page or Flutter app. See Mascot widgets. Both retry rate limits, page through lists, send an idempotency key on calls, test calls and top-ups, and raise errors carrying the API’s stable code, the request_id to quote and the doc_url to read. A test in each compares its method table against the OpenAPI document in both directions, so an endpoint cannot go unwrapped and a method cannot claim an endpoint that does not exist.
Every other language works against the same HTTP API and the same OpenAPI document. Integrate has a fifteen-line client in Node and in Python for anyone who would rather not add a dependency.

Quickstart

Both SDKs name their methods the same way: agents.create, calls.list, sipTrunks.status, billing.createTopup. Eighteen resources, and a method for each of the 100 /v1 endpoints.

Pagination

Lists are cursor-paginated. Iterate the page to walk every page; the cursor and your filters are carried along.

Errors

Match on code. The message is written for people and may be reworded.

Idempotency

calls.create, agents.testCall, phoneNumbers.purchase and billing.createTopup require an idempotency key. The SDKs generate one per call and reuse it across their own retries, so a network timeout never becomes two phone calls. Pass your own to make a retry from your side safe too.

Retries

The two SDKs share one policy:
  • 429: retried after Retry-After, capped at ten seconds, up to maxRetries (default 2). Rate-limited requests are never charged.
  • Network failures, timeouts and 502–504: retried only for GET and for requests carrying an idempotency key. DELETE, PATCH and unkeyed POST (hanging up, starting or pausing a campaign, testing a trunk, rotating a key) are never repeated when the outcome is unknown.
  • 500 and other 4xx: never retried.

Pinning a version

Sends the Wixzel-Version header, so an upgrade is something you do rather than something that happens to you.

Options

Both expose an escape hatch, client.request(method, path, …), that reaches an endpoint the SDK does not model yet with the same auth, retries and error handling.

In the browser and in Flutter

A live key in a page or a shipped app is a key anyone can read. Call your own backend from the client, and let the backend hold the key.
To put an agent in the page or app (a voice conversation with no phone line), mint a session on your server and connect from the client with wixzel-voice/realtime (browser) or RealtimeConnection (Dart). See Realtime: web and mobile. The API’s CORS policy does not yet expose Retry-After, X-Wixzel-Balance or Idempotent-Replay to page scripts, so those read as empty in a browser. Everything else works.

Mascot widgets

Every agent has a mascot: a small JSON spec of a shape, two eyes and a smile, drawn live. These two packages draw it in your own page or app, with the same runtime the share link, the website widget and the Wixzel Voice app use, so a mascot looks and moves the same everywhere. Both can lip-sync it to a realtime session.

On the web: wixzel-voice/mascot

A subpath of the TypeScript SDK, from 0.10.0:
face.connect asks for the microphone, connects, and moves the mascot with the call: thinking while it connects, listening while the user talks, and its mouth in time with the agent’s audio. If you create the RealtimeSession yourself, pass face.handlers(yourHandlers) to it instead. Without agent or spec it draws the default green mascot. Pass followPointer: true to make the eyes follow the pointer. DEFAULT_MASCOT, PRESETS, normalizeSpec, MOVE_NAMES and the Mascot class are exported too. The main wixzel-voice import does not load any of this, so server code pays nothing for it.

In Flutter: wixzel_voice_flutter

Flutter widgets for the mascot, on pub.dev. It works with the wixzel_voice Dart SDK and needs Flutter 3.27 or newer.
MascotRealtimeLink makes the mascot listen, think and talk in time with the agent’s audio. It does not play or record audio: your app sends the microphone with conn.sendAudio and plays the RealtimeAudio events, as in Realtime: In Flutter or Dart. Pass each microphone frame to link.micAudio(frame) too, and the mascot leans in while the user talks. The eyes follow the phone’s tilt (followTilt, on by default), and a mascot animates only while it is on screen.

Coming from wixzel-phone or wixzel_phone

Up to 0.3.0 the SDKs were published as wixzel-phone on npm and wixzel_phone on pub.dev, from when the product was called Wixzel Phone. From 0.4.0 they are wixzel-voice and wixzel_voice. To move, change the package name and the import: from 'wixzel-voice', and in Dart package:wixzel_voice/wixzel_voice.dart. WixzelPhone still works as a deprecated alias of WixzelVoice, so the rest of your code can follow later. The old packages keep working where they are. They call api.phone.wixzel.com, which serves the same API as api.voice.wixzel.com and always will.

Source