Vocal Bridge

Developer Documentation

Add voice to your app in minutes

Production-ready voice agents with sub-second latency, reliable tool calling, and bidirectional app communication. No infrastructure to manage.

Sub-Second Latency

Real-time voice over WebRTC with optimized STT/TTS pipelines.

Client Actions

Bidirectional: agent drives your UI, app sends events back.

Reliable Tool Calling

Native connectors, MCP servers, HTTP APIs, or 7,000+ apps via Zapier.

Deploy Anywhere

Web, mobile, or phone from a single config.

Live Transcript

Real-time streaming out of the box. Zero setup.

Evals & Analytics

Synthetic Simulation calls, Post evals, recordings, transcripts, and retained evidence.

Quick Start

Integrate in 4 steps

Go from zero to a working voice UI in under an hour.

1

Sign up and create your agent

Create a free account, configure your voice agent with a system prompt, and get a phone number and API key in minutes.

Create account
2

Set up a token endpoint

Your backend proxies a single API call to generate short-lived connection tokens. Keep your API key server-side.

# Your backend endpoint
curl -X POST "https://vocalbridgeai.com/api/v1/token" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"participant_name": "User"}'
3

Install the SDK and connect

Pick your framework, install, and connect in a few lines. Audio, transcripts, and heartbeats are handled automatically.

npm install @vocalbridgeai/sdk
import { VocalBridge } from '@vocalbridgeai/sdk';

const vb = new VocalBridge({
  auth: { tokenUrl: '/api/voice-token' },
  participantName: 'User',
});

// Live transcript streaming
vb.on('transcript', ({ role, text }) => {
  console.log(`[${role}] ${text}`);
});

// Handle agent-triggered actions
vb.on('agentAction', ({ action, payload }) => {
  handleAction(action, payload);
});

await vb.connect();
// Mic is live. Agent audio plays automatically.
npm install @vocalbridgeai/react
import { VocalBridgeProvider, useVocalBridge, useTranscript }
  from '@vocalbridgeai/react';

function App() {
  return (
    <VocalBridgeProvider
      auth={{ tokenUrl: '/api/voice-token' }}
      participantName="User">
      <VoiceUI />
    </VocalBridgeProvider>
  );
}

function VoiceUI() {
  const { state, connect, disconnect } = useVocalBridge();
  const { transcript } = useTranscript();

  return (
    <div>
      <button onClick={state === 'connected' ? disconnect : connect}>
        {state === 'connected' ? 'End Call' : 'Start Voice Chat'}
      </button>
      {transcript.map((e, i) => (
        <p key={i}><b>{e.role}:</b> {e.text}</p>
      ))}
    </div>
  );
}
# Xcode package dependencies
https://github.com/vocalbridgeai/sdk.git
product: VocalBridge
branch: main
commit Package.resolved

Fetch short-lived voice tokens from an authenticated backend route; do not embed API keys in production iOS apps.

import VocalBridge

let vb = VocalBridge(options: .init(
  auth: .tokenURL(URL(string: "https://example.com/api/voice-token")!),
  participantName: "User",
  debug: true
))

let subscription = vb.onEvent { event in
  switch event {
  case .transcript(let entry):
    print("[\(entry.role.rawValue)] \(entry.text)")
  case .agentAction(let action):
    print("Action:", action.action, action.payload)
  default:
    break
  }
}

try await vb.connect()
try await vb.sendAction("user_clicked_buy", payload: ["productId": "123"])
try await vb.toggleMicrophone()
await vb.disconnect()

subscription.cancel()
4

Iterate with the CLI

Use the Vocal Bridge CLI to review call logs, save candidate versions, and deploy them independently across environments. See Versions & Environments for CLI and API examples.

# Install
pip install vocal-bridge

# Authenticate
vb auth login

# Review call logs and transcripts
vb logs

# Save a candidate without changing production (prepare candidate.json first)
vb agent version save --config-file candidate.json --label candidate
vb agent version deploy candidate --environment staging

# Evaluate a call against an objective (Pilot only)
vb eval <session_id> --objective "Schedule a meeting"

# View full integration docs
vb docs

Key Feature

Client Actions: voice meets your UI

Bidirectional communication between your voice agent and your app. The agent can drive your UI, and your app can notify the agent.

Agent → App

The agent triggers actions in your UI during conversation.

vb.on('agentAction', ({ action, payload }) => {
  if (action === 'show_product') {
    showProductCard(payload.productId);
  }
  if (action === 'navigate') {
    router.push(payload.path);
  }
});

