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.
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 vocanta2. 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
dentalDentalHelpers
- book_cleaning
- book_consultation
- submit_insurance_claim
- get_treatment_history
Defaults: cleaning=30min, consultation=60min, root_canal=90min
client.medical
medicalMedicalHelpers
- book_consultation
- start_telemedicine_session
- record_vitals
- prescribe_medication
Defaults: consultation=30min, telemedicine recording=OFF (HIPAA-safe)
client.insurance
insuranceInsuranceHelpers
- verify_coverage
- submit_claim
- check_claim_status
Defaults: kind=insurance_coverage_verification, kind=insurance_claim_submission
client.hospitality
hospitalityHospitalityHelpers
- 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_modeis tri-state:undefineduses tenant config,truebills to test account,falseforces production. Default is nevertrue.- Recording URLs are TTL-bounded to
<= 1800s(30 min, RTD3-FOLLOWUP-C). Default is300s(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
VocantaVoiceProviderFailoverWarningwith 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 = S256with no non-PKCE bypass.code_verifierlives 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_modetri-state (undefined/true/false):truebills to test account. Bool type-validation rejects string typos with TypeError.business_idaccepted 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
datafield 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_idresume cache lives client-side per channel; never on URL.
Closed-set namespace prefixes
voice.— Call lifecycle, audio quality, transfersintegration.— OAuth refresh, DLQ, health transitionsvertical.— Per-vertical business events (dental booking, etc.)billing.— Invoice, subscription, dunning notificationssystem.— 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 withValueError. Those tiers route via dedicated direct-SDK adapters for latency + compliance. test_modetri-state: undefined / true / false. Bool type-validation rejects string typos with TypeError.cache_system=trueopt-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_choiceclosed-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 scoringembedding[consumer] — Vector embeddings (text-embedding-3-large)voice_turn[HOT-PATH (refused at SDK)] — Real-time voice turns -- direct Groq adaptermedical_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 MBper image (conservative floor across all 4 providers). Above: ValueError at SDK boundary. - Max
10 imagesper 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_modetri-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 KBper JSON-RPC params payload. Above: ValueError at SDK boundary (DoS defense). - Invoke timeout: default
60s, max600s. Negative or above-max rejected. test_modetri-state: undefined / true / false. Bool type-validation rejects string typos like"true".envvalues forwarded to backend; SDK never logs them.mcp_invocation_logsstores metadata only (tool_name, status, latency_ms, byte_size). NO arguments / NO result columns.
Transport closed-set (per MCP spec)
stdio-- local subprocess; requirescommand+ optionalargs/env.sse-- Server-Sent Events; requires HTTPSurl.websocket-- bidirectional WS; requiresurl.http_streaming-- streamable HTTP; requiresurl.
JSON-RPC 2.0 envelope (auto-built by SDK)
- Pinned:
jsonrpc="2.0"; validator rejects other versions. idauto-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=1TypeScript
// 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