This is the shortest path from zero to a voice agent that talks to a real caller. On managed cloud, TeleQuick runs the media engine, the SIP trunking edge, and the agent runtime for you — you get an API key and make one call. In a few minutes you will have either an AI agent phoning a number over the PSTN, or a click-to-talk voice agent in the browser.
Managed cloud is a single production environment — there is no separate sandbox tenant. Test against your own numbers and a low-volume trunk before you scale up. If you need an isolated stack, see On-Prem / Self-Hosted.

Before you start

1

Create a workspace and API key

Sign in at portal.telequick.dev, create (or pick) a workspace, and mint an API key under Settings → API keys. Keep it server-side — this key can originate calls and read call data.Your workspace is provisioned with a per-tenant SIP edge (<workspace-id>.sip.telequick.dev) and a browser media endpoint (<workspace-id>.webrtc.telequick.dev) automatically.
2

Configure a trunk and a number (for phone calls)

In the voice console at agent.telequick.dev, add an outbound SIP trunk and claim or bring a phone number. Note the trunk id — you pass it as trunkId. Skip this step if you only want the browser agent below.
3

Build an agent

Still in agent.telequick.dev, create a voice agent: pick a speech-to-speech or ASR→LLM→TTS provider, give it a system prompt, and note its id (e.g. appointment-reminder). You reference the agent by id when you originate. See Build a voice agent for the full walkthrough.

Install the SDK

npm install @telequick/sdk
Put your key in the environment so it never lands in source:
export TELEQUICK_CREDENTIALS="sk_live_…"

Path A — an AI agent on a phone call

Originate an outbound call and attach a server-side agent. When the callee answers, the engine wires the audio bridge to your agent automatically — your process never touches the media. This is the whole app.
1

Originate with an agent attached

Pass agent to originate(); the engine attaches the runtime on answer.
2

Wait for connect or failure

The control plane is request/response — poll calls.get() until the call leaves the ringing states.
import { Voice } from "@telequick/sdk/voice";

const v = new Voice({
  baseUrl: "https://engine.telequick.dev",
  apiKey:  process.env.TELEQUICK_CREDENTIALS!,
  orgId:   "org_abc",
});

const call = await v.calls.originate({
  to:      "+15551234567",
  from:    "+15558675309",
  trunkId: "trunk_main",
  agent:   "appointment-reminder",
  ringTimeoutSec: 25,
});

for (;;) {
  const c = await v.calls.get({ sid: call.sid });
  if (c.status === "in_progress") { console.log("agent is live on", call.sid); break; }
  if (c.status === "failed" || c.status === "no_answer") { console.log("ended:", c.status); break; }
  await new Promise((r) => setTimeout(r, 500));
}
The agent drives both legs of the conversation — turn-taking, barge-in, and tool calls all run server-side. Tune that behavior in Turn detection and Tool calling.

Path B — a browser voice agent

No phone number required. Capture the mic in the browser, publish it as encoded Opus, and play the agent’s reply back — media rides QUIC end to end, so there is no WebRTC transport and no SFU in this path. Use a browser-scoped key (minted in the console with browser origin restrictions), never your server key.
1

Originate a browser-legged call

Get a sid from the control plane.
2

Start playback

Create and start() an OpusPlayer for the downlink.
3

Attach as the caller

attachCaller() subscribes downlink and publishes uplink.
4

Capture the mic

captureMicrophone() forwards encoded frames onto the uplink.
import { Voice } from "@telequick/sdk/voice";
import { captureMicrophone, OpusPlayer } from "@telequick/sdk/moqt";

const v = new Voice({
  baseUrl: "https://engine.telequick.dev",
  apiKey:  BROWSER_SCOPED_KEY,
  orgId:   "org_abc",
});

async function talkToAgent() {
  const call = await v.calls.originate({ agent: "web-concierge" });

  const ctx = new AudioContext();
  const player = new OpusPlayer(ctx, { sampleRate: 48000, channels: 1 });
  await player.start();

  const bridge = await v.audioBridge.attachCaller(call.sid, {
    codec: "opus",
    onDownlink: (frame, tsUs) => player.push(tsUs, frame),
  });

  const mic = await captureMicrophone(
    { write: (tsUs, frame) => bridge.publishUplink(frame, tsUs) } as any,
    { audioConstraints: { echoCancellation: true, autoGainControl: true, noiseSuppression: true } },
  );

  return async function hangUp() {
    mic.stop(); player.close();
    await bridge.close();
    await call.hangup();
  };
}
captureMicrophone runs the browser’s own echo-cancellation, gain control, and noise suppression, then diverts the encoded Opus frames onto the uplink track — raw PCM never crosses the wire. This works today in Chromium-based browsers; Safari and UDP-blocked networks fall back to a WebSocket/WebRTC media leg. See Browser compatibility.

Next steps

Build a voice agent

Prompt, providers, and tools for the agent you attached above.

Recipes

End-to-end worked examples: outbound sales, browser agent, human handoff.

Calls API

Full signatures for originate, get, transfer, and hangup.

Outbound telephony

Trunks, numbers, and the dialer behind Path A.