App → Agent

Your app sends events to the agent to keep it in context.

// User clicked a buy button in your UI
await vb.sendAction('user_clicked_buy', {
  productId: '123',
  quantity: 2
});
// Agent responds: "Great choice!"

Agent → App

Handle agent-triggered actions with a hook.

import { useAgentActions } from '@vocalbridgeai/react';

function VoiceUI() {
  useAgentActions((action, payload) => {
    if (action === 'show_product') {
      showProductCard(payload.productId);
    }
    if (action === 'navigate') {
      router.push(payload.path);
    }
  });
  // ...
}

App → Agent

Send events to the agent from any component.

import { useVocalBridge } from '@vocalbridgeai/react';

function BuyButton({ productId }) {
  const { sendAction } = useVocalBridge();

  return (
    <button onClick={() =>
      sendAction('user_clicked_buy', {
        productId, quantity: 1
      })
    }>Buy Now</button>
  );
}
// Agent responds: "Great choice!"

Configure client actions from the dashboard or via vb config set --client-actions-file actions.json. Each action has a name, description, and direction. See the full developer guide for the complete reference.

Bring Your Own Agent

AI Agent Integration

Already have a chatbot, RAG system, or LLM agent? Give it a voice. Vocal Bridge handles the real-time voice layer while your existing agent handles domain logic.

  • Voice agent delegates domain questions to your agent
  • Async — voice agent chats naturally while your agent processes
  • Adaptive or verbatim response modes
  • Use a hosted HTTPS endpoint or client data channel
  • Test voice handoffs with a Haiku simulated AI Agent
import { VocalBridge } from '@vocalbridgeai/sdk';

const vb = new VocalBridge({
  auth: { tokenUrl: '/api/voice-token' },
});

// One callback — SDK handles the rest
vb.onAIAgentQuery(async (query) => {
  // Forward to your existing agent
  const answer = await yourAgent.ask(query);
  return answer; // spoken back to the user
});

await vb.connect();
import { useAIAgent } from '@vocalbridgeai/react';

function MyApp() {
  // One hook — queries are forwarded automatically
  useAIAgent({
    onQuery: async (query) => {
      const answer = await yourAgent.ask(query);
      return answer; // spoken back to the user
    },
  });

  return <VoiceUI />;
}

How it works: User speaks → voice agent determines domain question → calls your hosted endpoint or sends query_agent via data channel → your agent answers → response is spoken back. Use the full dashboard Test tab to hear this flow with Haiku standing in for your agent.

Passive Observer Mode

Listener Mode

A Vocal Bridge agent that never speaks. It joins a session, transcribes multi-speaker audio with speaker diarization, and streams real-time coaching suggestions to your app via the data channel.

  • Live transcript with speaker labels, streamed as the conversation unfolds
  • Coaching suggestions in Markdown when your prompt's policy matches the latest turn
  • Inferred speaker map — raw IDs upgraded to names and roles as the session progresses
  • Use cases: live IR coaching, sales-call assists, support-call escalation, interview prompts
  • Create with vb agent create --style Listener or pick "Listener" in the dashboard
import { VocalBridge } from '@vocalbridgeai/sdk';

const vb = new VocalBridge({
  auth: { tokenUrl: '/api/voice-token' },
});

vb.on('agentAction', ({ action, payload }) => {
  switch (action) {
    case 'live_transcript': {
      const { speaker_id, text, is_final } = payload;
      if (is_final) appendFinal(speaker_id, text);
      else updateInterim(text);
      break;
    }
    case 'coaching_suggestion':
      // payload.guidance is Markdown — render with any renderer.
      renderCoachingCard(payload);
      break;
    case 'speaker_map_update':
      // payload.mapping = { S0: {name, org, role, confidence}, ... }
      refreshSpeakerLabels(payload.mapping);
      break;
  }
});

await vb.connect();
import { useAgentActions } from '@vocalbridgeai/react';

function ListenerUI() {
  useAgentActions((action, payload) => {
    if (action === 'live_transcript') {
      const { speaker_id, text, is_final } = payload;
      if (is_final) appendFinal(speaker_id, text);
      else updateInterim(text);
    } else if (action === 'coaching_suggestion') {
      renderCoachingCard(payload);
    } else if (action === 'speaker_map_update') {
      refreshSpeakerLabels(payload.mapping);
    }
  });

  return <YourTranscriptAndCoachingPanels />;
}

