Developer Portal

Build on Vocanta in five minutes.

Streaming agent-chat over WebSockets with first-class SDKs in Python and TypeScript. Browse the OpenAPI 3.1 spec, the public MCP tool catalog, and copy-paste a working example below.

WebSocket-firstOpenAPI 3.1MCP 2025-11-25

Live status

Quick start

Install the SDK for your language, set VOCANTA_API_KEY, and stream a turn. Each example uses the production WebSocket endpoint.

1. Install

$pip install vocanta

2. Stream a turn

import asyncio
from vocanta import VocantaClient

async def main() -> None:
    async with VocantaClient(api_key="voc_...") as client:
        async with client.agent_chat.stream(
            business_id="biz_123",
            conversation_id="conv_abc",
            messages=[{"role": "user", "content": "Hola"}],
        ) as stream:
            async for frame in stream:
                if frame.event == "response.delta":
                    print(frame.data["text"], end="", flush=True)
                elif frame.event == "response.done":
                    break

asyncio.run(main())

Regions

Pin to a region for compliance (BAA / GDPR), or pass region="auto" to let the SDK probe latency and pick the closest healthy peer.

SDK resources

Codegen-driven resource classes (RTD1) -- one per curated OpenAPI tag. Adding a tag to scripts/codegen_sdk_resources.py regenerates Python + TypeScript classes mechanically. 16 resources / 236 operations today.

15 resources · generated from openapi/vocanta-public.json

  • client.patients

    PatientsResource

    Patient CRUD + appointment listing.

    Verticals: dental, medical, telemedicine

  • client.appointments

    AppointmentsResource

    Schedule, reschedule, list, cancel appointments.

    Verticals: dental, medical, hospitality, real_estate

  • client.doctor_portal

    DoctorPortalResource

    Doctor-facing dashboard endpoints.

    Verticals: dental, medical

  • client.patient_portal

    PatientPortalResource

    Patient self-service endpoints.

    Verticals: dental, medical, telemedicine

  • client.telemedicine

    TelemedicineResource

    Telemedicine session lifecycle endpoints.

    Verticals: medical, telemedicine

  • client.medical_history

    MedicalHistoryResource

    Patient medical history record CRUD.

    Verticals: dental, medical

  • client.tickets

    TicketsResource

    Customer-support ticket lifecycle.

    Verticals: all verticals

  • client.alerts

    AlertsResource

    Per-tenant alert subscriptions + delivery.

    Verticals: all verticals

  • client.conversations

    ConversationsResource

    Read + manage agent-chat conversation records.

    Verticals: all verticals

  • client.knowledge_base

    KnowledgeBaseResource

    Tenant knowledge-base document CRUD.

    Verticals: all verticals

  • client.canned_responses

    CannedResponsesResource

    Pre-canned reply templates.

    Verticals: all verticals

  • client.workflows

    WorkflowsResource

    Workflow definitions + executions.

    Verticals: all verticals

  • client.custom_integrations

    CustomIntegrationsResource

    Per-tenant custom integration registration.

    Verticals: all verticals

  • client.audit_logs

    AuditLogsResource

    Per-tenant audit-log access (admin only).

    Verticals: all verticals

  • client.users

    UsersResource

    User CRUD + role management.

    Verticals: all verticals

Each resource exposes one async method per matching OpenAPI operation. Method names derive from the spec's operationId. See scripts/codegen_sdk_resources.py for the curated allowlist.

Vertical helpers

Vertical-aware shortcut classes (RTD2): client.dental, client.medical, client.insurance, client.hospitality. Each helper wraps the generic resources with vertical-specific defaults and emits a structured warning on cross-vertical mismatch.

4 verticals · vertical-conflict warning fires when tenant vertical doesn't match

  • client.dental

    dental

    DentalHelpers

    • book_cleaning
    • book_consultation
    • submit_insurance_claim
    • get_treatment_history

    Defaults: cleaning=30min, consultation=60min, root_canal=90min

  • client.medical

    medical

    MedicalHelpers

    • book_consultation
    • start_telemedicine_session
    • record_vitals
    • prescribe_medication

    Defaults: consultation=30min, telemedicine recording=OFF (HIPAA-safe)

  • client.insurance

    insurance

    InsuranceHelpers

    • verify_coverage
    • submit_claim
    • check_claim_status

    Defaults: kind=insurance_coverage_verification, kind=insurance_claim_submission

  • client.hospitality

    hospitality

    HospitalityHelpers

    • book_reservation
    • check_in
    • check_out
    • assign_room

    Defaults: check-in=15:00, check-out=11:00 (industry standard)

