Error Handling
The SDK throws typed exceptions when something goes wrong. All API errors, HTTP failures, and response parsing issues are covered.
API errors
When the Anthropic API returns an error response, the client throws Anthropic\Exceptions\ErrorException:
use Anthropic\Exceptions\ErrorException;
try {
$response = $client->messages()->create([
'model' => 'claude-sonnet-4-6',
'max_tokens' => 1024,
'messages' => [
['role' => 'user', 'content' => 'Hello'],
],
]);
} catch (ErrorException $e) {
$e->getMessage(); // 'Overloaded'
$e->getErrorType(); // 'overloaded_error'
$e->getStatusCode(); // 529
}
ErrorException provides three methods:
| Method | Returns | Description |
|---|---|---|
getMessage() |
string |
The error message from the API |
getErrorType() |
?string |
The error type (e.g., invalid_request_error, authentication_error, overloaded_error) |
getStatusCode() |
int |
The HTTP status code |
The raw PSR-7 response is also available on the response property if you need to inspect headers or the full body:
$e->response; // Psr\Http\Message\ResponseInterface or null
Note: For streamed requests, the status code might be
200even when an error occurs, because the HTTP response started successfully before the error happened mid-stream.
Common API errors
| Status | Error type | Typical cause |
|---|---|---|
| 400 | invalid_request_error |
Bad parameters, missing required fields |
| 401 | authentication_error |
Invalid or missing API key |
| 402 | billing_error |
Issue with billing or payment information |
| 403 | permission_error |
API key doesn't have access to the requested resource |
| 404 | not_found_error |
Invalid model name or resource ID |
| 413 | request_too_large |
Request exceeds the maximum allowed size (32 MB for Messages, 256 MB for Batches) |
| 429 | rate_limit_error |
Too many requests (see below) |
| 500 | api_error |
Server-side issue |
| 504 | timeout_error |
Request timed out while processing; consider using streaming |
| 529 | overloaded_error |
API is temporarily overloaded |
Rate limit errors
HTTP 429 responses throw Anthropic\Exceptions\RateLimitException, a subclass of ErrorException. Since it extends ErrorException, existing catch (ErrorException $e) blocks will catch it too. If you want to handle rate limits specifically, catch it first:
use Anthropic\Exceptions\RateLimitException;
use Anthropic\Exceptions\ErrorException;
try {
$response = $client->messages()->create([...]);
} catch (RateLimitException $e) {
// Rate limited: check when you can retry
$retryAfter = $e->response->getHeaderLine('Retry-After');
// Wait and retry
sleep((int) $retryAfter);
} catch (ErrorException $e) {
// All other API errors
}
The Retry-After header tells you how many seconds to wait before retrying. It's available on the PSR-7 response object.
For more on rate limits, see Meta Information, which covers how to read your current limits and remaining quota from response headers.
HTTP transport errors
When the HTTP request itself fails (network error, DNS resolution failure, connection timeout, etc.), the client throws Anthropic\Exceptions\TransporterException:
use Anthropic\Exceptions\TransporterException;
try {
$response = $client->messages()->create([...]);
} catch (TransporterException $e) {
$e->getMessage(); // The underlying HTTP client's error message
}
This wraps the PSR-18 ClientExceptionInterface from your HTTP client. The original exception is available via getPrevious().
Response parsing errors
If the API returns a response that can't be decoded as JSON, the client throws Anthropic\Exceptions\UnserializableResponse:
use Anthropic\Exceptions\UnserializableResponse;
try {
$response = $client->messages()->create([...]);
} catch (UnserializableResponse $e) {
$e->getMessage(); // JSON decode error message
$e->response; // The raw PSR-7 response, if available
}
This is rare in normal operation. It typically indicates a proxy or middleware returned an unexpected response (HTML error page, empty body, etc.).
Exception hierarchy
ErrorException (API errors)
├── RateLimitException (HTTP 429)
TransporterException (HTTP client/network errors)
UnserializableResponse (JSON decode failures)
A practical catch block that covers everything:
use Anthropic\Exceptions\RateLimitException;
use Anthropic\Exceptions\ErrorException;
use Anthropic\Exceptions\TransporterException;
use Anthropic\Exceptions\UnserializableResponse;
try {
$response = $client->messages()->create([...]);
} catch (RateLimitException $e) {
// Back off and retry
} catch (ErrorException $e) {
// API returned an error (bad request, auth failure, overloaded, etc.)
} catch (TransporterException $e) {
// Network or HTTP client failure
} catch (UnserializableResponse $e) {
// Response wasn't valid JSON
}
For the full error format and request size limits, see the Errors reference on the Anthropic docs.