> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://agentphone.to/docs/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://agentphone.to/docs/_mcp/server.

# TypeScript SDK

> Official TypeScript/JavaScript SDK for the AgentPhone API

The official AgentPhone TypeScript library provides server-side access to the API. Examples below are checked against the published `agentphone@1.0.25`. Some endpoints return `unknown`; inspect or validate those results before accessing fields. Keep your API key on the server.

[![npm](https://img.shields.io/npm/v/agentphone)](https://www.npmjs.com/package/agentphone)

## Installation

```sh
npm install agentphone
```

Set `AGENTPHONE_API_KEY` in the server process before running examples.

```bash
export AGENTPHONE_API_KEY="YOUR_API_KEY"
```

## Quick start

```typescript
import { AgentPhoneClient } from "agentphone";

const client = new AgentPhoneClient({ token: process.env.AGENTPHONE_API_KEY!, maxRetries: 0 });

// Create an agent
const agent = await client.agents.createAgent({
  name: "Support Bot",
  voiceMode: "hosted",
  systemPrompt: "You are a helpful support assistant.",
});

// Buy a number and attach it
const number = await client.numbers.createNumber();
await client.agents.attachNumberToAgent({
  agent_id: agent.id,
  numberId: number.id,
});

// Make a call
await client.calls.createOutboundCall({
  agentId: agent.id,
  toNumber: "+15559876543",
  initialGreeting: "Hi, this is Support Bot!",
});
```

## Request and response types

The SDK exports all request and response types under the `AgentPhone` namespace:

```typescript
import { AgentPhone } from "agentphone";

const request: AgentPhone.CreateAgentRequest = {
  name: "Sales Agent",
  voiceMode: "hosted",
  systemPrompt: "You are a helpful sales assistant.",
};
```

The published 1.0.25 SDK omits `limit` from several list-request types. Use `requestOptions.queryParams` as shown below to pass that REST parameter. Method names and request fields differ from the Python SDK; do not copy Python calls into TypeScript.

The quick start buys a number and places a real call. See [pricing](/docs/usage) and [outbound calling requirements](/docs/documentation/guides/calls#create-outbound-call) before running it. Use a recipient you control.

## Resources

### Agents

```typescript
// List all agents
const agents = await client.agents.listAgents({ offset: 0 }, { queryParams: { limit: 20 } });

// Create an agent
const agent = await client.agents.createAgent({
  name: "Support Bot",
  description: "Handles customer inquiries",
  voiceMode: "hosted",
  systemPrompt: "You are a helpful support agent.",
  beginMessage: "Hello! How can I help you?",
});

// Get agent details
const existingAgent = await client.agents.getAgent({ agent_id: "agt_abc123" });

// Update an agent
await client.agents.updateAgent({
  agent_id: "agt_abc123",
  name: "Updated Bot",
  systemPrompt: "New prompt",
});

// Delete an agent
await client.agents.deleteAgent({ agent_id: "agt_abc123" });

// Attach a number to an agent
await client.agents.attachNumberToAgent({
  agent_id: "agt_abc123",
  numberId: "num_xyz789",
});

// List conversations for an agent
const convos = await client.agents.listAgentConversations({
  agent_id: "agt_abc123",
});

// List calls for an agent
const calls = await client.agents.listAgentCalls({
  agent_id: "agt_abc123",
});
```

### Numbers

```typescript
// List numbers
const numbers = await client.numbers.listNumbers({}, { queryParams: { limit: 20 } });

// Provision a new number
const number = await client.numbers.createNumber();

// Get messages for a number
const messages = await client.numbers.getMessages({
  number_id: "num_xyz789",
  limit: 50,
  before: "2024-01-01T00:00:00Z", // cursor-based pagination
});

// Release a number (irreversible)
await client.numbers.deleteNumber({ number_id: "num_xyz789" });
```

### Conversations

```typescript
// List all conversations
const convos = await client.conversations.listConversations({}, { queryParams: { limit: 20 } });

// Get a conversation with messages
const convo = await client.conversations.getConversation({
  conversation_id: "conv_abc123",
  message_limit: 50,
});

// Update conversation metadata
await client.conversations.updateConversation({
  conversation_id: "conv_abc123",
  metadata: { customerName: "Jane Doe", orderId: "ORD-12345" },
});

// Get paginated messages
const messages = await client.conversations.getConversationMessages({
  conversation_id: "conv_abc123",
  limit: 50,
  before: "2024-01-01T00:00:00Z", // cursor-based pagination
});
```

### Calls

```typescript
// List all calls
const calls = await client.calls.listCalls({}, { queryParams: { limit: 20 } });

// Get a call with transcript
const call = await client.calls.getCall({ call_id: "call_abc123" });

// Make an outbound call
await client.calls.createOutboundCall({
  agentId: "agt_abc123",
  toNumber: "+15559876543",
  initialGreeting: "Hello!",
  systemPrompt: "You are a support agent helping with order inquiries.",
});

// List calls for a specific number
const numberCalls = await client.calls.listCallsForNumber({
  number_id: "num_xyz789",
});
```

### Webhooks

```typescript
// Get webhook config
const webhook = await client.webhooks.getWebhook();

// Create or update webhook
const result = await client.webhooks.createOrUpdateWebhook({
  body: { url: "https://your-server.com/webhook", contextLimit: 10 },
});
console.log(result.secret); // save this!

// View delivery history
const deliveries = await client.webhooks.listDeliveries({ limit: 50 });

// Test webhook
await client.webhooks.testWebhook({ body: { channel: "sms" } });

// Delete webhook
await client.webhooks.deleteWebhook();
```

### Usage

```typescript
// Get usage stats
const usage = await client.usage.getUsage();
console.log(usage.numbers.remaining); // remaining phone numbers
console.log(usage.stats.messagesLast24h); // messages in last 24h
```

## Error handling

```typescript
import { AgentPhoneError } from "agentphone";

try {
  await client.agents.createAgent({ name: "Bot" });
} catch (err) {
  if (err instanceof AgentPhoneError) {
    console.log(err.statusCode); // e.g. 422
    console.log(err.message);
    console.log(err.body);
    console.log(err.rawResponse);
  }
}
```

## Streaming transcripts

In `agentphone@1.0.25`, `calls.streamCallTranscript` reads the SSE response as JSON instead of exposing live events. Use the [HTTP streaming examples](/docs/documentation/guides/calls#stream-transcript-sse) until the package provides a corrected stream interface.

## Recording downloads

In `agentphone@1.0.25`, `calls.getCallRecording` treats the audio response as JSON and does not return usable recording bytes. Download the `recordingUrl` with ordinary HTTP instead; see [Call recording](/docs/documentation/guides/calls#call-recording). Treat that URL as a sensitive bearer link.

## Advanced

### Retries

The SDK defaults to two retries on 408, 429, and 5xx, including writes. The examples set `maxRetries: 0` because a timed-out send, purchase, or call may already have executed. Enable bounded retries on safe reads individually; do not automatically resend an ambiguous write. See [Error handling](/docs/documentation/reference/error-handling).

```typescript
await client.agents.listAgents({}, { maxRetries: 0 }); // disable retries
```

### Timeouts

Default timeout is 60 seconds.

```typescript
await client.agents.listAgents({}, { timeoutInSeconds: 30 });
```

### Abort requests

```typescript
const controller = new AbortController();
const response = client.agents.listAgents({}, {
  abortSignal: controller.signal,
});
controller.abort();
```

### Raw response access

```typescript
const { data, rawResponse } = await client.agents
  .listAgents()
  .withRawResponse();
console.log(rawResponse.headers);
```

### Logging

```typescript
import { AgentPhoneClient, logging } from "agentphone";

const client = new AgentPhoneClient({
  token: process.env.AGENTPHONE_API_KEY!,
  maxRetries: 0,
  logging: {
    level: logging.LogLevel.Debug,
    logger: new logging.ConsoleLogger(),
    silent: false, // defaults to true
  },
});
```

### Runtime compatibility

The SDK works in Node.js 18+, Vercel, Cloudflare Workers, Deno 1.25+, Bun 1.0+, and React Native.

## Links

* [npm package](https://www.npmjs.com/package/agentphone)
* [GitHub organization](https://github.com/AgentPhone-AI)
* [Full API reference](/docs/api-reference)