Skip to main content

Python SDK

Official Python SDK for the Truedy API.

Installation

pip install trudy-python-sdk

Quick Start

from trudy import TrudyClient

# Initialize client
client = TrudyClient(api_key="YOUR_API_KEY")

# Create an agent
agent = client.agents.create(
    name="Support Agent",
    voice_id="VOICE_UUID",
    system_prompt="You are a helpful support agent."
)

# Make a call
call = client.calls.create(
    agent_id=agent.id,
    phone_number="+1234567890",
    direction="outbound"
)

# Get call status
status = client.calls.get(call.id)
print(f"Call status: {status.status}")

Authentication

from trudy import TrudyClient

# Using API key
client = TrudyClient(api_key="YOUR_API_KEY")

# Using JWT token (for frontend)
client = TrudyClient(jwt_token="YOUR_JWT_TOKEN")

Agents

# List agents
agents = client.agents.list()

# Get agent
agent = client.agents.get("agent-uuid")

# Create agent
agent = client.agents.create(
    name="My Agent",
    voice_id="voice-uuid",
    system_prompt="You are a helpful agent."
)

# Update agent
agent = client.agents.update(
    "agent-uuid",
    name="Updated Name"
)

# Delete agent
client.agents.delete("agent-uuid")

Calls

# List calls
calls = client.calls.list(limit=50, offset=0)

# Get call
call = client.calls.get("call-uuid")

# Create call
call = client.calls.create(
    agent_id="agent-uuid",
    phone_number="+1234567890",
    direction="outbound",
    call_settings={
        "recording_enabled": True,
        "transcription_enabled": True
    }
)

# Get transcript
transcript = client.calls.get_transcript("call-uuid")

# Get recording
recording = client.calls.get_recording("call-uuid")

Error Handling

Handle 402 Payment Required (trial not started, trial expired, insufficient credits) and 429 Rate limit exceeded explicitly:
from trudy import TrudyError, RateLimitError, PaymentRequiredError

try:
    call = client.calls.create(...)
except PaymentRequiredError as e:
    # e.code, e.message, e.details (reason, redirect_url, balance, required)
    print(f"Payment required: {e.message}")
    if e.details.get("redirect_url"):
        print(f"Redirect user to: {e.details['redirect_url']}")
except RateLimitError as e:
    print(f"Rate limit exceeded. Reset at: {e.details.get('reset_at')}")
    # Back off and retry after reset_at
except TrudyError as e:
    print(f"Error {e.code}: {e.message}")
All API errors use the same envelope: error.code, error.message, error.details, and meta.request_id (for support).

Rate limits and retries

The API uses per-minute rate limits. Responses do not include X-RateLimit-* headers; on 429 the body includes error.details.limit and error.details.reset_at (ISO timestamp). The SDK should retry after reset_at or use exponential backoff. See Rate Limits.

Minimal client (requests only)

If you prefer not to use the SDK, use requests with the same error handling:
import requests
import time
from datetime import datetime, timezone

BASE = "https://api.truedy.ai/api/public/v1"

def truedy_request(api_key: str, method: str, path: str, **kwargs):
    url = f"{BASE}{path}"
    headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}
    for _ in range(3):  # retries for 429
        r = requests.request(method, url, headers=headers, **kwargs)
        if r.status_code == 429:
            body = r.json()
            reset_at = body.get("error", {}).get("details", {}).get("reset_at")
            if reset_at:
                try:
                    reset_dt = datetime.fromisoformat(reset_at.replace("Z", "+00:00"))
                    wait = max(1, (reset_dt - datetime.now(timezone.utc)).total_seconds())
                except Exception:
                    wait = 60
            else:
                wait = 60
            time.sleep(min(wait, 120))
            continue
        if r.status_code == 402:
            body = r.json()
            err = body.get("error", {})
            raise Exception(f"402 {err.get('code')}: {err.get('message')} redirect_url={err.get('details', {}).get('redirect_url')}")
        r.raise_for_status()
        return r.json() if r.content else {}

# Example: list agents
data = truedy_request("YOUR_API_KEY", "GET", "/agents")
print(data["data"])

Examples

See the GitHub repository for more examples.