# SDKs

> Official client SDKs for integrating Edesy Voice Agent into your applications.

Source: https://edesy.in/docs/voice-agent/api/sdks

Official client libraries for JavaScript/TypeScript, Python, and Go to integrate voice agents into your applications.

## Available SDKs

| Language | Package | Status |
|----------|---------|--------|
| JavaScript/TypeScript | `@edesy/voice-agent` | Stable |
| Python | `edesy-voice-agent` | Stable |
| Go | `github.com/edesy-ai/voice-agent-go` | Stable |

## JavaScript/TypeScript SDK

### Installation

```bash
npm install @edesy/voice-agent
# or
yarn add @edesy/voice-agent
# or
pnpm add @edesy/voice-agent
```

### Quick Start

```typescript
import { EdesyClient, Agent } from '@edesy/voice-agent';

// Initialize client
const client = new EdesyClient({
  apiKey: process.env.EDESY_API_KEY,
});

// Create an agent
const agent = await client.agents.create({
  name: 'Customer Support',
  language: 'en-US',
  llmProvider: 'gemini-2.5',
  llmModel: 'gemini-2.5-flash-lite',
  sttProvider: 'deepgram',
  ttsProvider: 'cartesia',
  ttsVoice: '95856005-0332-41b0-935f-352e296aa0df',
  prompt: 'You are a helpful customer support agent.',
  greetingMessage: 'Hello! How can I help you today?',
});

// Initiate a call
const call = await client.calls.create({
  agentId: agent.id,
  to: '+1234567890',
  from: '+0987654321',
  variables: {
    customerName: 'John Smith',
  },
});

console.log(`Call started: ${call.id}`);
```

### Agents API

```typescript
// List agents
const agents = await client.agents.list();

// Get agent by ID
const agent = await client.agents.get('agent_123');

// Update agent
const updated = await client.agents.update('agent_123', {
  name: 'Updated Support',
  prompt: 'New system prompt...',
});

// Delete agent
await client.agents.delete('agent_123');
```

### Calls API

```typescript
// Create outbound call
const call = await client.calls.create({
  agentId: 'agent_123',
  to: '+1234567890',
  from: '+0987654321',
  variables: { customerName: 'John' },
});

// Get call details
const callDetails = await client.calls.get(call.id);

// List calls
const calls = await client.calls.list({
  agentId: 'agent_123',
  status: 'completed',
  limit: 10,
});

// End call
await client.calls.end(call.id);
```

### Transcripts API

```typescript
// Get transcript
const transcript = await client.transcripts.get('trans_123');

// Get transcript text
const text = await client.transcripts.getText('trans_123');

// List transcripts for a call
const transcripts = await client.transcripts.list({
  callId: 'call_123',
});
```

### WebSocket Streaming

```typescript
import { EdesyWebSocket } from '@edesy/voice-agent';

const ws = new EdesyWebSocket({
  apiKey: process.env.EDESY_API_KEY,
  agentId: 'agent_123',
});

ws.on('connected', () => {
  console.log('Connected to voice agent');
});

ws.on('transcript', (data) => {
  console.log(`${data.role}: ${data.text}`);
});

ws.on('audio', (data) => {
  // Handle audio output
  playAudio(data.audio);
});

// Send audio
ws.sendAudio(audioBuffer);

// Send text (for testing)
ws.sendText('Hello, I need help with my order');

// Close connection
ws.close();
```

### TypeScript Types

```typescript
interface Agent {
  id: string;
  name: string;
  language: string;
  llmProvider: string;
  llmModel: string;
  sttProvider: string;
  sttModel?: string;
  ttsProvider: string;
  ttsVoice: string;
  prompt: string;
  greetingMessage?: string;
  tools?: Tool[];
  createdAt: Date;
  updatedAt: Date;
}

interface Call {
  id: string;
  agentId: string;
  direction: 'inbound' | 'outbound';
  status: 'queued' | 'ringing' | 'in-progress' | 'completed' | 'failed';
  from: string;
  to: string;
  duration?: number;
  startedAt?: Date;
  endedAt?: Date;
}

interface Transcript {
  id: string;
  callId: string;
  turns: TranscriptTurn[];
  summary?: string;
  createdAt: Date;
}

interface TranscriptTurn {
  id: string;
  role: 'user' | 'assistant';
  text: string;
  timestamp: number;
  confidence?: number;
}
```

## Python SDK

### Installation

```bash
pip install edesy-voice-agent
```

### Quick Start

