SDK Reference

Client libraries for Python (server & worker) and JavaScript/React (browser).

Installation

bash
pip install hostdesk-sdk

For voice worker support (LiveKit agent), install with the gateway extra:

bash
pip install hostdesk-sdk[gateway]

Client

The Client is your main entry point. It provides access to calls, assistants, TTS, STT, and models.

python
from hostdesk import Client

client = Client(api_key="ek_...")

# Or set ECHOAI_API_KEY env var
client = Client()

Constructor

ParameterTypeDescription
api_keystr | NoneAPI key. Falls back to ECHOAI_API_KEY env var.
base_urlstr | NoneAPI base URL. Default: https://api.hostdeskai.com
sandboxboolUse sandbox environment. Default: False

Properties

client.calls — CallsAPI for outbound calls and call history

client.assistants — AssistantsAPI for CRUD assistant configs

client.tts — TTSAPI for text-to-speech generation

client.stt — STTAPI for speech-to-text transcription

client.models — ModelsAPI for listing available models

Calls

Place outbound calls and retrieve call history.

python
# Place an outbound call
result = client.calls.create(
    phone_number="+14155551234",
    objective="Confirm appointment for Friday at 3 PM",
    assistant_id="asst_abc123",  # optional
)
print(result.room_name)  # "hostdesk-out-a1b2c3d4"

# List recent calls
calls = client.calls.list(limit=10, status="completed")

# Get a single call
call = client.calls.get("call_id_or_room_name")

# Get conversation history
messages = client.calls.messages("call_id_or_room_name")

Assistants

Create and manage assistant configurations (system prompt, voice, model).

python
# Create an assistant
assistant = client.assistants.create(
    name="Sales Agent",
    system_prompt="You are a helpful sales agent...",
    voice_id="a0e99841-438c-4a64-b679-ae501e7d6091",
    llm_model="gemini-2.5-flash",
)

# List all assistants
assistants = client.assistants.list()

# Update
client.assistants.update(assistant.id, name="Senior Sales Agent")

# Delete
client.assistants.delete(assistant.id)

Voice Worker

EchoWorker runs a voice agent that handles calls. It connects to LiveKit and processes audio in real time.

python
from hostdesk import EchoWorker

worker = EchoWorker(api_key="ek_...")

@worker.on_call
async def handle_call(call):
    print(f"Call from {call.from_number}")
    # Speak immediately
    await call.say("Hello! How can I help you today?")

    # Transfer to another number
    await call.transfer("+14155559876", announce="Connecting you now")

    # Hold / resume
    call.hold()
    call.resume()

    # Access raw LiveKit room
    room = call.livekit_room

worker.run()

Token Mode

Workers can run without a LiveKit API key. They poll the HostDesk API for room tokens and join with those credentials. Set only ECHOAI_API_KEY — no LIVEKIT_API_KEY needed on the client.

join_room_with_token()

Lower-level function to join a specific LiveKit room with a pre-generated token.

python
from hostdesk import join_room_with_token

await join_room_with_token(
    url="wss://my-project.livekit.cloud",
    token="eyJhbG...",
    on_call=handle_call,
)

Webhooks

Verify incoming webhook signatures (HMAC-SHA256).

python
from hostdesk import verify_webhook

is_valid = verify_webhook(
    payload=request_body,
    # NOTE: the wire header names stay X-EchoAI-* — that's what the platform sends.
    signature=headers["X-EchoAI-Signature"],
    secret="whsec_...",
    timestamp=int(headers["X-EchoAI-Timestamp"]),
)

Function Calling

Register server-side functions that the voice agent can invoke via webhooks.

python
from hostdesk import FunctionHandler, create_function_webhook_app

handler = FunctionHandler(secret="whsec_...")

@handler.on("bookAppointment")
async def book_appointment(date: str, time: str, name: str):
    # Your booking logic here
    return {"confirmed": True, "date": date, "time": time}

@handler.on("lookupOrder")
async def lookup_order(order_id: str):
    return {"status": "shipped", "tracking": "1Z999AA10123456784"}

# Mount as a Starlette/FastAPI app
app = create_function_webhook_app(handler, path="/webhook")

# Or handle manually in an existing route
result = await handler.handle_request(request)

Error Handling

python
from hostdesk import (
    HostDeskError,      # base error
    AuthError,        # 401/403 — invalid API key
    ValidationError,  # 400/422 — bad request params
    NotFoundError,    # 404 — resource not found
    RateLimitError,   # 429 — too many requests
    ProviderError,    # 502/503 — upstream provider error
)

try:
    client.calls.create(phone_number="+1...")
except AuthError:
    print("Check your API key")
except RateLimitError as e:
    print(f"Slow down: {e}")
except HostDeskError as e:
    print(f"API error: {e}")