<!-- Generated from TradeReady.io docs. Visit https://tradeready.io/docs for the full experience. -->

---
title: Async Client
description: AsyncAgentExchangeClient — async/await Python client for concurrent agents
---

`AsyncAgentExchangeClient` is the async counterpart to `AgentExchangeClient`. It exposes an identical API surface of 37 methods — every method is an `async def` that must be awaited.

## When to Use Async vs Sync

**Use async when...:**

- Running multiple agent tasks in parallel with `asyncio.gather`
- Building a FastAPI or other async web service that serves agent requests
- Integrating with async frameworks like LangGraph or any `asyncio`-based tool
- You need high throughput from a single process (many concurrent HTTP calls)
**Use sync when...:**

- Writing a straightforward trading script that runs one task at a time
- Integrating with synchronous frameworks like LangChain's `Tool` or CrewAI's `@tool`
- The simplicity of `client.get_price("BTCUSDT")` is preferable to `await client.get_price("BTCUSDT")`

## Import and Construction

```python
from agentexchange import AsyncAgentExchangeClient

# Context manager — recommended
async with AsyncAgentExchangeClient(
    api_key="ak_live_...",
    api_secret="sk_live_...",
    base_url="http://localhost:8000",  # default
    timeout=30.0,                      # default
) as client:
    price = await client.get_price("BTCUSDT")
    print(price.price)
```

Or construct and close manually:

```python
client = AsyncAgentExchangeClient(
    api_key="ak_live_...",
    api_secret="sk_live_...",
)
try:
    price = await client.get_price("BTCUSDT")
finally:
    await client.close()
```

## Basic Usage

All methods are identical to the sync client, with `await` added:

```python
import asyncio
import os
from decimal import Decimal
from dotenv import load_dotenv
from agentexchange import AsyncAgentExchangeClient

load_dotenv()

async def main():
    async with AsyncAgentExchangeClient(
        api_key=os.environ["AGENTEXCHANGE_API_KEY"],
        api_secret=os.environ["AGENTEXCHANGE_API_SECRET"],
    ) as client:

        # Fetch live price
        price = await client.get_price("BTCUSDT")
        print(f"BTC: ${price.price}")

        # Check balance before ordering
        balance = await client.get_balance()
        print(f"Available USDT: {balance.balances[0].available}")

        # Place a market order
        order = await client.place_market_order(
            symbol="BTCUSDT",
            side="buy",
            quantity=Decimal("0.001"),
        )
        print(f"Order {order.order_id}: {order.status}")

        # Check portfolio
        portfolio = await client.get_portfolio()
        print(f"Total equity: ${portfolio.total_equity}  ROI: {portfolio.roi_pct}%")

asyncio.run(main())
```

## Running Multiple Tasks Concurrently

The async client shines when you need to make several independent calls simultaneously. Use `asyncio.gather` to run them in parallel instead of sequentially:

```python
import asyncio
from agentexchange import AsyncAgentExchangeClient

async def fetch_market_snapshot(client, symbol: str) -> dict:
    """Fetch price and 24h ticker for one symbol concurrently."""
    price, ticker = await asyncio.gather(
        client.get_price(symbol),
        client.get_ticker(symbol),
    )
    return {
        "symbol": symbol,
        "price": str(price.price),
        "change_24h": str(ticker.change_pct),
        "volume": str(ticker.volume),
    }

async def main():
    async with AsyncAgentExchangeClient(
        api_key=os.environ["AGENTEXCHANGE_API_KEY"],
        api_secret=os.environ["AGENTEXCHANGE_API_SECRET"],
    ) as client:

        # Fetch snapshots for 5 coins simultaneously
        symbols = ["BTCUSDT", "ETHUSDT", "SOLUSDT", "BNBUSDT", "ADAUSDT"]
        snapshots = await asyncio.gather(
            *[fetch_market_snapshot(client, s) for s in symbols]
        )
        for snap in snapshots:
            print(f"{snap['symbol']}: ${snap['price']}  ({snap['change_24h']}%)")

asyncio.run(main())
```

Compared to the sync client, this reduces latency from `5 × request_time` to `1 × request_time`.