Cross-vertical calls (e.g. client.dental.book_cleaning against a medical tenant) emit a VocantaVerticalMismatchWarning. Strict mode opt-in: warnings.simplefilter("error", VocantaVerticalMismatchWarning).

Voice helpers

Voice-mode SDK (RTD3) mounted at client.voice. Outbound calls, inbound event subscription, real-time audio streaming, recording playback URLs, and voice-quality probes -- all with privacy-first defaults (recording TTL upper-bounded to 1 hour, audio payloads never logged, test_mode tri-state).

client.voice · 12 public methods · privacy-first defaults

Privacy & safety contract

  • test_mode is tri-state: undefined uses tenant config, true bills to test account, false forces production. Default is never true.
  • Recording URLs are TTL-bounded to <= 1800s (30 min, RTD3-FOLLOWUP-C). Default is 300s (5 min). Above-max raises immediately at the SDK boundary.
  • Audio streams never log PCM bytes / base64 payloads / transcripts. Architecture ratchet enforces.
  • Provider failover (Twilio → Vonage → Plivo) emits VocantaVoiceProviderFailoverWarning with opaque IDs only. Strict mode opt-in: warnings.simplefilter("error", VocantaVoiceProviderFailoverWarning).
  • Outbound

    Trigger and manage outbound calls. test_mode is tri-state: undefined / true / false (default undefined uses tenant config).

    • start_outbound_call · startOutboundCall

      Trigger a call to a number with the tenant agent. Returns {call_id, ws_url, status}.

    • cancel_call · cancelCall

      Cancel a queued or ringing call.

    • transfer_call · transferCall

      Transfer an in-progress call to another number. warm_transfer keeps the agent on the line during handoff.

    • list_active_calls · listActiveCalls

      List currently-active calls for the tenant (status=in_progress).

  • Inbound

    Subscribe to inbound call events. Closed-set event_type values: inbound_started, inbound_ringing, inbound_answered, inbound_hangup.

    • subscribe_inbound_events · subscribeInboundEvents

      Async iterator over inbound call events. Polls under the hood; consumer can break to cancel.

  • Streaming

    Real-time audio chunks. Codec validation rejects unsupported codecs at construction time. The SDK NEVER logs PCM bytes.

    • stream_audio · streamAudio

      Async iterator yielding metadata-tagged audio chunks (codec, sample_rate, payload_b64, sequence_number). Default codec: pcm_mulaw_8khz.

    • stop_audio_stream · stopAudioStream

      Consumer-side abort: backend stops queueing new chunks.

    • inject_audio_chunk · injectAudioChunk

      Inject base64-encoded audio for the test-mode synthetic-caller scenario. Production callers use Twilio Media Stream forwarding.

  • Recording

    Signed playback URLs with TTL upper bound enforced by the SDK (defence-in-depth even if the backend forgets).

    • get_recording_url · getRecordingUrl

      Return a signed URL valid for ttl_seconds (default 300 / 5 min, max 1800 / 30 min). Above-max throws ValueError. RTD3-FOLLOWUP-C tightened from 3600 to match Twilio + Vonage default signed-URL TTL.

    • delete_recording · deleteRecording

      Delete the recording for a call (GDPR article 17 / HIPAA right-to-delete).

  • Quality

    Voice-quality probes return numerics-only (no PHI). Missing fields default to null so callers can branch on "metrics unavailable" without try/except.

    • get_quality_metrics · getQualityMetrics

      Return MOS / jitter_ms / packet_loss_pct / codec for the call.

    • subscribe_quality_alerts · subscribeQualityAlerts

      Async iterator yielding quality alerts (closed-set: low_mos, high_jitter, packet_loss_spike, codec_fallback).

Adding a new top-level voice surface (e.g. client.voice_clone) means adding a row to _VOICE_REGISTRY in both SDKs + a method-set parity ratchet. The dependency-order invariant ( _RESOURCE_REGISTRY → _VERTICAL_REGISTRY → _VOICE_REGISTRY) means voice helpers can call vertical helpers, but not vice versa.