Your custom_prompt drives both when coaching fires and what it says. See the full developer guide for the complete action schemas, prompt design patterns, and how to ground coaching in your own data via MCP.

Developer Tools

SDKs, CLI, and plugins

JavaScript SDK

npm install @vocalbridgeai/sdk

Connect, stream transcripts, send/receive client actions, and manage audio. Works in any JS environment.

React SDK

npm install @vocalbridgeai/react

React hooks and Provider. useVocalBridge(), useTranscript(), and useAgentActions() for idiomatic React.

iOS SDK

VocalBridge

Swift package for native iOS apps: token auth, connection lifecycle, microphone controls, transcripts, and client actions.

CLI

pip install vocal-bridge

Manage agents, review call logs, download recordings, update prompts, and access the full developer docs with vb docs — all from your terminal.

Claude Code Plugin

Native slash commands inside Claude Code. Manage your agent, stream debug events, and update configs without leaving your AI assistant.

# Claude Code
/plugin marketplace add vocalbridgeai/vocal-bridge-marketplace
/plugin install vocal-bridge@vocal-bridge

# Or via npx
npx skills add vocalbridgeai/vocal-bridge-claude-plugin

Also supports Flutter/Dart and Kotlin (Android) via WebRTC SDKs. See the full developer guide for platform-specific instructions.

Agent Versions and Environments

Save version does not deploy. Saving updates the editable configuration and records an immutable snapshot. Deploy selects a saved version for one named environment, without changing the editable configuration or other environments. Keep production on v1 while staging tests v2, then promote the same tested version. Vocal Bridge manages platform updates; you manage your agents through the dashboard, CLI, or API. Existing agents keep working without any setup changes.

In the dashboard, choose Save version and review the diff against the latest saved version. In Versions, choose Deploy, select the environment, and review its currently deployed version versus the candidate. Select the deployed environment in the test panel. To stop one environment without deleting saved versions, choose Undeploy beside it and review the impact.

Deployment previews are bound to the reviewed target. Changing the environment or display name requires a new diff review, even while a previous request is loading. Closing and reopening the dialog discards that review. Confirmation submits the reviewed agent, immutable version, environment, display name, and expected current deployment; target inputs stay locked during deployment. API clients must retain the same environment and display name between preview and deploy. The CLI retains its selected target while previewing and confirming.

Environment names and connector ownership

Changing the dashboard environment slug loads that target's existing friendly name, including a custom production name. A new target starts with a blank optional name so the server derives it from the slug. Select the slug before entering a rename. CLI/API clients can omit --display-name / display_name to preserve an existing name or derive a new one; an explicit name intentionally renames that environment.

The public deploy-preview API accepts display_name and returns the effective post-deploy label in environment.display_name, without creating or renaming an environment. Send the same target payload to preview and deploy. Omitted, null, or empty-string display names preserve an existing name or derive a new one; invalid display names are rejected during preview as well as deployment. Environment metadata is separate from the immutable agent configuration, so a label-only rename can have zero configuration changes in the diff.

Echo top-level preview expected_display_name unchanged to deploy, including null for a new environment, alongside expected_deployed_version_id. It contains the stored name before the proposed rename; concurrent same-version renames return 409. Omission retains older clients' version-only guard. Dashboard and CLI send both fields automatically.

Connector ownership transfer: connected accounts move with the agent, and the recipient gains control of those connections. Authorization attempts that were not completed before transfer must be restarted by the recipient. Disconnect before transfer if a connected account must not move.

Existing connection grants, scopes, provider account identity, snapshots, and deployments are preserved. Operations already accepted by an external provider may finish; transfer does not cancel remote requests or transfer ownership of the external account. Revocation affects every environment sharing that connection.

Credential safety and ownership hand-off

API keys are revoked on ownership transfer. Existing agent-scoped keys stop authorizing new requests after the transfer completes. The recipient must mint fresh keys and update integrations/CLI login. Untransferred agents, account keys, saves/deploys/rollbacks, and same-owner updates keep their keys. Failed transfers roll back revocation; already-issued connection tokens and active calls are not cancelled.

The former owner remains an Admin collaborator, preserving the established contract. Transfer changes ownership and billing; it is not a clean access hand-off. The recipient must remove that access separately and review other collaborators, shared links, and external OAuth grants.

Creation and transfer share the same logical-agent limit (plan plus partner agent slots), separate from phone-environment capacity. Versions and environments remain one logical agent. If concurrent requests compete for the final slot, one returns 403 without creating or transferring an agent. Pending and failed non-deleted agents count; deleted agents do not. Existing over-limit agents and deployed versions remain unchanged.

