SDKs
Python SDK
Full reference for the official Voisnap Python SDK — installation, authentication, all resource methods, async support, and error handling.
Python SDK
The official Voisnap Python SDK provides a Pythonic interface to the entire Voisnap API with auto-pagination, async support, and typed dataclasses.
Installation
pip install voisnap
Requires Python 3.8+.
Initialization
API key authentication
import voisnap
client = voisnap.VoisnapClient(api_key="vsnp_live_...")
JWT authentication
client = voisnap.VoisnapClient(access_token="eyJhbGci...")
Custom base URL (sandbox)
client = voisnap.VoisnapClient(
api_key="vsnp_sb_...",
base_url="https://sandbox.api.voisnap.ai"
)
Environment variable
Set VOISNAP_API_KEY in your environment and the client picks it up automatically:
import os
os.environ["VOISNAP_API_KEY"] = "vsnp_live_..."
client = voisnap.VoisnapClient() # uses VOISNAP_API_KEY
Agents
Create an agent
agent = client.agents.create(
name="Aria – Support Agent",
persona={"name": "Aria", "personality": "friendly, professional"},
voice={
"provider": "elevenlabs",
"voice_id": "EXAVITQu4vr4xnSDxMaL",
"stability": 0.5,
"similarity_boost": 0.75,
},
llm={"provider": "openai", "model": "gpt-4o", "temperature": 0.7, "max_tokens": 300},
transcription={"provider": "deepgram", "model": "nova-2", "language": "en-US"},
system_prompt_template="You are Aria, a friendly support agent...",
first_message="Hello! How can I help you today?",
first_message_mode="assistant_speaks_first",
end_call_phrases=["goodbye", "thank you, bye"],
max_duration_seconds=600,
recording={"enabled": True, "format": "mp3", "storage_retention_days": 90},
)
print(f"Created agent: {agent.id}")
List agents (auto-paginated)
The list() method returns a lazy iterator that automatically fetches subsequent pages:
# Iterate all active agents
for agent in client.agents.list(status="active"):
print(f"{agent.name} — {agent.status}")
# Collect all to a list
all_agents = list(client.agents.list())
# With filters
support_agents = list(client.agents.list(
status="active",
search="support",
sort_by="created_at",
sort_order="desc"
))
Get a single agent
agent = client.agents.get("agt_01HXK8Z3MNPQRS")
print(agent.system_prompt_template)
Update an agent
updated = client.agents.update(
"agt_01HXK8Z3MNPQRS",
system_prompt_template="Updated prompt text...",
llm={"temperature": 0.5},
max_duration_seconds=900,
)
Delete an agent
client.agents.delete("agt_01HXK8Z3MNPQRS")
Activate and deactivate
client.agents.activate("agt_01HXK8Z3MNPQRS")
client.agents.deactivate("agt_01HXK8Z3MNPQRS")
Publish a version
client.agents.publish("agt_01HXK8Z3MNPQRS", notes="Improved billing prompt")
Get agent stats
stats = client.agents.stats(
"agt_01HXK8Z3MNPQRS",
date_from="2025-06-01",
date_to="2025-06-30"
)
print(f"Conversations: {stats.total_conversations}")
print(f"Avg duration: {stats.avg_duration_seconds}s")
print(f"Resolution rate: {stats.outcome_breakdown.resolved / stats.total_conversations:.1%}")
Conversations
List conversations (auto-paginated)
for conv in client.conversations.list(
agent_id="agt_01HXK8Z3MNPQRS",
channel="phone",
status="completed",
date_from="2025-06-01",
date_to="2025-06-30",
):
print(f"{conv.id}: {conv.duration_seconds}s, sentiment: {conv.analysis.sentiment}")
Get a conversation
conv = client.conversations.get("conv_01HXDEF456GHI")
Get transcript
transcript = client.conversations.transcript("conv_01HXDEF456GHI")
for turn in transcript.turns:
role = "🤖" if turn.speaker == "agent" else "👤"
print(f"{role} [{turn.start_time:.1f}s] {turn.text}")
Get analysis
analysis = client.conversations.analysis("conv_01HXDEF456GHI")
print(f"Sentiment: {analysis.sentiment} ({analysis.sentiment_score:.2f})")
print(f"Intent: {analysis.intent}")
print(f"Summary: {analysis.summary}")
Add tags
client.conversations.add_tags("conv_01HXDEF456GHI", ["billing", "vip"])
Set outcome
client.conversations.set_outcome(
"conv_01HXDEF456GHI",
outcome="resolved",
notes="Billing question resolved."
)
Telephony
Search available numbers
numbers = client.telephony.numbers.search(
country="US",
area_code="415",
capabilities=["voice", "sms"]
)
for n in numbers:
print(f"{n.phone_number} — ${n.monthly_cost_usd}/mo")
Provision a number
number = client.telephony.numbers.provision(
phone_number="+14155550100",
provider="twilio",
friendly_name="Main Support Line"
)
Assign to agent
client.telephony.numbers.assign(
number_id=number.id,
agent_id="agt_01HXK8Z3MNPQRS"
)
List provisioned numbers
for num in client.telephony.numbers.list():
print(f"{num.phone_number} → {num.assigned_agent_name or 'unassigned'}")
Knowledge Base
Upload a document
with open("product-catalog.pdf", "rb") as f:
doc = client.knowledge_base.upload_document(
file=f,
name="Product Catalog Q2 2025",
agent_ids=["agt_01HXK8Z3MNPQRS"],
metadata={"department": "product"}
)
# Wait for indexing
import time
while doc.status == "processing":
time.sleep(3)
doc = client.knowledge_base.get(doc.id)
print(f"Indexed {doc.chunk_count} chunks")
Semantic search
results = client.knowledge_base.search(
query="What is the return policy?",
document_ids=["kb_01HXABC123DEF"],
top_k=5,
min_score=0.7
)
for match in results.matches:
print(f"Score: {match.score:.3f} | {match.excerpt[:100]}...")
Outbound Calls
Create an outbound call
# Immediate
call = client.outbound_calls.create(
agent_id="agt_01HXK8Z3MNPQRS",
to_number="+14155550199",
metadata={"customer_id": "cust_12345"},
)
# Scheduled
call = client.outbound_calls.create(
agent_id="agt_01HXK8Z3MNPQRS",
to_number="+14155550199",
scheduled_for="2025-06-17T09:00:00Z",
max_retries=2,
retry_delay_minutes=30,
)
Cancel a call
client.outbound_calls.cancel("obc_01HXMN8ZABC123")
List outbound calls
for call in client.outbound_calls.list(status="completed"):
print(f"{call.to_number}: {call.status}")
Async support
Every synchronous method has an async equivalent via AsyncVoisnapClient:
import asyncio
import voisnap
async def main():
client = voisnap.AsyncVoisnapClient(api_key="vsnp_live_...")
# Concurrent requests
agent, conversations = await asyncio.gather(
client.agents.get("agt_01HXK8Z3MNPQRS"),
client.conversations.list(agent_id="agt_01HXK8Z3MNPQRS").__anext__(),
)
# Async iteration
async for conv in client.conversations.list(status="completed"):
print(conv.id)
await client.close()
asyncio.run(main())
Error handling
from voisnap.exceptions import (
VoisnapError,
AuthenticationError,
PermissionError,
NotFoundError,
RateLimitError,
ValidationError,
ServerError,
)
try:
agent = client.agents.get("agt_does_not_exist")
except NotFoundError as e:
print(f"Not found: {e.detail}")
except AuthenticationError as e:
print(f"Auth failed: {e.message}")
except RateLimitError as e:
print(f"Rate limited. Retry after {e.retry_after}s")
except ValidationError as e:
for err in e.errors:
print(f" {err.field}: {err.message}")
except VoisnapError as e:
print(f"API error {e.status}: {e.detail} (trace: {e.trace_id})")
The SDK automatically retries RateLimitError (429) and transient ServerError (503) with exponential backoff. You can configure retry behavior:
client = voisnap.VoisnapClient(
api_key="vsnp_live_...",
max_retries=3, # default: 3
retry_on=[429, 503], # default
timeout=30, # seconds, default: 30
)
Pagination utilities
# Get a single page
page = client.agents.list_page(page=2, page_size=50)
print(f"Page {page.page} of {page.total_pages}, {page.total} total")
for agent in page.data:
print(agent.name)
# Collect all items across all pages
all_agents = client.agents.list_all() # fetches all pages sequentially