Integration ecosystem

Integration SDK (RTD4) at client.integrations: 228-provider ecosystem with OAuth2 PKCE (RFC 7636), HMAC-SHA-256/512 webhook verification, DLQ retry, and a closed-set health-status circuit breaker. Secrets never logged at the SDK boundary.

client.integrations · 21 public methods · OAuth2 PKCE + webhook HMAC verifier

Privacy & safety contract

  • Secrets in connect() config (api_key, client_secret, access_token, refresh_token, webhook_secret, password, code_verifier) NEVER appear in any log call. 7-token banned-list ratchet enforces (with camelCase aliases for TS).
  • OAuth2 is PKCE mandatory (RFC 7636). SDK forces code_challenge_method = S256 with no non-PKCE bypass. code_verifier lives client-side only.
  • Webhook HMAC: SHA-256 / SHA-512 only. SHA-1 and MD5 are REJECTED with explicit error (Shattered 2017 collision risk). Constant-time signature compare. Replay tolerance default 300s, max 600s.
  • test_mode tri-state (undefined/true/false): true bills to test account. Bool type-validation rejects string typos with TypeError.
  • business_id accepted on every helper for SDK-side clarity but NOT auto-injected on the wire — the JWT is the source of tenant truth (mirror of RTD3 voice posture).
  • Catalog

    Browse + one-click install from the public marketplace.

    • list_catalog · listCatalog

      Filter by vertical or auth_method.

    • get_catalog_entry · getCatalogEntry

      Fetch a single provider by slug.

    • install_from_catalog · installFromCatalog

      One-click install for low-config providers (Slack, Calendly, Zapier).

  • Lifecycle

    Connect non-OAuth providers, disconnect, list active, and test connectivity.

    • list_active · listActive

      List the tenant active integrations (JWT-bound, cross-tenant impossible).

    • connect · connect

      Connect via api_key / basic / bearer / webhook / mtls. OAuth2 must use start/complete ceremony.

    • disconnect · disconnect

      Drop integration + revoke OAuth tokens + cleanup webhook subscriptions.

    • test_connection · testConnection

      Synthetic ping to validate auth + connectivity.

  • OAuth2 PKCE

    Mandatory PKCE (RFC 7636) with S256. SDK generates code_verifier client-side and never exposes a non-PKCE bypass.

    • start_oauth2 · startOauth2

      Returns {authorization_url, state, code_verifier}. State is single-use CSRF token.

    • complete_oauth2 · completeOauth2

      Exchange code+state for tokens. SDK looks up code_verifier by state.

    • refresh_oauth2 · refreshOauth2

      Refresh an expired access token via stored refresh token.

  • Actions

    Per-integration actions (typed schemas deferred to RTD4-FOLLOWUP-A).

    • list_actions · listActions

      List supported actions with JSON Schema input/output descriptors.

    • invoke_action · invokeAction

      Execute a named action with typed payload. Tri-state test_mode for billing safety.

  • Observability

    Health probes (closed-set status), DLQ retry, debug logs, analytics aggregates.

    • get_health · getHealth

      Returns {health_status, last_success_at, last_failure_at, error_rate_24h, circuit_state}.

    • list_dlq · listDlq

      List failed events sitting in the integration DLQ.

    • retry_dlq · retryDlq

      Retry one event or retry-all. retry_policy in {linear, exponential, manual}.

    • list_debug_logs · listDebugLogs

      Structured debug log entries (admin-only at backend).

    • get_analytics · getAnalytics

      Event counts, p50/p95/p99 latency, success ratio, error class breakdown.

  • Templates

    Reusable custom-integration templates (REST / webhook scaffolding).

    • list_templates · listTemplates

      Browse available templates.

    • get_template · getTemplate

      Fetch a single template by ID.

    • apply_template · applyTemplate

      Materialize a template into a new tenant integration with overrides.

  • Webhook utility (stateless)

    Client-side HMAC verifier. Constant-time compare + timestamp tolerance to defeat replay attacks.

    • verify_webhook_signature · verifyWebhookSignature

      HMAC-SHA-256 (default) or HMAC-SHA-512. SHA-1 / MD5 REJECTED. Tolerance default 300s, max 600s.

