phaseo / sdk
Phaseo PHP SDK
Requires
- php: >=8.1
- guzzlehttp/guzzle: ^7.0
- psr/http-message: ^1.0
Requires (Dev)
- phpunit/phpunit: ^10.5
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Official PHP SDK for Phaseo Gateway.
Packagist package name: phaseo/sdk
Installation
composer require phaseo/sdk
Quick start
<?php declare(strict_types=1); require_once __DIR__ . '/vendor/autoload.php'; use Phaseo\Sdk\Phaseo; $client = new Phaseo( apiKey: getenv('PHASEO_API_KEY') ?: null, basePath: getenv('PHASEO_BASE_URL') ?: 'https://api.phaseo.app/v1', ); $response = $client->createResponse([ 'model' => 'google/gemma-3-27b:free', 'input' => 'Reply with: PHP SDK works', ]); echo json_encode($response, JSON_PRETTY_PRINT) . PHP_EOL;
Common methods
createResponse(array $payload)createChatCompletion(array $payload)listModels(array $params = [])listOrganisations(array $params = [])for paginated/organisationsdiscoverylistPricingModels(array $params = [])for/pricing/modelscatalogue pricing discoverycalculatePricing(array $payload)for/pricing/calculateusage estimationlistProviders(array $params = []),getCredits(array $params = []),getActivity(array $params = []), andgetAnalytics(array $params = [])for provider discovery and management-key usage surfaceslistApiKeys(array $params = [])for management-key/keysdiscoverycreateApiKey(array $payload),updateApiKey(string $id, array $payload), anddeleteApiKey(string $id)for management-key API-key lifecycle changesgetApiKey(string $id)for management-key/keys/{id}lookuplistWorkspaces(array $params = []),getWorkspace(string $id),createWorkspace(array $body),updateWorkspace(string $id, array $body), anddeleteWorkspace(string $id)for management-key workspace lifecycle managementgetCurrentApiKey()health()getModelDeprecationInfo(string $modelId)validateModel(string $modelId)
Model discovery supports the public /models filters, including provider, provider_status, provider_routing_status, model_routing_status, capability_status, provider_availability_status, provider_availability_reason, status, organisation, endpoints, input_types, output_types, params, availability, limit, and offset.
Use getModelEndpointCapabilities() for live provider routes, or checkModelParameters() to highlight unsupported, partially supported, unknown, and out-of-range values before submitting a request.
$report = $client->checkModelParameters("openai/gpt-5.4", ["temperature" => 0.7], ["endpoint" => "responses"]); $preflight = $client->preflightRequest(["model" => "openai/gpt-5.4", "input" => "Hello", "temperature" => 0.7], ["endpoint" => "responses"]);
PageIterator provides lazy offset pagination, and JobHandle refreshes or waits
for an existing job ID without resubmitting it.
Use provider_availability_reason with availability=all when you want rollout-state entries such as preview_only, provider_not_ready, gated, access_limited, region_limited, project_limited, paused, or soft_blocked. Use capability_status with availability=all when you want non-routable endpoint mappings such as coming_soon or internal_testing.
$models = $client->listModels([ 'provider' => 'anthropic', 'provider_status' => 'beta,not_ready', 'provider_availability_reason' => 'preview_only,provider_not_ready', 'capability_status' => 'coming_soon,internal_testing', 'availability' => 'all', ]);
Async job websocket helpers
Batch and video operations can expose a websocket lifecycle stream at /v1/async/{kind}/{id}/ws.
$batchSocketUrl = $client->getBatchWebSocketUrl('batch_123', 1500); $videoSocketUrl = $client->getVideoWebSocketUrl('video_123', null, true); $genericSocketUrl = $client->getAsyncJobWebSocketUrl('video', 'video_123'); $resourceSocketUrl = $client->asyncJobs()->websocketUrl('video', 'video_123'); echo $batchSocketUrl . PHP_EOL; echo $videoSocketUrl . PHP_EOL; echo $genericSocketUrl . PHP_EOL; echo $resourceSocketUrl . PHP_EOL;
TLS and SSL behavior
TLS verification is enabled by default.
Resolution order for CA bundle:
- Constructor
caBundlePath PHASEO_CA_BUNDLEcurl.cainfo/openssl.cafileSSL_CERT_FILE- Bundled
certs/cacert.pem
Disabling TLS verification (verifyTls: false) should only be used for local debugging.
Realtime voice (beta)
$client->realtime()->connect(...) creates a realtime session and opens the relay WebSocket. It needs the optional phrity/websocket package: composer require phrity/websocket. Provider events pass through unchanged as arrays. PHP is single-threaded, so events are read when you call receive(), iterate events() or call end(), and your listeners run as each event is read.
$session = $client->realtime()->connect(["model" => "openai/gpt-realtime-2", "voice" => "marin"]); $session->onWarning(fn (array $warning) => error_log($warning["code"])); $session->sendAudio($pcm16Chunk); // PCM16 bytes; base64 is handled for you $ended = $session->end(reason: "caller hung up"); // session.ended: reason, usage, cost, billing_status
If the socket closes without session.ended, end() throws RealtimeSessionClosedException, whose getFinalBillPath() is the GET /v1/generations?id=realtime%3A<session_id> lookup for the final cost.
Trusted workloads (OIDC tokens instead of an API key)
Workspaces in the trusted workloads beta can let GitHub Actions jobs and Vercel deployments call Phaseo with their short-lived OIDC token instead of an API key. Set up a trust policy in Settings → API Keys → Trusted workloads, then pass a callable as apiKey. It is called before every request and retry, so each request uses a current token. Tokens must be issued for the audience https://api.phaseo.app.
The built-in helpers fetch the token and reuse it until a minute before it expires:
use Phaseo\Sdk\Phaseo; use Phaseo\Sdk\WorkloadTokens; // GitHub Actions: the job needs `permissions: id-token: write`. $client = new Phaseo(apiKey: WorkloadTokens::githubActions()); // Vercel: exchanges the deployment's OIDC token (VERCEL_OIDC_TOKEN, or the file named by // VERCEL_OIDC_TOKEN_FILE) for one issued to Phaseo. $client = new Phaseo(apiKey: WorkloadTokens::vercel()); // In a request handler, pass the request's x-vercel-oidc-token header instead. $client = new Phaseo(apiKey: WorkloadTokens::vercel(token: fn () => $request->getHeaderLine('x-vercel-oidc-token')));
Both helpers take an optional audience:. Any other callable that returns a credential string works too. A blank result throws and the request is not sent. An Authorization header you pass to requestWithResponse() is used as-is, without calling the provider.
Free and paid models
- Models with
:freein the model ID can be called with zero deposited credits. - Paid models require available wallet balance.
Environment variables
PHASEO_API_KEY(required unless passed in code)PHASEO_BASE_URL(optional, defaults tohttps://api.phaseo.app/v1)PHASEO_CA_BUNDLE(optional TLS override)
Regeneration and local checks
- Regenerate generated client:
pnpm openapi:gen:php - Validate and test:
pnpm --filter @phaseo/php-sdk run validate && pnpm --filter @phaseo/php-sdk run test