request_too_large

HTTP 413 Payload Limit Not Retryable

Your HTTP request body exceeds Anthropic's 10 MB limit. Almost always caused by large base64-encoded images or too many images in one call. Compress or chunk before sending.

What the error looks like

{
  "type": "error",
  "error": {
    "type": "request_too_large",
    "message": "Request body is too large. Maximum size is 10485760 bytes (10 MB)."
  }
}

The 10 MB limit breakdown

  • Limit applies to the raw HTTP request body (JSON payload), NOT the token count
  • A 5 MB JPEG = ~6.7 MB base64-encoded (base64 adds ~33% overhead)
  • Multiple images compound fast: 3 × 3 MB images = ~12 MB → over limit
  • Text-only prompts rarely hit this limit even at max tokens

Fix: Compress images before encoding

from PIL import Image
import io
import base64

def compress_image(image_path, max_size_kb=800, quality=85):
    """Compress image to under max_size_kb before base64 encoding."""
    with Image.open(image_path) as img:
        # Convert to RGB if needed (handles PNG with transparency)
        if img.mode in ('RGBA', 'P'):
            img = img.convert('RGB')

        # Resize if very large
        max_dim = 1568   # Claude's max recommended image dimension
        if max(img.size) > max_dim:
            img.thumbnail((max_dim, max_dim), Image.LANCZOS)

        # Compress to JPEG
        buf = io.BytesIO()
        img.save(buf, format='JPEG', quality=quality, optimize=True)
        buf.seek(0)

        size_kb = len(buf.getvalue()) / 1024
        print(f"Compressed to {size_kb:.1f} KB")

        return base64.standard_b64encode(buf.getvalue()).decode('utf-8')

img_b64 = compress_image("large_screenshot.png")

response = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    messages=[{
        "role": "user",
        "content": [
            {"type": "text", "text": "Describe this image"},
            {"type": "image", "source": {
                "type": "base64",
                "media_type": "image/jpeg",
                "data": img_b64
            }}
        ]
    }]
)

Fix: Use URL instead of base64

If your image is publicly accessible, use the URL source type — no payload size issue:

response = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    messages=[{
        "role": "user",
        "content": [
            {"type": "text", "text": "What's in this image?"},
            {"type": "image", "source": {
                "type": "url",
                "url": "https://your-cdn.com/image.jpg"
            }}
        ]
    }]
)

Fix: Process images one at a time

def process_images_individually(image_paths, prompt):
    """Process each image in a separate API call."""
    results = []
    for path in image_paths:
        img_b64 = compress_image(path)
        response = client.messages.create(
            model="claude-sonnet-4-6",
            max_tokens=512,
            messages=[{
                "role": "user",
                "content": [
                    {"type": "text", "text": prompt},
                    {"type": "image", "source": {
                        "type": "base64",
                        "media_type": "image/jpeg",
                        "data": img_b64
                    }}
                ]
            }]
        )
        results.append(response.content[0].text)
    return results