```python
from edesy import EdesyClient

# Initialize client
client = EdesyClient(api_key="your-api-key")

# Create an agent
agent = client.agents.create(
    name="Customer Support",
    language="en-US",
    llm_provider="gemini-2.5",
    llm_model="gemini-2.5-flash-lite",
    stt_provider="deepgram",
    tts_provider="cartesia",
    tts_voice="95856005-0332-41b0-935f-352e296aa0df",
    prompt="You are a helpful customer support agent.",
    greeting_message="Hello! How can I help you today?",
)

# Initiate a call
call = client.calls.create(
    agent_id=agent.id,
    to="+1234567890",
    from_="+0987654321",
    variables={"customer_name": "John Smith"},
)

print(f"Call started: {call.id}")
```

### Async Support

```python
import asyncio
from edesy import AsyncEdesyClient

async def main():
    client = AsyncEdesyClient(api_key="your-api-key")

    # Async operations
    agents = await client.agents.list()

    # Create call
    call = await client.calls.create(
        agent_id="agent_123",
        to="+1234567890",
        from_="+0987654321",
    )

    # Wait for completion
    while call.status not in ["completed", "failed"]:
        await asyncio.sleep(1)
        call = await client.calls.get(call.id)

    print(f"Call ended with status: {call.status}")

asyncio.run(main())
```

### Agents API

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

# Get agent
agent = client.agents.get("agent_123")

# Update agent
agent = client.agents.update(
    "agent_123",
    name="Updated Support",
    prompt="New system prompt...",
)

# Delete agent
client.agents.delete("agent_123")
```

### Calls API

```python
# Create call
call = client.calls.create(
    agent_id="agent_123",
    to="+1234567890",
    from_="+0987654321",
)

# Get call
call = client.calls.get(call.id)

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

# End call
client.calls.end(call.id)
```

### WebSocket Streaming

```python
from edesy import EdesyWebSocket

def on_transcript(data):
    print(f"{data['role']}: {data['text']}")

def on_audio(data):
    # Handle audio output
    play_audio(data['audio'])

ws = EdesyWebSocket(
    api_key="your-api-key",
    agent_id="agent_123",
)

ws.on("transcript", on_transcript)
ws.on("audio", on_audio)

# Connect and start
ws.connect()

# Send audio
ws.send_audio(audio_buffer)

# Close
ws.close()
```

### Error Handling

```python
from edesy import EdesyError, RateLimitError, AuthenticationError

try:
    call = client.calls.create(agent_id="agent_123", to="+1234567890")
except AuthenticationError:
    print("Invalid API key")
except RateLimitError as e:
    print(f"Rate limited. Retry after {e.retry_after} seconds")
except EdesyError as e:
    print(f"API error: {e.message}")
```

## Go SDK

### Installation

```bash
go get github.com/edesy-ai/voice-agent-go
```

### Quick Start

```go
package main

import (
    "context"
    "fmt"
    "log"

    edesy "github.com/edesy-ai/voice-agent-go"
)

func main() {
    // Initialize client
    client := edesy.NewClient("your-api-key")

    ctx := context.Background()

    // Create an agent
    agent, err := client.Agents.Create(ctx, edesy.CreateAgentRequest{
        Name:            "Customer Support",
        Language:        "en-US",
        LLMProvider:     "gemini-2.5",
        LLMModel:        "gemini-2.5-flash-lite",
        STTProvider:     "deepgram",
        TTSProvider:     "cartesia",
        TTSVoice:        "95856005-0332-41b0-935f-352e296aa0df",
        Prompt:          "You are a helpful customer support agent.",
        GreetingMessage: "Hello! How can I help you today?",
    })
    if err != nil {
        log.Fatal(err)
    }

    // Initiate a call
    call, err := client.Calls.Create(ctx, edesy.CreateCallRequest{
        AgentID: agent.ID,
        To:      "+1234567890",
        From:    "+0987654321",
        Variables: map[string]string{
            "customerName": "John Smith",
        },
    })
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Call started: %s\n", call.ID)
}
```

### Agents API

```go
// List agents
agents, err := client.Agents.List(ctx, edesy.ListAgentsParams{})

// Get agent
agent, err := client.Agents.Get(ctx, "agent_123")

// Update agent
agent, err := client.Agents.Update(ctx, "agent_123", edesy.UpdateAgentRequest{
    Name:   "Updated Support",
    Prompt: "New system prompt...",
})

