# How to Use Custom HTTP Clients like httpx with the Anthropic Python SDK

> Configure httpx clients for the Anthropic Python SDK for custom networking. Easily integrate httpx with the SDK's http_client parameter.

- Repository: [Anthropic/anthropic-sdk-python](https://github.com/anthropics/anthropic-sdk-python)
- Tags: how-to-guide
- Published: 2026-02-23

---

**Pass a pre-configured `httpx.Client` or `httpx.AsyncClient` instance to the `http_client` parameter when initializing `Anthropic` or `AsyncAnthropic` to override default networking behavior while maintaining full SDK compatibility.**

The `anthropics/anthropic-sdk-python` repository is built entirely on the `httpx` library, abstracting all HTTP communication through a thin wrapper called `BaseClient`. By leveraging the `http_client` parameter, you can inject your own pre-configured httpx instances to fine-tune timeouts, connection limits, and middleware without modifying the SDK source code.

## Why Inject a Custom HTTP Client?

When you don't provide an `http_client` argument, the SDK automatically constructs default clients (`DefaultHttpxClient` for synchronous operations, `DefaultAsyncHttpxClient` for async) with sensible defaults for timeouts, connection limits, and redirect following. However, passing a custom client enables you to:

- Configure specific **timeout values** for long-running inference requests
- Set custom **connection pool limits** for high-throughput applications
- Implement specific **transport layers** (Unix sockets, custom TLS configurations)
- Add **middleware** via httpx event hooks for logging or request modification
- Use alternative async transports like `aiohttp` instead of the default

## Passing a Custom httpx Client

The `http_client` parameter in [`src/anthropic/_client.py`](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/_client.py) accepts any httpx-compatible instance. The SDK validates the client type in lines 75-84, ensuring you cannot accidentally pass a synchronous client to `AsyncAnthropic` or vice versa.

### Synchronous Custom Clients

For synchronous operations, instantiate `Anthropic` with a configured `httpx.Client`:

```python
import httpx
from anthropic import Anthropic

# Build a custom httpx.Client with your own settings

my_client = httpx.Client(
    timeout=httpx.Timeout(30.0),               # 30-second timeout

    limits=httpx.Limits(max_connections=200),  # larger connection pool

    follow_redirects=True,                     # same as SDK default

)

# Hand the client to the SDK

anthropic = Anthropic(
    api_key="my-anthropic-api-key",
    http_client=my_client,
)

response = anthropic.completions.create(
    model="claude-3-opus-20240229",
    max_tokens=256,
    messages=[{"role": "user", "content": "Explain quantum tunnelling"}],
)
print(response.completion)

```

*Relevant source:* `http_client` handling in [`src/anthropic/_client.py`](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/_client.py) (lines 72-84).

### Asynchronous Custom Clients

For async operations, pass an `httpx.AsyncClient` (or compatible) to `AsyncAnthropic`:

```python
import httpx
from anthropic import AsyncAnthropic

async_client = httpx.AsyncClient(
    timeout=httpx.Timeout(20.0),
    limits=httpx.Limits(max_connections=50),
)

async_anthropic = AsyncAnthropic(
    api_key="my-key",
    http_client=async_client,
)

response = await async_anthropic.completions.create(
    model="claude-3-sonnet-20240229",
    max_tokens=128,
    messages=[{"role": "user", "content": "What is the capital of France?"}],
)

```

Supplying the wrong client type raises a clear `TypeError` during initialization.

## Customizing SDK Defaults

If you want to keep the SDK's default networking behavior (socket keep-alive options, automatic proxy handling) but tweak specific settings, use the SDK's default client classes rather than raw `httpx.Client`.

### Extending DefaultHttpxClient

The `DefaultHttpxClient` and `DefaultAsyncHttpxClient` classes, defined in [`src/anthropic/_base_client.py`](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/_base_client.py) (lines 838-896), inherit from `httpx.Client` and apply SDK-wide defaults before merging your overrides:

```python
from anthropic import Anthropic, DefaultHttpxClient

# Only override the timeout; everything else stays as the SDK defines it

default_like = DefaultHttpxClient(timeout=10.0)

anthropic = Anthropic(api_key="my-key", http_client=default_like)

```

These classes handle automatic proxy configuration from environment variables and set socket options that the SDK expects.

### Using aiohttp Transport

To use `aiohttp` as the underlying transport instead of httpx's default, install the optional dependency and use `DefaultAioHttpClient`:

```bash
pip install "anthropic[aiohttp]"

```

```python
import httpx
from anthropic import AsyncAnthropic, DefaultAioHttpClient

# The SDK's DefaultAioHttpClient wraps httpx-aiohttp and respects SDK defaults

aio_client = DefaultAioHttpClient(
    timeout=httpx.Timeout(20.0),
    limits=httpx.Limits(max_connections=50),
)

async_anthropic = AsyncAnthropic(
    api_key="my-key",
    http_client=aio_client,
)

```

*Relevant source:* async default client in [`src/anthropic/_base_client.py`](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/_base_client.py) (lines 1520-1534).

## Advanced Configuration Patterns

### Request Logging with Event Hooks

Because `DefaultHttpxClient` inherits from `httpx.Client`, you can use any httpx feature including `event_hooks` for request/response middleware:

```python
import httpx
from anthropic import Anthropic, DefaultHttpxClient

def log_request(request: httpx.Request):
    print(f"→ {request.method} {request.url}")

client = DefaultHttpxClient(event_hooks={"request": [log_request]})

anthropic = Anthropic(api_key="my-key", http_client=client)

```

### Proxy Configuration

The default client classes automatically read `HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY`, and `NO_PROXY` environment variables via the helper in [`src/anthropic/_utils/_httpx.py`](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/_utils/_httpx.py). You can verify this behavior matches the SDK test suite:

```python
import os
from anthropic import DefaultHttpxClient

os.environ["HTTPS_PROXY"] = "https://proxy.example.org"

client = DefaultHttpxClient()
assert any(mount.pattern == "https://" for mount in client._mounts.items())

```

For custom clients, configure `mounts` directly on your `httpx.Client` instance before passing it to the SDK.

## How the SDK Handles HTTP Clients Internally

The SDK's internal `BaseClient` class serves as the abstraction layer for all HTTP operations. When you provide a custom client:

1. **Validation**: [`src/anthropic/_client.py`](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/_client.py) checks that the client type matches the sync/async nature of the Anthropic client class
2. **Default Construction**: If you pass `None`, the SDK instantiates `_DefaultHttpxClient` or `_DefaultAsyncHttpxClient` from [`src/anthropic/_base_client.py`](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/_base_client.py)
3. **Transport Setup**: Default clients build a custom transport that adds socket keep-alive options and merges proxy configurations from environment variables
4. **Lifecycle Management**: The SDK uses your client for all requests but does not automatically close it, allowing connection reuse across multiple SDK instances

## Summary

- Pass custom `httpx.Client` or `httpx.AsyncClient` instances via the `http_client` parameter to `Anthropic` or `AsyncAnthropic`
- Match synchronous clients to `Anthropic` and asynchronous clients to `AsyncAnthropic` to avoid `TypeError` exceptions
- Use `DefaultHttpxClient` or `DefaultAsyncHttpxClient` to preserve SDK networking defaults while tweaking specific settings like timeouts
- Install `anthropic[aiohttp]` and use `DefaultAioHttpClient` to use aiohttp as the underlying async transport
- The SDK respects all httpx configuration including `timeout`, `limits`, `transport`, `mounts`, and `event_hooks`

## Frequently Asked Questions

### Can I use aiohttp instead of httpx with the Anthropic SDK?

Yes. Install the optional dependency with `pip install "anthropic[aiohttp]"` and pass an instance of `DefaultAioHttpClient` (or any `httpx.AsyncClient` configured with the aiohttp transport) to the `http_client` parameter of `AsyncAnthropic`. This is implemented in [`src/anthropic/_base_client.py`](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/_base_client.py).

### What happens if I pass the wrong client type to the SDK?

The SDK validates the client type in [`src/anthropic/_client.py`](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/_client.py) (lines 75-84). Passing a synchronous `httpx.Client` to `AsyncAnthropic` or an `httpx.AsyncClient` to the synchronous `Anthropic` class raises a clear `TypeError` indicating the expected client type for that class.

### How do I configure proxy settings when using a custom HTTP client?

When using `DefaultHttpxClient` or `DefaultAsyncHttpxClient`, the SDK automatically reads `HTTP_PROXY`, `HTTPS_PROXY`, and `NO_PROXY` environment variables via the helper in [`src/anthropic/_utils/_httpx.py`](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/_utils/_httpx.py). For fully custom clients, configure the `mounts` parameter directly on your `httpx.Client` instance before passing it to the SDK.

### Will the SDK close my custom HTTP client automatically?

No. The SDK deliberately does not close custom clients passed via `http_client` to avoid interfering with connection reuse patterns. You must manage the client lifecycle yourself, including calling `.close()` or using the client as a context manager (`with httpx.Client() as client:`) in your application code.