openai-php/client: an OpenAI API client for PHP 8.2 projects
⚡️ OpenAI PHP is a supercharged community-maintained PHP API client that allows you to interact with OpenAI API.
At a glance
- What is it?
- openai-php/client is a community-maintained PHP client for the OpenAI API, installable with Composer and covering resources from Responses and Chat to Batches and Vector Stores. It fits PHP applications that need typed access to the API without writing their own HTTP layer.
- Who is it for?
- Adopt openai-php/client if you are building on PHP 8.2 or newer and want a typed client rather than hand-rolled HTTP calls. Skip it if your application runs on PHP 8.1 or older, since the README states PHP 8.2+ is required.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 4 days ago.
- What is it written in?
- Mainly PHP, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
What openai-php/client is for
The project is a PHP API client for the OpenAI API, maintained by the community rather than by OpenAI. The README describes it as a client that "allows you to interact with the Open AI API", and the repository is published under the MIT licence with the package name openai-php/client on Packagist.
The target reader is a PHP developer who already has an API key and wants to call OpenAI endpoints from application code. Without a client, that means constructing HTTP requests, handling JSON encoding and decoding, and mapping error responses by hand. The client's value is that each API resource gets a typed entry point on a single client object. The README's own first example is three lines: create a client from an API key, call responses()->create() with a model and an input string, and read $response->outputText.
It is not a framework, not an agent runtime, and not a drop-in abstraction over multiple providers. Nothing in the README suggests a provider-agnostic interface. If you need to swap between OpenAI and another vendor behind one interface, this package does not offer that.
How the client is structured: resources, factory, HTTP discovery
The client is organised by API resource. The table of contents lists Models, Responses, Conversations, Conversations Items, Containers, Containers Files, Chat, Audio, Embeddings, Files, FineTuning, Moderations, Images, Vector Stores, Vector Stores Files, Vector Stores File Batches, Batches, and Realtime Ephemeral Keys, plus a set of deprecated entries: Completions (legacy), Assistants, Threads, Thread Messages, Thread Runs, Thread Run Steps, FineTunes, and Edits.
Each resource is reached as a method on the client, and each method returns a response object with named properties and a toArray() method. The Models resource shows the pattern: list() returns an object with an object property equal to 'list' and a data array whose entries expose id and object; retrieve() returns properties id, object, created and ownedBy; delete() returns id, object and deleted. The same shape appears across resources, so you read fields as properties rather than digging through nested arrays.
Construction goes through either the OpenAI::client($apiKey) shortcut or the OpenAI::factory() builder. The factory exposes withApiKey, withOrganization, withProject, withBaseUri, withHttpClient, withHttpHeader, withQueryParam, withStreamHandler, and make(). Defaults are documented inline: organization and project default to null, the base URI defaults to api.openai.com/v1, and the HTTP client defaults to whatever PSR-18 discovery finds. That base URI override is what makes the Azure service section possible, and it also lets you point the client at a proxy or a compatible gateway.
The streaming path is worth noting. withStreamHandler() accepts a callable that receives a RequestInterface and returns a ResponseInterface, and the README's example passes 'stream' => true to the underlying HTTP client's send() call. Streaming is therefore configured at the HTTP layer, not through a separate client API.
Installing openai-php/client and making a first Responses call
The README states the requirement plainly: PHP 8.2 or newer. Installation is a single Composer command.
composer require openai-php/clientAfter that, the README warns that the php-http/discovery Composer plugin must be allowed to run, or you must install a PSR-18 client yourself. The suggested fallback is Guzzle.
composer require guzzlehttp/guzzleWith the package installed, the first working call in the README creates a client from an API key read out of the environment and calls the Responses resource. The model shown is gpt-4o and the input is a plain string.
$yourApiKey = getenv('YOUR_API_KEY');
$client = OpenAI::client($yourApiKey);
$response = $client->responses()->create([
'model' => 'gpt-4o',
'input' => 'Hello!',
]);
echo $response->outputText; // Hello! How can I assist you today?What you should see is the assistant's reply printed to standard output. The outputText property is the documented way to read the text out of a Responses result, so if you are inspecting the object and looking for a nested array path, start with that property instead.
The README also shows a Responses call that enables a built-in tool, passing a tools array with a single entry whose type is web_search_preview and a model of gpt-4o-mini. That is the pattern for built-in tools: an array of tool definitions alongside model and input.
Configuration through the factory, and what it does not cover
For anything beyond a single API key, the factory is the documented route. It sets the organization and project headers, changes the base URI, injects your own HTTP client, adds arbitrary headers and query parameters, and installs a stream handler.
$client = OpenAI::factory()
->withApiKey($yourApiKey)
->withOrganization('your-organization')
->withProject('Your Project')
->withBaseUri('openai.example.com/v1')
->withHttpClient(new \GuzzleHttp\Client([]))
->withHttpHeader('X-My-Header', 'foo')
->withQueryParam('my-param', 'bar')
->make();One detail in that snippet is easy to miss: withBaseUri takes a host and path without a scheme in the README's example, while the default is written as api.openai.com/v1. If you copy the example verbatim, check what your HTTP client does with a scheme-less URI before assuming it resolves.
The factory is also where the client's limits show. There is no documented retry policy, no backoff configuration, and no rate-limit handling in the README. There is a Troubleshooting section listed in the table of contents, but the README excerpt does not show its contents, so the failure guidance it offers cannot be summarised here. If your workload needs retries with jitter or a circuit breaker, you will be adding that yourself, either in a wrapping service or in a custom HTTP client passed to withHttpClient.
Where openai-php/client is the wrong choice
The PHP 8.2 floor is the first hard boundary. Applications pinned to PHP 8.1 or earlier cannot use the current release, and the README gives no indication of a compatibility branch.
The second boundary is the deprecated surface. The table of contents marks Completions as legacy and labels Assistants, Threads, Thread Messages, Thread Runs, Thread Run Steps, FineTunes and Edits as deprecated. If your existing integration is built on the Assistants API, the client still exposes those resources, but you are building new work on a surface the project itself files under deprecated. That is a migration signal, not a reason the code stops working.
The third case is non-PHP services. A Python, Node or Go service should use a client in its own language; adding a PHP sidecar purely to reach OpenAI adds a process, a deployment unit and a failure mode for no benefit. Similarly, if your only need is a single endpoint called once at deploy time, the dependency may cost more than a direct HTTP call.
Finally, the project is community-maintained and not an official OpenAI SDK. The README's support section points at individual sponsors rather than a vendor support contract. Teams that need a commercial support agreement should weigh that before standardising on it.
Alternatives and the difference in approach
The most direct alternative is calling the OpenAI HTTP API yourself with a PSR-18 client such as Guzzle. The difference is where the typing lives. With openai-php/client, request payloads are arrays but responses arrive as objects with named properties and a toArray() escape hatch, and the resource list is enumerated for you. With raw Guzzle, you write the URL, the JSON body and the decode step for every call, and you own the mapping from response JSON to your own value objects. The client wins on repetition; raw HTTP wins when you need a request shape the client does not model, since you are not working around an abstraction.
Among PHP options, the meaningful distinction is official versus community. openai-php/client is explicitly community-maintained, and its README routes support through sponsor links for named contributors. An official SDK would carry vendor backing but is not what this repository is.
A third path is a framework-specific integration, for example a Laravel package that wraps this client and adds facades, config files and container bindings. Those packages typically depend on this one underneath, so the choice is not either/or: you can adopt the framework wrapper and still be running openai-php/client at the bottom of the stack.
Maintenance, releases and the MIT licence
The repository is not archived, and the last push was on 2026-09-11. Releases are versioned and dated: v0.20.1 on 2026-07-20, v0.20.0 on 2026-06-13, and v0.19.2 on 2026-04-19. The version numbers are still in the 0.x range, which in Composer terms means a caret constraint such as ^0.20 does not behave the way ^1.0 would; minor bumps can carry breaking changes under semver conventions. Pin deliberately and read CHANGELOG.md, which is present at the repository root, before upgrading.
Upgrade cost is tied to how much of the deprecated surface you use. Code on Responses, Chat, Embeddings or Files is on the current path. Code on Assistants, Threads or FineTunes is on a surface the README labels deprecated, and every future release is a chance for that surface to change or disappear.
The licence is MIT, as stated in the README badges and the LICENSE.md file at the repository root. MIT is permissive: it allows commercial and closed-source use, modification and redistribution provided the copyright notice and permission notice are retained. This is a description of the licence text, not legal advice; if your organisation has specific obligations around attribution or third-party notices, route that through your own review.
Editorial conclusion
Adopt openai-php/client if you are building on PHP 8.2 or newer and want a typed client rather than hand-rolled HTTP calls. Skip it if your application runs on PHP 8.1 or older, since the README states PHP 8.2+ is required. Before committing, verify that a PSR-18 HTTP client is available or that the php-http/discovery plugin is allowed to run, and confirm the resource you depend on is not listed as deprecated in the table of contents.
Frequently asked questions
What PHP version does openai-php/client require?
The README states that PHP 8.2 or newer is required. Applications on PHP 8.1 or earlier cannot use the current release.
How do I install openai-php/client?
Install it with Composer using composer require openai-php/client. The README also notes that the php-http/discovery plugin must be allowed to run, or you should install a PSR-18 client such as guzzlehttp/guzzle yourself.
How do I make a first request with openai-php/client?
Create a client with OpenAI::client($yourApiKey), then call responses()->create() with a model and an input string. The README's example uses the model gpt-4o and reads the reply from the outputText property.
Does openai-php/client support Azure OpenAI?
The README's table of contents includes a Services section with an Azure entry, and the factory exposes withBaseUri() so the client can be pointed at a different endpoint. The README excerpt shown here does not include the Azure configuration details themselves.
Can I point openai-php/client at a different base URL?
Yes. The factory's withBaseUri() method changes the endpoint, and the README documents the default as api.openai.com/v1.
Which openai-php/client resources are deprecated?
The README's table of contents marks Completions as legacy and labels Assistants, Threads, Thread Messages, Thread Runs, Thread Run Steps, FineTunes and Edits as deprecated. Responses, Chat, Embeddings, Files, Batches and the vector store resources are listed without that label.
Community notes