PHP SDK
⚠️
Preview — this feature is being built; the design below is the spec.
syntic/syntic-php is the planned official PHP client. It is generated from the OpenAPI description, works with any PSR-18 HTTP client, and adds helpers for streaming with generators, pagination, a tool runner and batch waiting. It is in the second release wave; see Other languages.
Today, use ext-curl as shown in Quickstart: PHP. That code keeps working after the SDK ships.
Install
composer require syntic/syntic-php| Requirement | Value |
|---|---|
| PHP | 8.1 or newer |
| Package | syntic/syntic-php on Packagist |
| HTTP | Any PSR-18 client; Guzzle is used when installed |
Create a client
<?php
require 'vendor/autoload.php';
$client = Syntic\Client::fromEnv(); // SYNTIC_API_KEY, SYNTIC_BASE_URL
$client = Syntic\Client::create([
'api_key' => getenv('SYNTIC_API_KEY'),
'base_url' => 'https://app.syntic.ai/v1',
'max_retries' => 3,
'timeout' => 300,
]);| Option | Default | Notes |
|---|---|---|
api_key | SYNTIC_API_KEY | Private key or workload identity token. |
base_url | SYNTIC_BASE_URL, else https://app.syntic.ai/v1 | |
version | The release’s API version | Sent as syntic-version. |
betas | [] | Sent as syntic-beta; methods that need a flag add it. |
max_retries | 2 | rate_limit, overloaded, api_error and network errors. |
timeout | 600 seconds | |
http_client | discovered | Your own PSR-18 client. |
A first request
$reply = $client->chat->completions->create([
'model' => 'Amara S1.2',
'max_tokens' => 200,
'messages' => [
['role' => 'system', 'content' => 'Answer in one sentence.'],
['role' => 'user', 'content' => 'Why is the sky blue?'],
],
]);
echo $reply->choices[0]->message->content, PHP_EOL;
echo $reply->usage->totalTokens, ' tokens, request ', $reply->requestId, PHP_EOL;Streaming
$stream = $client->chat->completions->stream([
'model' => 'Amara Quick',
'messages' => [['role' => 'user', 'content' => 'Write a haiku about rain.']],
]);
foreach ($stream->textDeltas() as $text) {
echo $text;
flush();
}
$final = $stream->finalCompletion(); // assembled message, tool calls, usageTool loop
$getOrder = Syntic\Tool::define(
name: 'get_order',
description: 'Look up an order by its id.',
parameters: ['order_id' => ['type' => 'string', 'description' => 'Order id such as 88123']],
required: ['order_id'],
handler: fn (array $args) => ['order_id' => $args['order_id'], 'status' => 'shipped'],
);
$result = $client->tools->run([
'model' => 'Amara S1.2',
'messages' => [['role' => 'user', 'content' => 'Where is order 88123?']],
'tools' => [$getOrder],
'max_rounds' => 8,
]);
echo $result->finalMessage->content, PHP_EOL;Errors
| Exception | error.type |
|---|---|
Syntic\Exception\InvalidRequestException | invalid_request |
Syntic\Exception\AuthenticationException | authentication |
Syntic\Exception\PermissionDeniedException | permission |
Syntic\Exception\NotFoundException | not_found |
Syntic\Exception\QuotaExhaustedException | quota_exhausted |
Syntic\Exception\RateLimitException | rate_limit |
Syntic\Exception\OverloadedException | overloaded |
Syntic\Exception\ServerException | api_error |
Syntic\Exception\ConnectionException | No response received |
All API exceptions extend Syntic\Exception\ApiException with getStatusCode(), getType(), getErrorCode(), getParam(), getDetails() and getRequestId().
try {
$client->chat->completions->create(['model' => 'Amara S1.2', 'messages' => []]);
} catch (Syntic\Exception\QuotaExhaustedException $e) {
echo 'Paused until ', $e->getDetails()['resets_at'] ?? 'unknown', PHP_EOL;
}Pagination
foreach ($client->agents->list(['limit' => 50])->autoPaging() as $agent) {
echo $agent->id, ' ', $agent->name, PHP_EOL;
}Files, batches, agents and admin
$file = $client->files->upload(path: 'contract.pdf', purpose: 'document');
$batch = $client->batches->create(['input_file_id' => $file->id]);
$batch = $client->batches->wait($batch->id, pollInterval: 30);
$session = $client->sessions->create(['agent_id' => 'agt_01JC4R8W6Q2N9X3T5V7Y']);
foreach ($client->sessions->stream($session->id) as $event) {
if ($event->type === 'message.completed') {
echo $event->content, PHP_EOL;
}
}
$admin = Syntic\AdminClient::fromEnv(); // SYNTIC_ADMIN_KEY
foreach ($admin->users->list()->autoPaging() as $user) {
echo $user->email, PHP_EOL;
}Raw responses
$raw = $client->chat->completions->withRawResponse()->create($params);
echo $raw->getHeaderLine('x-syntic-billing-source'), PHP_EOL;
$reply = $raw->parse();Related
Was this page helpful?