// Delete agent
err := client.Agents.Delete(ctx, "agent_123")
```

### Calls API

```go
// Create call
call, err := client.Calls.Create(ctx, edesy.CreateCallRequest{
    AgentID: "agent_123",
    To:      "+1234567890",
    From:    "+0987654321",
})

// Get call
call, err := client.Calls.Get(ctx, call.ID)

// List calls
calls, err := client.Calls.List(ctx, edesy.ListCallsParams{
    AgentID: "agent_123",
    Status:  "completed",
    Limit:   10,
})

// End call
err := client.Calls.End(ctx, call.ID)
```

### WebSocket Streaming

```go
import (
    edesy "github.com/edesy-ai/voice-agent-go"
)

ws, err := client.WebSocket(ctx, "agent_123")
if err != nil {
    log.Fatal(err)
}
defer ws.Close()

// Handle events
go func() {
    for event := range ws.Events() {
        switch e := event.(type) {
        case *edesy.TranscriptEvent:
            fmt.Printf("%s: %s\n", e.Role, e.Text)
        case *edesy.AudioEvent:
            playAudio(e.Audio)
        case *edesy.ErrorEvent:
            log.Printf("Error: %s", e.Message)
        }
    }
}()

// Send audio
err = ws.SendAudio(audioBuffer)

// Wait for completion
<-ws.Done()
```

### Error Handling

```go
import "errors"

call, err := client.Calls.Create(ctx, req)
if err != nil {
    var apiErr *edesy.APIError
    if errors.As(err, &apiErr) {
        switch apiErr.Code {
        case "authentication_error":
            log.Fatal("Invalid API key")
        case "rate_limit_exceeded":
            log.Printf("Rate limited. Retry after %d seconds", apiErr.RetryAfter)
        default:
            log.Printf("API error: %s", apiErr.Message)
        }
    }
    log.Fatal(err)
}
```

## Webhooks

### Webhook Signature Verification

#### JavaScript

```typescript
import { verifyWebhookSignature } from '@edesy/voice-agent';

app.post('/webhook', (req, res) => {
  const signature = req.headers['x-edesy-signature'];
  const isValid = verifyWebhookSignature(
    req.body,
    signature,
    process.env.WEBHOOK_SECRET
  );

  if (!isValid) {
    return res.status(401).send('Invalid signature');
  }

  // Process webhook
  const event = req.body;
  console.log(`Received event: ${event.event}`);

  res.status(200).send('OK');
});
```

#### Python

```python
from edesy import verify_webhook_signature

@app.post("/webhook")
def handle_webhook(request):
    signature = request.headers.get("X-Edesy-Signature")
    is_valid = verify_webhook_signature(
        request.data,
        signature,
        os.environ["WEBHOOK_SECRET"],
    )

    if not is_valid:
        return "Invalid signature", 401

    event = request.json
    print(f"Received event: {event['event']}")

    return "OK", 200
```

#### Go

```go
import "github.com/edesy-ai/voice-agent-go/webhook"

func handleWebhook(w http.ResponseWriter, r *http.Request) {
    body, _ := io.ReadAll(r.Body)
    signature := r.Header.Get("X-Edesy-Signature")

    isValid := webhook.VerifySignature(body, signature, os.Getenv("WEBHOOK_SECRET"))
    if !isValid {
        http.Error(w, "Invalid signature", http.StatusUnauthorized)
        return
    }

    var event webhook.Event
    json.Unmarshal(body, &event)
    fmt.Printf("Received event: %s\n", event.Event)

    w.WriteHeader(http.StatusOK)
}
```

## Best Practices

### 1. Use Environment Variables

```typescript
// Never hardcode API keys
const client = new EdesyClient({
  apiKey: process.env.EDESY_API_KEY,
});
```

### 2. Handle Rate Limits

```typescript
import { RateLimitError } from '@edesy/voice-agent';

async function createCallWithRetry(params, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await client.calls.create(params);
    } catch (error) {
      if (error instanceof RateLimitError) {
        await sleep(error.retryAfter * 1000);
        continue;
      }
      throw error;
    }
  }
}
```

### 3. Use Async/Await

```typescript
// Good
const call = await client.calls.create(params);

// Avoid callback hell
client.calls.create(params).then(call => {
  client.calls.get(call.id).then(details => {
    // ...
  });
});
```

## Next Steps

- [REST API](https://edesy.in/docs/voice-agent/api) - API reference
- [WebSocket](https://edesy.in/docs/voice-agent/api/websocket) - Real-time streaming
- [Webhooks](https://edesy.in/docs/voice-agent/features/webhooks) - Event handling
