A lightweight PHP client for the OpenRouter.ai API.
Supports simple single-line calls as well as advanced features like tool calling, structured outputs, SSE streaming, plugins, provider routing, and reasoning models.
- PHP >= 8.1
- Composer
guzzlehttp/guzzle(installed automatically)
composer require cheinisch/openrouter-php-client<?php
require __DIR__.'/vendor/autoload.php';
use cheinisch\OpenRouterClient;
$apiKey = getenv('OPENROUTER_API_KEY');
echo OpenRouterClient::OpenRouterChat($apiKey, 'openai/gpt-4o-mini', 'Say only: OK');echo OpenRouterClient::OpenRouterChat(
$apiKey,
'mistralai/mistral-small',
'Give me one short fun fact about PHP.',
'https://my-app.com', // optional – HTTP-Referer
'My App' // optional – X-Title
);$client = new OpenRouterClient($apiKey);
$answer = $client->chat(
[['role' => 'user', 'content' => 'What is the capital of France?']],
'openai/gpt-4o-mini'
);
echo $answer; // plain stringThe optional 4th parameter $options allows passing any API parameter without breaking existing calls:
$answer = $client->chat(
[['role' => 'user', 'content' => 'Explain recursion briefly.']],
'openai/gpt-4o',
[], // headers
[
'max_completion_tokens' => 256,
'temperature' => 0.5,
'plugins' => [['id' => 'web']],
]
);Returns a full result array with content, usage, finish_reason, tool_calls, reasoning, and id.
$result = $client->chatEx(
[['role' => 'user', 'content' => 'Summarize todays AI news.']],
'openai/gpt-4o',
['plugins' => [['id' => 'web']]]
);
echo $result['content'];
echo $result['usage']['total_tokens'];$result = $client->chatEx(
[['role' => 'user', 'content' => "What's the weather in Berlin?"]],
'openai/gpt-4o',
[
'tools' => [[
'type' => 'function',
'function' => [
'name' => 'get_weather',
'description' => 'Returns the current weather for a city',
'parameters' => [
'type' => 'object',
'properties' => ['city' => ['type' => 'string']],
'required' => ['city'],
],
],
]],
'tool_choice' => 'auto',
]
);
if (!empty($result['tool_calls'])) {
$fn = $result['tool_calls'][0]['function']['name'];
$args = json_decode($result['tool_calls'][0]['function']['arguments'], true);
}$data = $client->structuredChat(
[['role' => 'user', 'content' => 'List 3 cities in Germany']],
[
'name' => 'cities',
'schema' => [
'type' => 'object',
'properties' => [
'cities' => ['type' => 'array', 'items' => ['type' => 'string']],
],
'required' => ['cities'],
],
]
);
print_r($data['cities']); // ['Berlin', 'Hamburg', 'Munich']$client->stream(
[['role' => 'user', 'content' => 'Write a short poem about the ocean.']],
function(string $delta, bool $done): void {
if ($done) { echo PHP_EOL; return; }
echo $delta;
flush();
}
);$result = $client->chatEx(
[['role' => 'user', 'content' => 'Solve this step by step: 3x + 7 = 22']],
'anthropic/claude-3-7-sonnet',
['reasoning' => ['effort' => 'high']]
);
echo $result['reasoning']; // internal thinking text
echo $result['content']; // final answer$result = $client->chatEx(
[['role' => 'user', 'content' => 'Hello']],
'openai/gpt-4o',
[
'provider' => [
'sort' => 'price',
'data_collection' => 'deny',
],
]
);$result = $client->chatEx($messages, 'openai/gpt-4o');
$stats = $client->getGenerationStats($result['id']);
echo 'Cost: $' . $stats['usage']['cost'];| Parameter | Type | Description |
|---|---|---|
max_completion_tokens |
int | Max tokens in the response |
temperature |
float | Creativity 0–2, default 1.0 |
top_p / top_k |
float / int | Sampling parameters |
frequency_penalty |
float | Repetition penalty by frequency |
presence_penalty |
float | Repetition penalty by presence |
stop |
array | Stop sequences |
seed |
int | Reproducible output |
tools |
array | Tool / function definitions |
tool_choice |
string | auto | none | required |
parallel_tool_calls |
bool | Call multiple tools in parallel |
response_format |
array | json_object or json_schema |
plugins |
array | web, file-parser, response-healing, context-compression |
provider |
array | Routing: sort, allow, ignore, data_collection |
reasoning |
array | ['effort' => 'low|medium|high'] |
modalities |
array | text, audio, image |
session_id |
string | Session group for observability |
openai/gpt-4o-miniopenai/gpt-4oanthropic/claude-3.5-sonnetanthropic/claude-3-7-sonnetgoogle/gemini-2.5-flashmistralai/mistral-smallx-ai/grok-3-mini- … and 400+ more on OpenRouter