RepoAnthropicAnthropicpublished Aug 25, 2025seen 6d

anthropics/anthropic-sdk-php

PHP

Open original ↗

Captured source

source ↗
published Aug 25, 2025seen 6dcaptured 8hhttp 200method plain

anthropics/anthropic-sdk-php

Description: Access to Anthropic's safety-first language model APIs in PHP

Language: PHP

License: MIT

Stars: 158

Forks: 49

Open issues: 11

Created: 2025-08-25T23:19:47Z

Pushed: 2026-06-09T23:57:32Z

Default branch: main

Fork: no

Archived: no

README:

Claude SDK for PHP

The Claude SDK for PHP provides access to the Claude API from PHP applications.

Documentation

Full documentation is available at [platform.claude.com/docs/en/api/sdks/php](https://platform.claude.com/docs/en/api/sdks/php).

Installation

composer require "anthropic-ai/sdk:^0.29.1"

Getting started

messages->create(
maxTokens: 1024,
messages: [['role' => 'user', 'content' => 'Hello, Claude']],
model: 'claude-opus-4-6',
);

var_dump($message->content);

Value Objects

It is recommended to use the static with constructor Base64ImageSource::with(data: 'U3RhaW5sZXNzIHJvY2tz', ...) and named parameters to initialize value objects.

However, builders are also provided (new Base64ImageSource)->withData('U3RhaW5sZXNzIHJvY2tz').

Streaming

We provide support for streaming responses using Server-Sent Events (SSE).

messages->createStream(
maxTokens: 1024,
messages: [['role' => 'user', 'content' => 'Hello, Claude']],
model: 'claude-sonnet-4-5-20250929',
);

foreach ($stream as $message) {
var_dump($message);
}

Streaming requests are dispatched through a separate streamingTransporter PSR-18 HTTP client. When unset, the SDK uses the configured transporter. Some PSR-18 HTTP clients will by default try to read the entire response, so you may need to specify a streaming capable implementation.

$client = new Anthropic\Client(
requestOptions: Anthropic\RequestOptions::with(streamingTransporter: $myStreamingClient),
);

Structured Output

You can use PHP classes to define structured output schemas. The SDK will automatically convert your class to a JSON schema and parse responses back into typed objects.

messages->create(
maxTokens: 1024,
messages: [['role' => 'user', 'content' => 'Write an article about PHP']],
model: 'claude-sonnet-4-5-20250929',
outputConfig: ['format' => Article::class],
);

$article = $message->content[0]->parsed; // Article instance
echo $article->title;

See [examples/messages_structured_output.php](examples/messages_structured_output.php) for more examples including constraints, nested models, and streaming.

Pagination

List methods in the Anthropic API are paginated.

This library provides auto-paginating iterators with each list response, so you do not have to request successive pages manually:

beta->messages->batches->list(limit: 20);

var_dump($page);

// fetch items from the current page
foreach ($page->getItems() as $item) {
var_dump($item->id);
}
// make additional network requests to fetch items from all pages, including and after the current page
foreach ($page->pagingEachItem() as $item) {
var_dump($item->id);
}

Handling errors

When the library is unable to connect to the API, or if the API returns a non-success status code (i.e., 4xx or 5xx response), a subclass of Anthropic\Core\Exceptions\APIException will be thrown:

messages->create(
maxTokens: 1024,
messages: [['role' => 'user', 'content' => 'Hello, Claude']],
model: 'claude-sonnet-4-5-20250929',
);
} catch (APIConnectionException $e) {
echo "The server could not be reached", PHP_EOL;
var_dump($e->getPrevious());
} catch (RateLimitException $e) {
echo "A 429 status code was received; we should back off a bit.", PHP_EOL;
} catch (APIStatusException $e) {
echo "Another non-200-range status code was received", PHP_EOL;
echo $e->getMessage();
}

Error codes are as follows:

| Cause | Error Type | | ---------------- | ------------------------------ | | HTTP 400 | BadRequestException | | HTTP 401 | AuthenticationException | | HTTP 403 | PermissionDeniedException | | HTTP 404 | NotFoundException | | HTTP 409 | ConflictException | | HTTP 422 | UnprocessableEntityException | | HTTP 429 | RateLimitException | | HTTP >= 500 | InternalServerException | | Other HTTP error | APIStatusException | | Timeout | APITimeoutException | | Network error | APIConnectionException |

Retries

Certain errors will be automatically retried 2 times by default, with a short exponential backoff.

Connection errors (for example, due to a network connectivity problem), 408 Request Timeout, 409 Conflict, 429 Rate Limit, >=500 Internal errors, and timeouts will all be retried by default.

You can use the maxRetries option to configure or disable this:

0]);

// Or, configure per-request:
$result = $client->messages->create(
maxTokens: 1024,
messages: [['role' => 'user', 'content' => 'Hello, Claude']],
model: 'claude-sonnet-4-5-20250929',
requestOptions: ['maxRetries' => 5],
);

File uploads

Request parameters that correspond to file uploads can be passed as a resource returned by fopen(), a string of file contents, or a FileParam instance.

beta->files->upload(
file: FileParam::fromString($contents, filename: '/path/to/file', contentType: '…'),
);

// Pass in only a string (where applicable)
$fileMetadata = $client->beta->files->upload(file: '…');

// Pass an open resource:
$fd = fopen('/path/to/file', 'r');
try {
$fileMetadata = $client->beta->files->upload(
file: FileParam::fromResource($fd, filename: '/path/to/file', contentType: '…'),
);
} finally {
fclose($fd);
}

Advanced concepts

Making custom or undocumented requests

Undocumented properties

You can send undocumented parameters to any endpoint, and read undocumented response properties, like so:

Note: the extra* parameters of the same name overrides the documented parameters.

messages->create(
maxTokens: 1024,
messages: [['role' => 'user', 'content' => 'Hello, Claude']],
model: 'claude-sonnet-4-5-20250929',
requestOptions: [
'extraQueryParams' => ['my_query_parameter' => 'value'],
'extraBodyParams' => ['my_body_parameter' => 'value'],
'extraHeaders' => ['my-header' => 'value'],
],
);

Undocumented request params

If you want to explicitly send an extra param, you can do so with the extra_query, extra_body, and extra_headers under the request_options: parameter when making a request, as seen in the examples above.

Undocumented endpoints

To make requests to undocumented endpoints while retaining the…

Excerpt shown — open the source for the full document.

Notability

notability 4.0/10

New SDK by Anthropic, moderate traction