Exports and save/deploy diffs redact recognized credential fields, including bot_token, provider_token, and X-Auth-Token. The CLI also masks known secret paths and escapes terminal controls. Keep free-text labels/prompts free of secrets and exports private.

Keep exported configuration private. Redaction does not remove secrets from older downloads or revoke credentials. Rotate any exposed credentials, then save and deploy a new configuration; version history is immutable.

Trusted token proxies

POST /api/v1/token requires an API key. Its optional environment is a trusted server-side selector, not an anonymous-browser authorization boundary. Customer token proxies must authorize callers, allowlist input fields, and set a fixed server-owned environment; never forward untrusted JSON wholesale. Public shared links stay production-only. Use separate agents/accounts for separate access boundaries.

Version requests are rate limited. Handle 429 with backoff and obtain fresh state before retrying; preview endpoints are not intended for bulk export.

Existing deployed agents keep their current connections and running calls. Saving a candidate does not revoke credentials or redeploy production. Use separate agents and sandbox credentials when test calls need independent external access.

Ownership transfer and outbound consent

Outbound consent does not transfer. An ownership change removes the logical agent's prior consent across all environments. The recipient must explicitly accept the Outbound Calling Terms of Use before starting new outbound calls. Restoring or deploying an older version cannot restore consent.

In the dashboard, accept the outbound terms and Save version. CLI users can run vb agent version save --config-file outbound-candidate.json --accept-outbound-tos. Public API clients send outbound_tos_accepted: true to POST /api/v1/agent/versions. Saving acceptance does not deploy. If the deployed version already enables outbound calling, new calls can resume after acceptance, subject to the recipient's existing usage limits and entitlements. --yes alone is not consent.

Untransferred agents and same-owner updates retain their acceptance. Transfer does not change snapshots, deployment pointers, phone resources, or inbound/web availability, and does not terminate already-admitted calls. A failed transfer rolls back the consent reset along with ownership.

Owner consent and agent capacity

Only the current owner can accept new outbound terms. Edit/Admin collaborators, including a former owner retained as Admin, cannot record outbound_tos_accepted: true on the owner's behalf: fresh attempts return 403 before saving. This restriction also applies if ownership changes during the request. Existing owner consent remains valid: older dashboards echoing true can keep editing, without replacing the first acceptance timestamp. Ordinary collaborator saves without new acceptance remain supported. Legacy API/classic edits enforce the same ownership checks. Consent is shared agent policy, not version configuration.

Creation and transfer share the same logical-agent limit (plan plus partner agent slots), separate from phone-environment capacity. Versions and environments remain one logical agent. If concurrent requests compete for the final slot, one returns 403 without creating or transferring an agent. Pending and failed non-deleted agents count; deleted agents do not. Existing over-limit agents and deployed versions remain unchanged.

Outbound allowance when saving

Saving a version that newly enables outbound calling requires the current owner's plan or a partner outbound grant, even for a web-only candidate. Telephony access and accepted terms do not grant outbound access.

The dashboard and public version API return a client error when that allowance is missing. Denied saves do not record consent, change the draft, create a version, or deploy.

Existing outbound-enabled configurations can still be saved or edited after a downgrade; disabling outbound does not require outbound entitlement. New calls remain subject to runtime entitlements and usage limits. Restoring an older snapshot cannot bypass the check when it newly enables outbound.

Explicit version deployment of a phone/both snapshot with outbound enabled rechecks the current owner's outbound plan/grant and accepted terms. Both version-deploy APIs return 403 before provisioning when either is missing. Save owner consent first, or save and deploy a version with outbound disabled. Existing deployments, inbound/web availability, and legacy save/redeploy contracts are unchanged; runtime call gates still apply.

Backward compatibility: existing agents receive v1 in production. Legacy PATCH /api/v1/agent, vb prompt set/edit, and vb config set/edit still save and deploy to production. Do not use them to prepare a staged-only candidate. Existing token clients still default to production; agent identity and API keys stay the same.

Safe saves and bounded environments

Legacy updates still save and deploy, but now return 409 Conflict if another editor saves after the source draft was read. Refresh and review before retrying; the newer draft and live production stay intact. This also applies when restoring production phone resources.