Registry walk: _RESOURCE_REGISTRY _VERTICAL_REGISTRY _VOICE_REGISTRY _INTEGRATIONS_REGISTRY. Integration helpers may call generic resources but MUST NOT depend on verticals or voice.

Realtime events

Realtime events SDK (RTD5) at client.events: stream CloudEvents 1.0 envelopes via Server-Sent Events with Last-Event-ID resume, monotonic backoff reconnect, and a 24h replay window. Closed-set namespace prefixes ensure stable consumer code across vendors.

client.events · 3 public methods · CloudEvents 1.0 + SSE streaming

Privacy & safety contract

  • CloudEvents data field NEVER logged at the SDK boundary. Architecture ratchet enforces.
  • CloudEvents 1.0 envelope (CNCF spec): required id / source / type / specversion. Other vendors can ingest the same envelope.
  • Replay window upper bound: EVENT_REPLAY_MAX_HOURS = 24. Older requests rejected at the SDK boundary (defence-in-depth even if backend forgets).
  • Reconnect backoff is a closed tuple (1, 2, 4, 8, 16, 30) seconds -- consumer cannot misconfigure; thundering-herd defense.
  • last_event_id resume cache lives client-side per channel; never on URL.

Closed-set namespace prefixes

  • voice.Call lifecycle, audio quality, transfers
  • integration.OAuth refresh, DLQ, health transitions
  • vertical.Per-vertical business events (dental booking, etc.)
  • billing.Invoice, subscription, dunning notifications
  • system.Platform-wide announcements, maintenance windows
  • Streaming

    Async iterator yielding CloudEvent envelopes. Auto-reconnects with monotonic backoff. Last-Event-ID resume on disconnect.

    • subscribe · subscribe

      Streams CloudEvents 1.0 envelopes. types= filters by closed-set namespace prefixes (voice./integration./vertical./billing./system.). last_event_id resumes from cursor. replay_from_iso is bounded at 24h.

  • Acknowledgement

    For at-least-once consumers wanting backend-side dedup state. Idempotent server-side.

    • ack · ack

      POST /events/{event_id}/ack. Acking the same id twice is safe.

  • Catalog

    Vendor-portable contract: list of currently-emitted event types with descriptions and (optional) JSON Schema URLs.

    • list_types · listTypes

      GET /events/types. Returns the closed-set of stable event types.

5-stage registry walk: _RESOURCE_REGISTRY _VERTICAL_REGISTRY _VOICE_REGISTRY _INTEGRATIONS_REGISTRY _EVENTS_REGISTRY. Events fan-IN: they observe but never call earlier helpers.

AI mode

AI inference SDK (RTD6) at client.ai: Anthropic-style tool use, JSON Schema draft 2020-12 structured output, SSE streaming with normalized delta chunks. Hot-path tiers (voice / clinical) refused at SDK boundary.

client.ai · 5 public methods · Anthropic-style tool use + JSON Schema + SSE

Privacy & safety contract

  • Prompt + completion text NEVER logged at SDK boundary. 6-token banned-list ratchet (messages, prompt, completion, tool_call_input, tool_call_output, embedding).
  • Hot-path purposes (voice_turn, medical_clinical) REFUSED at SDK boundary with ValueError. Those tiers route via dedicated direct-SDK adapters for latency + compliance.
  • test_mode tri-state: undefined / true / false. Bool type-validation rejects string typos with TypeError.
  • cache_system=true opt-in for Anthropic-style 5-min ephemeral prompt caching. Consumer attests system prompt is PHI-free.
  • JSON Schema draft 2020-12 structured output enforced at SDK boundary. tool_choice closed-set: auto / any / none / {type:tool, name}.

