What's New
The latest Teler SDK releases and features, newest first.
September 2026
Section titled “September 2026”Node SDK 2.0.0 and Python SDK 1.0.0 are now stable with production-ready call mutations, media streaming, SIP management, recordings, and events APIs. Python includes async client with full parity to Node.
Node SDK 2.0.0 and Python SDK 1.0.0 — Stable releases with full API support for all Teler services:
Core capabilities (Node and Python):
- Voice calls — Initiate, control, and manage calls with mutations (mute, DTMF, play, hangup, transfer)
- SIP trunks — Full SIP trunk management with IP ACL support and UDP transport
- Virtual numbers — Provision and manage Teler numbers
- Recordings — Capture call audio in multiple modes:
mono,stereo, orper_leg - Events — Subscribe to call and stream lifecycle events via webhooks
- Secrets — Securely store and retrieve API credentials for integrations
Python-specific:
- Sync
Clientfor traditional blocking code - Async
AsyncClientfor high-concurrency applications (new in 1.0.0) - Full feature parity with Node SDK
Node-specific:
- Auto-pagination built-in for all list operations
- Promise-based async API
Install
Section titled “Install”pip install telernpm install @frejun/telerBoth SDKs include:
- Automatic idempotency key generation for safe retries
- Typed exceptions:
BadParametersException,ForbiddenException,RateLimitException,TelerException - Cursor-based pagination for large result sets
- Webhook signing verification with HMAC-SHA256
- Streaming support via
StreamConnectorto bridge AI provider integrations - Production-ready error handling and retry logic
July 2026
Section titled “July 2026”Two ways to move a caller from an AI agent to a live person: a REST transfer operation for live calls, and the dial flow verb for flow-time handoff.
Transfer an in-progress call to a new PSTN or SIP destination, enabling agent-to-human handoff flows. Three features ship together to support flexible transfer patterns:
1. Transfer control operation (REST API)
Section titled “1. Transfer control operation (REST API)”Your backend can initiate a transfer on a live call via POST /api/v1/voice/calls/{call_id}/transfer. This is async and idempotent — use the same Idempotency-Key to safely retry.
Request:
POST /api/v1/voice/calls/{call_id}/transferContent-Type: application/jsonIdempotency-Key: <unique-per-attempt>
{ "target": { "kind": "pstn", "number": "+14155550123" }, "mode": "cold", "timeout": 30, "record": false, "ringback": "suppress", "on_failure": { "action": "play", "media_url": "https://.../could-not-connect.mp3" }}Supported parameters:
target.kind—"pstn"(PSTN number) or"sip"(SIP URI)timeout— 1–600 seconds, default 30record— Recording mode:false,true,"mono","stereo","per_leg"ringback—"suppress"(default) or"passthrough"on_failure— Nested action (play, hangup) if transfer fails
Constraints:
- Only
mode: "cold"is supported today - One transfer per call at a time (
409 transfer_in_progress) - Voice App only
- Requires webhook version
2026-06-01
2. Transfer lifecycle events
Section titled “2. Transfer lifecycle events”Track the transfer as it progresses through your webhook:
call.transfer.initiated— Transfer request accepted, target leg originatescall.transfer.bridged— Target answered and is now bridged to callercall.transfer.failed— Transfer failed (includesreasonfor debugging)
Each event carries the transfer ID (op_<ULID>) for correlation.
3. dial (flow verb) — Flow-based handoff
Section titled “3. dial (flow verb) — Flow-based handoff”Return {"action": "dial", "to": "+14155550123"} from your flow endpoint to dial and bridge a target, letting your flow logic drive the handoff decision.
Request:
{ "action": "dial", "to": "+14155550123", "timeout": 25, "record": "stereo", "ringback": "passthrough", "dial_music": { "action": "play", "media_url": "https://cdn.example.com/hold.mp3", "loop": true }, "on_no_answer": { "action": "hangup" }, "on_busy": { "action": "play", "media_url": "https://cdn.example.com/try-later.mp3" }}Supported parameters:
to— Target E.164 number or SIP URI (single target)timeout— 1–600 seconds, default 30record— Recording mode:false,true,"mono","stereo","per_leg", defaultfalseringback—"passthrough"(default) or"suppress"dial_music— Audio to play to caller while target ringsconfirm_sound— Audio to play to target immediately after pickupon_no_answer,on_busy,on_failure— Fallback actions (play or hangup only)custom_headers— SIP headers starting withX-(max 16, 256 bytes each)
Constraints:
- Not available on webhook version
2025-08-01; requires2026-06-01 - Nested actions support only
playandhangup - Multiple targets,
machine_detection, and mixed SIP+PSTN targets not yet shipped
Leg lifecycle events
The dialed leg emits events as it progresses:
leg.created— Outbound leg originated to targetleg.answered— Target answered and bridge establishedleg.completed— Leg disconnected withreason(normal,no_answer,busy,rejected,unreachable, etc.)
Each event includes the leg ID for tracking across your call lifecycle.
When to use each method
Section titled “When to use each method”| Call transfer (REST) | dial (flow verb) | |
|---|---|---|
| Decision point | Backend, mid-call | Flow endpoint, before response |
| Use case | Real-time server logic (queue depth, agent availability) | Flow-driven logic (intent, escalation policy) |
| Target | PSTN or SIP | PSTN or SIP |
| Timeout | 1–600 s (default 30) | 1–600 s (default 30) |
| Fallback control | on_failure only | on_no_answer, on_busy, on_failure |
| Recording | Configurable per transfer | Configurable per dial |
| Events | call.transfer.* | leg.* |
| Requires | Voice App 2026-06-01; Voice App only | Voice App 2026-06-01 |
July 3, 2026 Webhook version 2026-06-01: event envelope, call control, and call resources
#
Added Changed
New dated webhook version with event envelope wrapper, live call control operations, call resources API, new event types, and stable event IDs for idempotent deduplication.
A new dated webhook API version, 2026-06-01, available opt-in per Voice App or SIP Trunk. The previous 2025-08-01 version continues to work for existing deployments. This version introduces a complete redesign of webhooks, new call management APIs, and infrastructure for reliable event delivery.
Event envelope
Section titled “Event envelope”Every webhook body is now wrapped in a standard envelope:
{ "id": "evt_...", "type": "call.initiated", "api_version": "2026-06-01", "occurred_at": "2026-07-03T12:34:56Z", "account_id": "acc_...", "voice_app_id": "va_...", "call_id": "cs_...", "leg_id": "cl_...", "data": { "from_number": "+14155550100", "to_number": "+14155550123", "direction": "inbound", "answered_at": "2026-07-03T12:34:57Z", "duration_seconds": 45, "ended_by": "caller", "reason": "normal" }}Envelope fields:
id— Stable, unique event ID (for idempotent deduplication across retries)type— Event type (e.g.,call.initiated,call.answered,leg.created)api_version— Pinned webhook version (2026-06-01)occurred_at— ISO 8601 timestamp when the event occurredaccount_id,voice_app_id/sip_trunk_id,call_id,leg_id— Resource IDs for correlationdata— Event-specific payload
New headers on every webhook request:
X-Teler-Event-Id— Echoes the eventidfor deduplicationX-Teler-Api-Version— Echoes2026-06-01X-Teler-Source— Identifies the webhook source (e.g.,voice_app,sip_trunk)
Resource-typed IDs
Section titled “Resource-typed IDs”All resource IDs now have consistent prefixes for type safety:
acc_— Accountva_— Voice Appst_— SIP Trunkcs_— Callcl_— Call legms_— Media streamevt_— Eventrec_— Recordingpb_— Playback
New event types
Section titled “New event types”Eight new events ship with this version:
leg.created— Outbound leg originatedleg.answered— Leg answered and bridgedleg.completed— Leg disconnected with reasonstream.initiated— Media stream startedstream.completed— Media stream endedrecording.completed— Recording file readyrecording.failed— Recording failed- Plus existing call events with new envelope format
See Call events for full schemas.
Call resources API
Section titled “Call resources API”Retrieve call and leg details via REST:
GET /api/v1/voice/callsGET /api/v1/voice/calls/{call_id}GET /api/v1/voice/calls/{call_id}/legsGET /api/v1/voice/calls/{call_id}/legs/{leg_id}For SIP Trunks:
GET /api/v1/sip/callsGET /api/v1/sip/calls/{call_id}GET /api/v1/sip/calls/{call_id}/legsReturns call state, participant info, timing, recording status, and more. See Call resources.
Live call control
Section titled “Live call control”Perform mutations on active calls via async, idempotent operations:
POST /api/v1/voice/calls/{call_id}/hangupPOST /api/v1/voice/calls/{call_id}/mutePOST /api/v1/voice/calls/{call_id}/dtmfPOST /api/v1/voice/calls/{call_id}/playAll require Idempotency-Key header for safety. See Live call control.
Stable event IDs for idempotent dedupe
Section titled “Stable event IDs for idempotent dedupe”The id field is stable across webhook retries, replays, and recovery re-deliveries. Use it to deduplicate events on your side for exactly-once processing. See Retries and idempotency.
Field renames and normalization
Section titled “Field renames and normalization”Inside the data payload, fields are renamed for clarity:
hangup_time→ended_athangup_source→ended_byduration(seconds) →duration_secondsanswer_time→answered_at- New normalized
reasonfield for all completion events directionunchanged (inbound/outbound)
Full migration guide: API versioning.
Opt-in per resource
Section titled “Opt-in per resource”Pin this version on a per-Voice-App or per-SIP-Trunk basis. The previous 2025-08-01 version continues to work unchanged for existing resources that don’t pin the new version.