With Save version or vb agent version save, explicit outbound consent and the version save succeed together. If acceptance cannot be recorded, the version is not saved and your existing configuration stays unchanged. The first acceptance timestamp is preserved; saving an unchanged configuration can record consent without a duplicate version. Preview never records consent. Legacy save-and-deploy may retain accepted consent even if deployment fails.

Each agent can have 50 environments total, including production, independently of the owner-wide phone quota. Web-only, failed, inactive, and pending environments all count. Reuse stable names such as qa or staging; avoid a new slug for every build. A new environment beyond the cap returns 403 before allocation. Existing deployments, including installations already above the cap, remain available and can be redeployed. Undeploy releases one environment's runtime resources but keeps its record, deployment audit, and saved versions.

Version descriptions reject terminal controls, including ANSI/OSC escapes; printable Unicode, newline, and tab remain supported. The CLI escapes controls in older stored notes. Deployment display_name must be a string or null, with at most 100 printable characters. Invalid metadata returns a client error, not a server error.

CLI: save, test, promote, roll back

Requires CLI 0.27.0+. Authenticate with vb auth login; select an agent with vb agent use AGENT_UUID for account keys. VOCAL_BRIDGE_API_URL chooses the Vocal Bridge API endpoint; --environment chooses a deployment within your agent. Changing environments does not require changing your API endpoint.

Create candidate.json with your changes. This web-only example avoids provisioning a test phone number:

{
  "greeting": "Hello from the release candidate.",
  "custom_prompt": "You are a helpful support assistant.",
  "deploy_targets": "web"
}
vb agent version list
vb agent environment list
vb agent version save --config-file candidate.json --label rc-2 --description "Ready for QA"
	vb agent version diff 1 rc-2
	vb agent version show rc-2 --json
	vb agent version restore 1 --label restored-v1
	vb agent version deploy rc-2 --environment staging --display-name Staging

# After QA: use the actual immutable version number from save/list.
vb agent version label rc-2 approved --description "QA passed"
vb agent version deploy 2 --environment production

# Roll back production; staging and version history are unchanged.
vb agent version deploy 1 --environment production

# Stop staging without deleting versions or changing production.
vb agent environment undeploy staging

Save/deploy/undeploy preview the change and require confirmation. Without a terminal, supply --yes. --json suppresses the printed preview and returns only the final response; it does not bypass confirmation. There is no CLI --dry-run: cancel the preview or use the preview API. A no-change save may reuse the latest version (created: false); use the returned ID.

Every version and environment command supports --json. versions/environments are aliases. Use vb agent version restore REF to preview and save an older snapshot as a new immutable version without deploying it. Omit the label in vb agent version label REF to clear it. Omit --config-file to snapshot the saved editable configuration, not unsaved browser changes. Deploy defaults to production if the environment is omitted; undeploy requires an explicit environment.