ModelPurpose closed-set (5 tiers)

  • general [consumer] General-purpose chat (LiteLLM gateway)
  • batch_postcall [consumer] Post-call summaries, quality scoring
  • embedding [consumer] Vector embeddings (text-embedding-3-large)
  • voice_turn [HOT-PATH (refused at SDK)] Real-time voice turns -- direct Groq adapter
  • medical_clinical [HOT-PATH (refused at SDK)] Clinical decisions -- direct Anthropic adapter
  • Chat completion

    Single-turn or multi-turn chat. Anthropic-style tool use, JSON Schema structured output, prompt caching opt-in.

    • chat · chat

      POST /ai/chat. messages + purpose + tools + tool_choice + response_format + cache_system. Returns AIChatResponse envelope.

    • stream · stream

      POST /ai/stream + GET /ai/stream/cursor. Yields delta chunks (content_delta / tool_call_delta / message_stop).

  • Embeddings

    Generate vector embeddings for retrieval / semantic search.

    • embed · embed

      POST /ai/embed. Accepts list of strings, returns list of float vectors. Non-string inputs rejected at SDK boundary.

  • Telemetry

    Token + cost usage aggregates and the supported model catalog.

    • get_usage · getUsage

      GET /ai/usage. Returns token + cost aggregates per purpose for the date window.

    • list_models · listModels

      GET /ai/models. Returns the closed-set of currently-supported models per purpose.

6-stage registry walk: RTD1 → RTD2 → RTD3 → RTD4 → RTD5 → RTD6. AI fan-OUT: consumers call client.ai.* but helpers do not depend on RTD2-RTD5.

Vision (multimodal)

Vision SDK (RTD7) at client.vision: analyze, structured extract via JSON Schema, classify, and OCR. MIME allowlist, 5 MB size cap, 10-image max per request -- all enforced at the SDK boundary. Image bytes never logged.

client.vision · 4 public methods · multimodal + JSON Schema + OCR

Privacy & safety contract

  • Image bytes NEVER logged at SDK boundary. 4-token banned list: image_data, image_b64, image_bytes, image_payload.
  • MIME allowlist: image/jpeg, image/png, image/webp, image/gif. SVG REJECTED (XSS surface), AVIF REJECTED (provider compat 2026).
  • Size cap: 5 MB per image (conservative floor across all 4 providers). Above: ValueError at SDK boundary.
  • Max 10 images per request (provider-converged limit); classify accepts max 32 labels each ≤64 chars (prompt-injection defense).
  • Source closed-set: base64 / url / vocanta_object_id. Unknown sources rejected at SDK boundary.
  • test_mode tri-state: undefined / true / false. Bool type-validation rejects string typos.

Image source closed-set

  • base64 -- inline upload (size + MIME validated at SDK boundary)
  • url -- consumer-provided URL (https/http only; backend resolves)
  • vocanta_object_id -- previously-uploaded image on the platform
  • Free-form analyze

    Describe images with a prompt. Anthropic / OpenAI / Gemini / Mistral converged shape.

    • analyze · analyze

      POST /vision/analyze. images + prompt + purpose. Returns text description.

  • Structured extract

    JSON Schema draft 2020-12 structured output -- extract patient names, insurance IDs, ID numbers, etc.

    • extract · extract

      POST /vision/extract. Requires json_schema arg with type=object + properties. Returns parsed_json.

  • Classify

    Probability distribution over a closed list of labels.

    • classify · classify

      POST /vision/classify. Up to 32 labels (each <=64 chars). Returns label_probabilities + top_label.

  • OCR

    Text extraction with bounding boxes; 10 supported languages + auto-detect.

    • ocr · ocr

      POST /vision/ocr. languages=("auto",) by default; closed-set: es/en/pt/fr/de/it/ja/zh/ar/auto.

7-stage registry walk: RTD1 → RTD2 → RTD3 → RTD4 → RTD5 → RTD6 → RTD7. Vision fan-OUT: consumers call but helpers don't depend on RTD2-RTD6.

MCP federation

MCP federation SDK (RTD8) at client.mcp: register MCP servers (stdio / sse / websocket / http_streaming), discover and invoke tools, read resources, and subscribe to push notifications. JSON-RPC 2.0 envelope built client-side; tool args and outputs never logged.

client.mcp · 9 public methods · MCP 2025-11-25 + JSON-RPC 2.0

Privacy & safety contract

  • Tool arguments and outputs NEVER logged at SDK boundary. 4-token banned list: arguments, tool_input, tool_output, mcp_args.
  • Args size cap: 64 KB per JSON-RPC params payload. Above: ValueError at SDK boundary (DoS defense).
  • Invoke timeout: default 60s, max 600s. Negative or above-max rejected.
  • test_mode tri-state: undefined / true / false. Bool type-validation rejects string typos like "true".
  • env values forwarded to backend; SDK never logs them.
  • mcp_invocation_logs stores metadata only (tool_name, status, latency_ms, byte_size). NO arguments / NO result columns.