## Running Multiple Independent Agent Tasks

```python
import asyncio
from agentexchange import AsyncAgentExchangeClient

async def run_agent_task(client, task_description: str) -> str:
    """Stub for an agent task that uses the client."""
    portfolio = await client.get_portfolio()
    return f"Task '{task_description}' — equity: ${portfolio.total_equity}"

async def run_concurrent_agents():
    async with AsyncAgentExchangeClient(
        api_key=os.environ["AGENTEXCHANGE_API_KEY"],
        api_secret=os.environ["AGENTEXCHANGE_API_SECRET"],
    ) as client:

        tasks = [
            "What is the current BTC price?",
            "What is my portfolio value?",
            "List my open orders.",
            "What were my last 5 trades?",
            "What is my 7-day Sharpe ratio?",
        ]

        results = await asyncio.gather(
            *[run_agent_task(client, t) for t in tasks]
        )
        for result in results:
            print(result)

asyncio.run(run_concurrent_agents())
```

## Using with FastAPI

When building an API service that runs agent operations as async tasks:

```python
import asyncio
import os
from contextlib import asynccontextmanager
from fastapi import FastAPI
from agentexchange import AsyncAgentExchangeClient

# Shared client held for the lifetime of the application
_client: AsyncAgentExchangeClient | None = None

@asynccontextmanager
async def lifespan(app: FastAPI):
    global _client
    _client = AsyncAgentExchangeClient(
        api_key=os.environ["AGENTEXCHANGE_API_KEY"],
        api_secret=os.environ["AGENTEXCHANGE_API_SECRET"],
    )
    yield
    await _client.close()

app = FastAPI(lifespan=lifespan)

@app.get("/portfolio")
async def get_portfolio():
    portfolio = await _client.get_portfolio()
    return {
        "total_equity": str(portfolio.total_equity),
        "roi_pct": str(portfolio.roi_pct),
    }

@app.post("/order")
async def place_order(symbol: str, side: str, quantity: str):
    from decimal import Decimal
    order = await _client.place_market_order(
        symbol=symbol,
        side=side,
        quantity=Decimal(quantity),
    )
    return {"order_id": str(order.order_id), "status": order.status}
```

## Error Handling in Async Code

Exception handling is identical to the sync client — the same exception classes are raised:

```python
import asyncio
import time
from agentexchange import AsyncAgentExchangeClient
from agentexchange.exceptions import (
    InsufficientBalanceError,
    RateLimitError,
    InvalidSymbolError,
    AgentExchangeError,
)

async def safe_buy(client, symbol: str, quantity: str):
    from decimal import Decimal
    try:
        order = await client.place_market_order(
            symbol=symbol,
            side="buy",
            quantity=Decimal(quantity),
        )
        return order
    except InsufficientBalanceError as e:
        print(f"Need {e.required} USDT, only have {e.available}")
        return None
    except RateLimitError as e:
        wait = e.retry_after or 60
        print(f"Rate limited — waiting {wait}s")
        await asyncio.sleep(wait)
        return await safe_buy(client, symbol, quantity)  # one retry
    except InvalidSymbolError as e:
        print(f"Unknown symbol: {e.symbol}")
        return None
    except AgentExchangeError as e:
        print(f"Error {e.code}: {e}")
        return None
```

> **Info:**
> The sync and async clients share no base class — the duplication is intentional to avoid runtime complexity. Every method on `AgentExchangeClient` has an identical `async def` version on `AsyncAgentExchangeClient`.

## Full Method Reference

The async client exposes the exact same 37 methods as the sync client. See the [Sync Client reference](/docs/sdk/sync-client) for the complete list — prefix each call with `await`.

```python
# Sync
price = client.get_price("BTCUSDT")

# Async
price = await client.get_price("BTCUSDT")
```

## Further Reading

- [Sync Client](/docs/sdk/sync-client) — full method reference with examples
- [WebSocket Client](/docs/sdk/websocket-client) — real-time streaming (always async)
- [Error Handling](/docs/sdk/error-handling) — exception hierarchy and retry patterns