In the dashboard, Versions → View displays a historical snapshot (edit access required; view-only collaborators see the history, not each version's configuration) and Open as editable draft loads it into the editor. Saving creates a new version and leaves every environment unchanged. Overview and Versions pair each active phone number with its deployed immutable version and environment.

When first enabling outbound calling in a phone-enabled candidate, use vb agent version save --config-file outbound-candidate.json --accept-outbound-tos to accept the Outbound Calling Terms of Use. This saves only; deploy separately. API clients send outbound_tos_accepted: true in the save body. --yes alone does not accept outbound terms.

CI/CD: retain an approved immutable UUID and run vb agent version deploy VERSION_UUID --environment production --yes --json after your approval step. Labels can change; UUIDs and version numbers cannot. A nonzero exit needs inspection before retry.

API reference

Call https://vocalbridgeai.com/api/v1 from your backend with X-API-Key and JSON Content-Type. Account keys also require X-Agent-Id: AGENT_UUID; agent-scoped keys do not. REF accepts a UUID, version number, or case-insensitive label; URL-encode path references.

Method / endpointRequest and response
GET /api/v1/agent/versionsversions, environments, and latest 50 deployments audit entries.
POST /api/v1/agent/versions/previewconfig, optional full_snapshot/source_version_idbase_version, next_version_number, changes, summary. No mutation.
POST /api/v1/agent/versionsSame config fields plus optional label, description, expected_latest_version_id, outbound_tos_acceptedversion, changes, summary, created, deployed: false.
POST /api/v1/agent/versions/diff{"from":"1","to":"rc-2"}from_version, to_version, changes, summary.
GET /api/v1/agent/versions/REFversion with redacted config.
PATCH /api/v1/agent/versions/REFlabel and/or description → updated metadata. Null clears; omitted fields stay unchanged.
POST /api/v1/agent/versions/REF/deploy-previewenvironment, optional display_nameenvironment with the effective post-deploy label, stored expected_display_name, from_version, to_version, changes, summary. No mutation.
POST /api/v1/agent/versions/REF/deployenvironment, optional display_name, expected_deployed_version_id, expected_display_nameversion, environment, deployment, changes, summary.
POST /api/v1/agent/environments/ENVIRONMENT/undeploy-previewNo body → current environment/version, resource and sharing impact, changes, and expected_deployed_version_id, expected_deployment_status, expected_updated_at. On an inactive or failed environment with retained resources it previews cleanup with a null version expectation. needs_operator_reconciliation marks retained capacity that no retry can release; contact support instead of retrying. No mutation.
POST /api/v1/agent/environments/ENVIRONMENT/undeployEcho all three preview expectations → inactive environment, undeploy audit, prior version, and cleanup_pending. Only the agent owner can undeploy an environment whose preview reports phone_will_be_released or telephony_reservation_will_be_stranded; an Admin collaborator gets 403. API keys are issued only for agents you own.

Public version operations return HTTP 200 on success. Version summaries include id, version_number, label, description, source, and creator/timestamp metadata. Changes contain path, kind (added/removed/changed), before, and after; summary.change_count counts changes.

Use these documented /api/v1 routes for CLI and external automation. Dashboard access follows the agent's existing collaborator permissions; test-only collaborators can select active environments but cannot read full version configurations.

Version history defaults to 50 rows per page. Use API limit (1–100) and before_version, or CLI --limit and --before-version. Follow pagination.next_before_version until null. The dashboard has Older versions / Newer versions controls. Deployed summaries remain visible on every page; old versions are not pruned.

Preview before every write

  1. Send the candidate config to POST /api/v1/agent/versions/preview. Review the diff against the latest saved version.
  2. Send the same config to POST /api/v1/agent/versions with expected_latest_version_id set to the preview's base_version.id. Retain the returned version.id.
  3. Send {"environment":"staging","display_name":"Staging"} to that immutable version's /deploy-preview. Review the diff against the version deployed to staging and its effective post-deploy label.
  4. Send the same environment and display name to /deploy with expected_deployed_version_id from the preview's environment.deployed_version_id. For a new environment, send explicit null; omitting the field skips the preview-to-deploy comparison.

If a label was previewed, deploy its returned to_version.id so relabeling cannot change the approved target. Existing agents have a baseline v1. If state changes after preview, the write is rejected so you can review a fresh diff.

{
  "environment": "staging",
  "display_name": "Staging",
  "expected_deployed_version_id": null
}

The null above is for a new environment only; for an existing deployment use the ID from its preview. On 409 Conflict, inspect state, wait for any in-progress deployment, and obtain a fresh preview and approval. Do not silently retry or remove the expectation.

Undeploy has a separate read-only preview. Echo its expected_deployed_version_id, expected_deployment_status, and expected_updated_at to confirmation. It deactivates the selected environment before retiring phone/routing resources, so new sessions fail closed even if cleanup must be retried. For phone and both targets, redeploy may provision a different phone number because a retired number is not guaranteed to be available again. If cleanup_pending is true, run the same preview-and-confirm flow again; inactive or failed cleanup previews return a null version expectation, and retrying an inactive environment does not create another undeploy audit. Only the agent owner can undeploy an environment that releases its phone number, or one whose preview reports telephony_reservation_will_be_stranded: an Admin collaborator receives 403 and the dashboard control is disabled with that reason, because both outcomes are irreversible and spend capacity from the owner's telephony quota. The second flag marks an undeploy that cannot prove the reserved telephony slot is unused, so the slot stays held until support reconciles it and no cleanup retry can release it. An Admin can still undeploy a web-only environment. Versions, other environments, collaborator access, and sharing settings remain unchanged. Undeploying production stops new public talk-link sessions until production is deployed again; configuration-share links remain available.

Test a deployed version through the API or SDK

curl --fail-with-body -X POST "https://vocalbridgeai.com/api/v1/token" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "X-Agent-Environment: staging" \
  -H "Content-Type: application/json" \
  -d '{"participant_name":"QA tester","environment":"staging"}'

Add X-Agent-Id for account keys. The response includes environment, version_id, and version_number alongside the usual token fields. Your SDK still consumes the normal token response; no SDK environment flag is required. Authorize environment selection in your backend and keep keys server-side.

Missing/inactive named environments fail instead of falling back to production. Omitting environment keeps the production default. This selector applies to web-token calls; do not assume outbound-call APIs accept it.

Integration guides and debug access

Agent-specific integration guides describe the version deployed to production, not the saved draft. Dashboard copy/preview and vb docs / GET /api/v1/docs follow the same contract. Deploy to production and refresh the guide after changing modes, tools, or client actions. Account-key docs without a selected agent remain generic. Guides do not select a named environment, even when the tester is set to staging; inspect that environment's deployed snapshot separately.

vb debug and vb debug --poll use production's deployed debug_mode. Saving an enablement or disablement does not change access until deployment. Existing owner/admin and API-key permissions still apply. Debug streams and stored events remain agent-wide rather than environment-specific.

If production is inactive or unavailable, guide and debug requests fail without exposing the saved draft. Reading these guides does not change versions, deployments, phone resources, keys, or billing.

Request types and routing safety

  • full_snapshot and outbound_tos_accepted must be JSON booleans, not strings, numbers, or null. Omission defaults to false. "full_snapshot": false preserves partial model-setting merges; "full_snapshot": "false" is rejected. Only explicit true records new outbound consent; previously accepted consent remains valid. CLI flags already send booleans. Invalid flag types are rejected before saving or recording consent.
  • Version descriptions must be a string or null, at most 2,000 characters after trimming. Empty/whitespace/null clears a description; omission on metadata PATCH preserves it. Invalid types return a client error.
  • Environment names do not change call direction or grant access to a feature. Existing production connections, active calls, and historical call records remain valid. Issued tokens are not cryptographically revoked, but a token that has not started a session cannot enter an inactive environment; redeploy it before testing new sessions.
  • Updating or rolling back an existing phone-enabled environment reuses its phone resources when available. A failed update does not silently detach the existing number or allocate a replacement number solely for a configuration change.

Config exports, labels, and deployment limits

  • Raw JSON is a partial update over the editable configuration. Use custom_prompt / mode, not legacy prompt / style. Omitted fields stay unchanged. Partial model_settings groups merge; other supplied fields and arrays replace their old values.
  • Restore directly with vb agent version restore 1 --label restored-v1. Direct API clients first fetch GET /api/v1/agent/versions/REF, then send the complete returned version.config, full_snapshot: true, and source_version_id: version.id to both preview and save, with the preview's base version as expected_latest_version_id. This replaces model settings, restores redacted credentials from the selected snapshot, creates a new immutable version, and never deploys automatically.
  • Keep __VB_SECRET_KEPT__ placeholders intact. Diffs redact secrets, but prompts/config exports can still contain sensitive business information. Protect exported files and review artifacts.
  • Custom API-tool URLs (api_tools[].url) are fully redacted in CLI/API-key exports, all dashboard historical-version reads, and every version/deployment diff, including older stored audits. This covers userinfo, arbitrary query credentials, and opaque path tokens, even on ordinary endpoint URLs. Preserve each tool's stable id (or name for older snapshots): reordered tools restore their own URL from source_version_id; an explicit replacement URL is honored. Live execution, stored snapshots, and access to the current editable configuration are unchanged. Previously downloaded artifacts are not retroactively redacted; rotate any credentials exposed in them.
  • Labels are unique per agent, case-insensitive, 1–120 printable characters; numbers and UUID-shaped labels are reserved. Empty/null clears a label. Descriptions allow at most 2,000 characters.
  • Environments normalize to lowercase with spaces replaced by hyphens, matching [a-z0-9][a-z0-9_-]{0,62}. Friendly display_name allows 100 characters. First deploy creates the environment; preview does not.
  • Snapshots include behavior, tools, and deployment targets, not ownership, billing, collaboration, OAuth grants, or provisioned phone resources. Phone-enabled environments can provision separate numbers and consume telephony capacity; entitlements, quotas, and outbound terms still apply.
  • Environments are not permission boundaries. Labels/notes do not enforce approval gates. This release does not add traffic splitting, scheduled promotion, or environment-specific RBAC.

Billing, usage limits, and isolation

Versions share one logical agent and owner account. Saving and labeling do not consume agent slots, provision phones, or create billable calls. Test calls are real usage, including web-only QA calls. Production, staging, shared links, and collaborator calls use the owner's allowance.

  • Voice minutes, outbound/evaluation limits, partner credits, and usage alerts remain owner-wide. Versions do not reset or clone allowances. Existing billing rules continue to apply; no separate environment subscription or test-call discount is created.
  • Phone-enabled environments across all of an owner's agents share min(plan agent limit + partner agent slots, 50) reservations. Production and staging phones use two slots; redeploying the same environment reuses one. Legacy phone creation/retry uses the same pool. Web-only environments reserve no phone slot, but calls still use minutes.
  • Failed provisioning/cleanup retains capacity while resources remain. Deploying a web-only version releases a phone slot only after cleanup succeeds. Agent deletion covers all environments. Inspect vb agent environment list or GET /api/v1/agent/versions; the billing page counts logical agents, not phone reservations.
  • If a phone deployment times out and its outcome cannot be confirmed, phone capacity remains reserved and redeployment, transfer, or deletion may be blocked until reconciliation. Inspect version history and environment status, then contact Vocal Bridge support if reconciliation is required. Do not repeatedly create replacement agents. Your previously deployed version remains selected until a deployment succeeds.
  • After an explicit web-only deployment retires production's phone resources, legacy PATCH or vb config set --deploy-targets phone (or both) provisions the missing phone/dispatch before publishing production. Current owner entitlement and shared phone capacity, including partner slots, apply; denial returns 403. A retired number is not guaranteed to return. Existing phone resources are reused when present; named environments are unchanged. A failed deployment can leave the new snapshot saved while production stays on its prior version; inspect history before retrying after a timeout. Concurrent changes require refresh/retry. Ordinary edits to an already complete phone deployment do not buy another number.
  • Current owner/current plan entitlements apply, including after downgrade. Old snapshots cannot restore paid features. Downgrade does not automatically delete environments, and usage gates do not terminate calls already in progress.
  • Ownership transfer moves all phone reservations with the agent. The recipient needs enough unused phone capacity and telephony entitlement. Insufficient capacity or an in-progress deployment leaves ownership, keys, and collaborators unchanged. Web-only transfers need no phone capacity.
  • Treat room names as opaque. Named environments are isolated from one another even when a session_id is reused. Version changes do not disconnect active calls. Issued tokens are not cryptographically revoked, but admission rejects new sessions for inactive environments.
  • Environments are not security boundaries. Agent keys, collaborator permissions, native OAuth connections/revocations, and billing are shared. Staging tools can affect production data in the same external account. Use separate agents/accounts and sandbox credentials for isolation.
  • Sharing and collaborator settings belong to the logical agent, not a version. Saving, deploying, rolling back, or undeploying does not copy, reset, or version those settings. Public talk links remain production-only; undeploying production stops new talk-link sessions until production is deployed again. Configuration-share links show the current editable configuration rather than a named environment snapshot, and remain valid until disabled or regenerated. Existing calls retain their admitted version; deployment selects the version for subsequent sessions.
  • Live tester AI simulation and app actions follow the selected deployed snapshot; the outbound launcher follows production. Saved-only configuration tests still use the draft.
  • Use environment undeploy to stop one environment while keeping the agent and immutable history. It makes new sessions fail closed before retiring that environment's phone/routing resources; cleanup failures retain retry state and capacity. Other environments keep running. Use the normal agent-deletion workflow only to remove the whole agent across all environments. If a deployment is in progress, wait for completion and retry. If ownership changes while deletion or undeploy is pending, refresh and retry under the current owner; undeploy requires a fresh preview.
  • Rollback changes the version used by that environment; it does not undo emails, CRM writes, charges, or other external side effects, nor restore revoked credentials. Protect exports/diffs and never put secrets in labels or prompts. Read the full billing and capacity guidance in vb docs or GET /api/v1/docs.

Errors and recovery

400: invalid config, label/reference, environment, or missing outbound acceptance. 401/403: credentials, access, or deployment entitlement/capacity. 404: agent/version lookup failed. 409: stale preview or concurrent deployment. 429: rate limit; back off, then refresh the preview. Dashboard schema validation can return 422.

For 500 or network timeouts, inspect GET /api/v1/agent/versions, environment status, and deployment history before retrying. An error response is not proof that external resources were unchanged. Read the JSON detail for the specific failure.

Get the full copyable backend workflow and integration reference with vb docs or GET /api/v1/docs.

Need the complete reference?

The full developer guide covers API reference, authentication details, all SDK methods, AI Agent mode, native connectors, MCP tools, post-processing, and more.

$ vb docs

Start building with voice today

Create your free account, deploy an agent, and integrate it into your app. No credit card required.