Transport closed-set (per MCP spec)

  • stdio -- local subprocess; requires command + optional args / env.
  • sse -- Server-Sent Events; requires HTTPS url.
  • websocket -- bidirectional WS; requires url.
  • http_streaming -- streamable HTTP; requires url.

JSON-RPC 2.0 envelope (auto-built by SDK)

  • Pinned: jsonrpc="2.0"; validator rejects other versions.
  • id auto-generated client-side via uuid4 if not provided.
  • Spec version MCP_PROTOCOL_VERSION="2025-11-25" sent on every request (header / body field).
  • Server lifecycle

    Register / discover / disconnect MCP servers per tenant. Backend brokers all transport types.

    • list_servers · listServers

      GET /mcp/servers. Returns connected servers + their declared capabilities.

    • connect · connect

      POST /mcp/servers/connect. transport in (stdio, sse, websocket, http_streaming); stdio requires command, others require url.

    • disconnect · disconnect

      DELETE /mcp/servers/{server_id}. Idempotent shutdown of a connected server.

    • get_capabilities · getCapabilities

      GET /mcp/servers/{server_id}/capabilities. Returns capability set: tools / resources / prompts / sampling / logging.

  • Tools

    Discover and invoke tools exposed by MCP servers. Args travel inside JSON-RPC params; never logged.

    • list_tools · listTools

      GET /mcp/servers/{server_id}/tools. Returns tool descriptors with input_schema.

    • invoke_tool · invokeTool

      POST /mcp/servers/{server_id}/invoke. SDK auto-builds JSON-RPC 2.0 envelope. Timeout default 60s, max 600s.

  • Resources

    Discover and read resources (files, datasets, prompts) exposed by an MCP server.

    • list_resources · listResources

      GET /mcp/servers/{server_id}/resources. Returns resource descriptors with URIs.

    • read_resource · readResource

      POST /mcp/servers/{server_id}/resources/read. Reads a resource by URI.

  • Notifications

    Subscribe to push events from the MCP server (e.g. tools/list_changed) -- async iterator.

    • subscribe_notifications · subscribeNotifications

      GET /mcp/servers/{server_id}/notifications (cursor-paginated). AsyncIterator -- consumer breaks to cancel.

8-stage registry walk: RTD1 → RTD2 → RTD3 → RTD4 → RTD5 → RTD6 → RTD7 → RTD8. MCP fan-OUT: AI gateway (RTD6) calls MCP tools as part of agent loops; MCP MUST NOT depend on RTD2-RTD5 / RTD7.

Public MCP catalog

Platform-default MCP tools available out of the box. Tenant-scoped tools require an authenticated MCP client and never appear here.

OpenAPI 3.1 spec

Canonical source for SDK codegen. Pull openapi/vocanta-public.json directly, or browse the interactive explorer.

Public metrics

Live scrape of /api/v1/public/metrics in Prometheus 0.0.4 format. Wire your own Grafana / Datadog scraper directly, or read SDK-side counters via client.metrics.snapshot().

Privacy & telemetry

The SDK ships silent by default. Opt in to send OpenTelemetry-compatible spans and structured error reports — never PHI, never message bodies.

SDK telemetry (opt-in)

Both SDKs ship with telemetry off by default. Opt in to send OpenTelemetry-compatible spans + structured error reports to Vocanta. We never receive PHI, message bodies, or stack traces — only opaque IDs and the exception class name.

  • Default-off: nothing is sent unless you explicitly opt in.
  • PHI-safe: reports carry only conversation_id, business_id, error code, and the exception class name.
  • Revocable: call client.telemetry.opt_out() any time.
  • GDPR-aligned: per-instance consent, no PII, no free-form text fields in the wire schema.

Python

# Per-instance opt-in (recommended)
client = VocantaClient(api_key="voc_...", telemetry=True)

# Or via env var (process-wide)
export VOCANTA_SDK_TELEMETRY=1

TypeScript

// Per-instance opt-in (recommended)
const client = new VocantaClient({ apiKey: 'voc_...', telemetry: true });

// Or via env var (process-wide, Node only)
process.env.VOCANTA_SDK_TELEMETRY = '1';

Source: sdks/python/vocanta/telemetry.py · sdks/typescript/src/telemetry.ts