# How to Access Raw Response Headers Using the Anthropic Python SDK

> Easily access raw response headers using the Anthropic Python SDK. Learn how to get the underlying httpx.Response with the .with_raw_response accessor today.

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

---

**Use the `.with_raw_response` accessor on any resource to return a `LegacyAPIResponse` object containing the underlying `httpx.Response` and its headers.**

The **anthropics/anthropic-sdk-python** library wraps HTTP calls in convenient Pydantic models, but production applications often need to inspect **raw response headers** for rate-limit tracking, request IDs, or debugging. While the SDK automatically surfaces the request ID via the `_request_id` property, custom headers and detailed HTTP metadata remain accessible only through the low-level response object.

## Using the `.with_raw_response` Accessor

The SDK exposes a dedicated `.with_raw_response` property on every resource that returns a thin wrapper around the standard client methods. According to the source code in [[`src/anthropic/_client.py`](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/_client.py)](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/_client.py#L42-L48), the main `Anthropic` and `AsyncAnthropic` clients define this property to return an `AnthropicWithRawResponse` instance.

When you invoke a method through this accessor—such as `client.messages.with_raw_response.create()`—the call returns a **`LegacyAPIResponse`** object instead of the parsed Pydantic model. As implemented in [[`src/anthropic/_legacy_response.py`](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/_legacy_response.py)](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/_legacy_response.py), this wrapper stores the original `httpx.Response` and exposes:

- `.headers` – A case-insensitive dictionary of HTTP headers
- `.status_code` – The integer HTTP status code
- `.parse()` – A method to convert the raw body back into the standard typed model

Each resource defines its own *WithRawResponse* class. For example, [[`src/anthropic/resources/messages/messages.py`](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/resources/messages/messages.py)](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/resources/messages/messages.py#L84-L96) implements `MessagesWithRawResponse`, which forwards calls to the underlying API method while ensuring the raw HTTP response is preserved.

The official documentation mirrors this approach in the README section ["Accessing raw response data (e.g. headers)"](https://github.com/anthropics/anthropic-sdk-python/blob/main/README.md#accessing-raw-response-data-e-g-headers).

## Retrieving Headers from Synchronous Requests

To access headers from a standard blocking call, prefix your method invocation with `.with_raw_response`:

```python
from anthropic import Anthropic

client = Anthropic()

# Request the Messages endpoint while preserving the raw HTTP response

raw_resp = client.messages.with_raw_response.create(
    max_tokens=256,
    messages=[{"role": "user", "content": "Hello, Claude"}],
    model="claude-sonnet-20240229",
)

# Access any header (e.g., custom metadata or rate-limit info)

print("X-My-Header →", raw_resp.headers.get("X-My-Header"))

# Parse the response body into the standard Message model

msg = raw_resp.parse()
print("Assistant reply →", msg.content)

```

The `raw_resp.headers` attribute provides direct access to the case-insensitive header dictionary from the underlying `httpx.Response`. Calling `raw_resp.parse()` returns the standard `Message` model without requiring a second network request.

## Accessing Headers in Async Applications

The asynchronous client mirrors this pattern exactly. Await the method call on the `with_raw_response` accessor, then await `.parse()` to deserialize the model:

```python
import asyncio
from anthropic import AsyncAnthropic

async def main() -> None:
    client = AsyncAnthropic()

    raw_resp = await client.messages.with_raw_response.create(
        max_tokens=256,
        messages=[{"role": "user", "content": "Hi, async Claude"}],
        model="claude-sonnet-20240229",
    )

    print("X-My-Header →", raw_resp.headers.get("X-My-Header"))

    # Parse the response model asynchronously

    msg = await raw_resp.parse()
    print("Assistant reply →", msg.content)

    await client.aclose()

asyncio.run(main())

```

## Inspecting Headers During Streaming

When using streaming responses, you can still access headers by combining `.with_streaming_response` with a context manager. The streaming response object exposes the same `.headers` attribute before you consume the body:

```python
from anthropic import Anthropic

client = Anthropic()

with client.messages.with_streaming_response.create(
    max_tokens=512,
    messages=[{"role": "user", "content": "Stream me something"}],
    model="claude-sonnet-20240229",
) as stream:
    # Headers are available immediately without consuming the stream

    print("Rate-Limit-Remaining →", stream.headers.get("Rate-Limit-Remaining"))

    # Iterate over Server-Sent Events (SSE)

    for line in stream.iter_lines():
        print(line)

```

As defined in [[`src/anthropic/_response.py`](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/_response.py)](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/_response.py), the streaming response wrapper ensures the HTTP connection closes properly when exiting the context manager, while still exposing header metadata upfront.

## Summary

- **Use `.with_raw_response`** on any resource (e.g., `client.messages.with_raw_response.create()`) to receive a `LegacyAPIResponse` instead of a parsed model.
- **Access headers** via the `.headers` property, which returns a case-insensitive dictionary from the underlying `httpx.Response`.
- **Parse the body** by calling `.parse()` (or `await raw_resp.parse()` in async contexts) to convert the raw response back into the standard Pydantic model.
- **Stream with headers** using `.with_streaming_response` and a context manager; headers are available immediately via `stream.headers`.

## Frequently Asked Questions

### How do I access the request ID from a response?

The SDK automatically extracts the `request_id` from response headers and exposes it via the `_request_id` property on every returned model. However, if you need the raw header value or additional metadata, use `.with_raw_response` and inspect `raw_resp.headers.get("request-id")`.

### Does using `.with_raw_response` impact performance?

No. The accessor returns the same underlying HTTP response that the SDK already processed; it simply skips the automatic Pydantic parsing step until you explicitly call `.parse()`. No additional network requests are made.

### Can I access response headers when using the streaming API?

Yes. When using `.with_streaming_response.create()`, the returned context manager exposes `.headers` immediately upon entering the `with` block, before any stream data is consumed. This allows you to check rate limits or request IDs before processing the streamed content.

### What is the difference between `LegacyAPIResponse` and `APIResponse`?

`LegacyAPIResponse` (defined in [[`src/anthropic/_legacy_response.py`](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/_legacy_response.py)](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/_legacy_response.py)) is returned by `.with_raw_response` and wraps a complete `httpx.Response`. `APIResponse` (defined in [[`src/anthropic/_response.py`](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/_response.py)](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/_response.py)) is returned by `.with_streaming_response` and wraps a streaming response that must be consumed within a context manager.