Metadata-Version: 2.5
Name: dialogbrain
Version: 1.0.0
Summary: Python SDK for the DialogBrain messaging API
Project-URL: Homepage, https://dialogbrain.com
Project-URL: Documentation, https://docs.dialogbrain.com
Project-URL: Repository, https://github.com/saloprj/dialogbrain
Author-email: DialogBrain <dev@dialogbrain.com>
License: MIT
Keywords: ai,api,dialogbrain,messaging
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27
Provides-Extra: langchain
Requires-Dist: langchain-mcp-adapters>=0.1.0; extra == 'langchain'
Requires-Dist: mcp>=1.0.0; extra == 'langchain'
Description-Content-Type: text/markdown

# DialogBrain Python SDK

Python client for the [DialogBrain](https://dialogbrain.com) API: agents, calls, conversations, contacts, webhooks and billing, over one API key.

## Install

```bash
pip install dialogbrain

# With LangChain/MCP support:
pip install "dialogbrain[langchain]"
```

## Quick start

```python
import asyncio
from dialogbrain import DialogBrainClient

async def main():
    async with DialogBrainClient(api_key="db_live_YOUR_KEY") as client:
        agent = await client.agents.create(name="Booking assistant", prompt_text="You confirm bookings.")
        call = await client.calls.create(agent_id=agent["id"], target="+66812345678")
        print(call["call_id"], call["status"])

asyncio.run(main())
```

Prefer blocking code? Same surface, no `await`:

```python
from dialogbrain import SyncDialogBrainClient

with SyncDialogBrainClient(api_key="db_live_YOUR_KEY") as client:
    for a in client.agents.list()["agents"]:
        print(a["id"], a["name"])
```

## What you get

| resource | methods |
|---|---|
| `agents` | `create` `list` `get` `update` `delete` `get_activity` `list_traces` `get_trace` `get_prompt_blocks` `put_prompt_blocks` |
| `calls` | `create` `list` `get` `hangup` `get_transcript` `get_recording` |
| `prompt_blocks` | `list` — the registry of blocks an agent's system prompt is built from |
| `conversations` | `list` `list_page` `get` `get_messages` |
| `messages` | `send` |
| `contacts` | `list` `list_page` `get` `update` `discover` (`search`) `sync` |
| `webhooks` | `list` `create` `delete` `activate` `list_deliveries` |
| `billing` | `get_balance` `list_transactions` |
| `search` | `rag` |
| `handoffs` | `request` (also `client.handoff(...)`) |

Every method is generated from the API's OpenAPI spec, so the SDK cannot fall behind the API: a test fails if they disagree.

## Things the SDK does for you

**Idempotency.** `agents.create` and `calls.create` require an `Idempotency-Key` — a retried create must never dial someone twice or make two agents. The SDK mints one per call. Pass your own to make a retry *deliberately* replay:

```python
await client.calls.create(agent_id=1, target="+66812345678", idempotency_key=order_id)
```

If another request with the same key is mid-flight you get the server's 409 "in progress"; the SDK waits `Retry-After` and retries once, which replays the first request's result.

**Partial updates.** `update()` sends only what you pass. `None` means "leave it alone", not "clear it".

**Errors.** Every non-2xx raises `DialogBrainError` with `.status` and the server's `.detail`:

```python
from dialogbrain import DialogBrainError

try:
    await client.agents.get(999)
except DialogBrainError as e:
    print(e.status, e.detail)   # 404 Agent 999 not found
```

## Upgrading from 0.1.0

Nothing you wrote breaks. `conversations.list()` still returns a bare list; `conversations.get(conversation_id=...)`, `contacts.search(...)` and `client.handoff(...)` still work alongside the spec's own names. See `CHANGELOG.md`.

## Regenerating after an API change

```bash
curl -s https://api.dialogbrain.com/openapi.json > openapi.json
python scripts/generate.py
pytest
```

## Docs

[docs.dialogbrain.com](https://docs.dialogbrain.com)
