php changedcli-sdks-libraries/sdks/php
Nearest release: v2.1.310, published 2 hours before this site recorded the change. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.
Recorded here
Lines+38added
Lines−0removed
From line
167
where the diff opens
First seen
14 Aug 2026
this site's first read of the page
Recorded edits13to this page, all time
### OpenTelemetry tracing ### Middleware
The whole hunk
from line 167, old and new numbered
/
from line 167
167167
168168## Advanced usage
169169
170### OpenTelemetry tracing
171
172When your application registers an OpenTelemetry tracer provider, the SDK emits a span for each request that it sends. To send the spans to your observability platform, see [Set up OpenTelemetry with the Claude SDK](https://platform.claude.com/docs/en/manage-claude/opentelemetry/sdk).
173
170174### Undocumented properties
171175
172176You can send undocumented parameters to any endpoint, and read undocumented response properties, as follows:
from line 215
211215 body: ['hello' => 'world']
212216);
213217```
218
219### Middleware
220
221Middleware runs your code around every HTTP request the client sends. [SDK middleware](https://platform.claude.com/docs/en/cli-sdks-libraries/middleware) shows how to register a middleware and the order in which several run. This section covers the details that are specific to the PHP SDK.
222
223A middleware is a callable that takes the request and `$next`, or an instance of a class that implements `Anthropic\Middleware`, whose `handle()` method has the same signature. The `middleware` request option accepts both:
224
225```php
226use Anthropic\Middleware;
227use Psr\Http\Message\RequestInterface;
228use Psr\Http\Message\ResponseInterface;
229
230final class TracingMiddleware implements Middleware
231{
232 public function handle(RequestInterface $request, \Closure $next): ResponseInterface
233 {
234 return $next($request->withHeader('x-trace-id', bin2hex(random_bytes(8))));
235 }
236}
237
238$client = new Client(requestOptions: ['middleware' => [new TracingMiddleware()]]);
239```
240
241`$next` runs the rest of the chain and sends the request. Call it once to forward the request, skip the call to return your own response (such as a cached one), or call it several times to send follow-up requests (such as a custom retry).
242
243The SDK also passes every middleware a third argument: the request's `Anthropic\RequestOptions`, which merges the client's options with the options of the call. To read an option such as `fallbackState`, declare an optional third parameter, `?RequestOptions $options = null`. Treat the object as read-only, because every middleware and every retry of the request shares it. If your callable already has a third parameter with another purpose, rewrite it, because the SDK fills that parameter on every call.
244
245At runtime:
246
247* **Retries:** Middleware runs once for each HTTP attempt, inside the SDK's retry loop, so it runs again on each retry.
248* **Error responses:** `$next` returns a response for every HTTP status. The SDK throws its [typed exceptions](https://platform.claude.com/docs/en/cli-sdks-libraries/sdks/php#error-handling) only after the whole chain returns, so a middleware can inspect or replace a 4xx or 5xx response.
249* **Exceptions:** An exception that a middleware throws reaches your code unchanged, except in two cases. The SDK handles a PSR-18 `ClientExceptionInterface` as a connection error, which surfaces as `APIConnectionException`. It retries the attempt after an `Anthropic\Core\Exceptions\RetryableException`, and throws that exception unchanged when no retries are left.
250* **Authentication:** The SDK refreshes OAuth tokens, and signs or authorizes Amazon Bedrock and Google Cloud requests, inside the innermost `$next`. A request that your middleware changes is therefore signed after the change, and again each time you call `$next`.
251* **Response bodies:** A middleware that reads the response body must rewind it, or return `$response->withBody(...)` with a new body, so that the SDK can still decode it. A streaming body can't be rewound, so pass it through unread.
214252
215253## Platform integrations
216254
No line in this hunk matches that.