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

# AutoGen integration

> Give a Microsoft AutoGen agent Dial tools for SMS, OTP, and voice calls — phone identity for enterprise multi-agent systems.

`dial-autogen` packages Dial's operations as [Microsoft AutoGen](https://microsoft.github.io/autogen/)
tools, so an `AssistantAgent` can send messages, receive OTP codes, and place calls as part of its
work. It's the AutoGen sibling of the [LangChain integration](/documentation/sdks/langchain): each
tool is an `autogen_core.tools.FunctionTool` wrapping the [Python SDK](/documentation/sdks/python)
client — it adds nothing to the REST contract, it just shapes Dial's operations into AutoGen tools.

Targeting Microsoft's newer **Agent Framework** (the 1.0 successor to AutoGen + Semantic Kernel)
instead? Use [`dial-agentframework`](/documentation/sdks/agentframework). Both expose the same Dial
tools; pick the one that matches your stack.

## Install

```bash
pip install dial-autogen
```

This pulls in `dial-sdk` and `autogen-agentchat`.

## Give the tools to an agent

Build one [`DialClient`](/documentation/sdks/python), pass it to `dial_tools`, and hand
the list to an agent. Every tool shares that one client — a single connection pool for the
whole agent session — and you own its lifecycle (`await client.close()` when done).
Enterprise / Azure AI builds typically drive AutoGen with an Azure OpenAI model client:

```python
from autogen_agentchat.agents import AssistantAgent
from autogen_ext.models.openai import AzureOpenAIChatCompletionClient
from dial_sdk import DialClient, DialConfig
from dial_autogen import dial_tools

dial = DialClient(DialConfig(api_key="sk_live_..."))  # close with `await dial.close()`

model_client = AzureOpenAIChatCompletionClient(
    azure_deployment="gpt-4o",
    model="gpt-4o",
    api_version="2024-10-21",
    azure_endpoint="https://<your-resource>.openai.azure.com/",
)

agent = AssistantAgent(
    name="phone_agent",
    model_client=model_client,
    tools=dial_tools(dial),
    system_message="You operate the team's Dial phone number for SMS, OTP, and voice calls.",
)
```

`dial_tools` returns the full set, all sharing your client — the analog of LangChain's
`DialToolkit.get_tools()`. AutoGen runs tools in an async loop, so the Dial tools are
**async-native** — there's no async→sync bridge (the one difference from the
[CrewAI sibling](/documentation/sdks/crewai)).

## Available tools

Each builder takes your shared `DialClient` and returns one `FunctionTool`:

| Builder                      | Tool name               | Action                                                |
| ---------------------------- | ----------------------- | ----------------------------------------------------- |
| `list_numbers_tool`          | `list_numbers`          | List your phone numbers                               |
| `purchase_number_tool`       | `purchase_number`       | Provision a new number (billable)                     |
| `set_number_properties_tool` | `set_number_properties` | Update a number's nickname or inbound instruction     |
| `send_message_tool`          | `send_message`          | Send an SMS                                           |
| `list_messages_tool`         | `list_messages`         | List recent messages                                  |
| `make_call_tool`             | `make_call`             | Place an AI voice call                                |
| `list_calls_tool`            | `list_calls`            | List recent calls                                     |
| `get_call_tool`              | `get_call`              | Fetch one call by id                                  |
| `get_billing_tool`           | `get_billing`           | Credit balance, subscription, per-number mode         |
| `wait_for_message_tool`      | `wait_for_message`      | Block until the next inbound SMS arrives, or time out |

### Or pick individual tools

```python
from dial_autogen import send_message_tool, wait_for_message_tool

tools = [
    send_message_tool(dial),
    wait_for_message_tool(dial),
]
```

## Handling OTP

The reason an agent needs phone identity: receive a verification code and act on it.
`wait_for_message` blocks until the next inbound SMS arrives, so an agent can trigger a
signup that texts a code to your Dial number, read the code, and enter it back into the form.

```python
agent = AssistantAgent(
    name="signup_agent",
    model_client=model_client,
    tools=dial_tools(dial),
    system_message="You complete phone-verified signups by reading the OTP sent to our Dial number.",
)

result = await agent.run(
    task="Wait up to 120 seconds for the inbound verification code on our Dial number, then report it."
)
print(result.messages[-1].content)
```

A full runnable example is in [`examples/signup_autogen.ipynb`](https://github.com/GENWAY-AI/dial/blob/main/sdk-autogen/examples/signup_autogen.ipynb).

`send_message` is a write action and **isn't idempotent** — a re-invoke after a failure can
send a duplicate. `make_call` accepts an `idempotency_key`. See
[Retries and idempotency](/documentation/reference/errors#retries-and-idempotency).

## Receiving events beyond a single wait

`wait_for_message` is a one-shot wait, backed by a **presence-based** stream (not
at-least-once — missed events replay only on reconnect within \~2 minutes). To react to
inbound SMS or completed calls durably, use the [Python SDK's](/documentation/sdks/python)
`new_events_connection()` directly, or register a [webhook](/documentation/platform/webhooks)
(signed and retried at-least-once), and feed events into your agent however suits your app.