PHP SDK
Connect PHP applications to nRouter using openai-php/client. Configure custom base URLs, manage API authentication, and access hundreds of top AI models.
Last updated
Modern PHP applications—including Laravel, Symfony, and WordPress services—can connect directly to the nRouter unified AI gateway (https://api.nrouter.ai/v1) using the popular openai-php/client package. By setting the base URI and virtual API key, your PHP backend accesses all leading LLM providers (OpenAI, Anthropic, Gemini, Bedrock, and open-source models) through a single, consistent API.
Routing PHP traffic through nRouter adds enterprise controls without extra dependencies: server-side guardrails stop prompt injections before tokens reach model providers, virtual keys isolate project budgets, and automatic failovers prevent downtime during upstream cloud disruptions.
Prerequisites & Installation
The package requires PHP 8.1 or higher with the curl and json extensions enabled.
Install the client library using Composer:
composer require openai-php/client guzzlehttp/guzzleSetup & Configuration
Configure your environment with your nRouter virtual API key:
export NROUTER_API_KEY="sk-nrouter-your-virtual-key"In Laravel applications, add the key to your .env file:
NROUTER_API_KEY=sk-nrouter-your-virtual-keyBasic Initialization
Initialize the client with the nRouter base URI:
<?php
require 'vendor/autoload.php';
use OpenAI;
$client = OpenAI::factory()
->withApiKey(getenv('NROUTER_API_KEY'))
->withBaseUri('https://api.nrouter.ai/v1')
->make();Configuration Parameters
Configure custom HTTP timeouts, headers, and Guzzle client options:
| Parameter | Type | Default | Description |
|---|---|---|---|
withApiKey | string | Environment | Your nRouter virtual key (sk-nrouter-...). |
withBaseUri | string | https://api.nrouter.ai/v1 | Unified gateway base URI. Must include /v1. |
withHttpClient | ClientInterface | GuzzleHttp\Client | Custom Guzzle instance with custom timeouts and connection pooling. |
withHttpHeader | string, string | None | Custom headers sent on every request (e.g. x-nr-routing). |
<?php
require 'vendor/autoload.php';
use GuzzleHttp\Client as GuzzleClient;
use OpenAI;
// Custom Guzzle client with connection pooling and timeouts
$httpClient = new GuzzleClient([
'timeout' => 45.0,
'connect_timeout' => 5.0,
]);
$client = OpenAI::factory()
->withApiKey(getenv('NROUTER_API_KEY'))
->withBaseUri('https://api.nrouter.ai/v1')
->withHttpClient($httpClient)
->withHttpHeader('x-nr-routing', 'latency')
->make();Implementation Patterns
1. Synchronous Chat Completion
Send structured messages and print the response:
<?php
require 'vendor/autoload.php';
$client = OpenAI::factory()
->withApiKey(getenv('NROUTER_API_KEY'))
->withBaseUri('https://api.nrouter.ai/v1')
->make();
$response = $client->chat()->create([
'model' => 'gpt-5.4-mini',
'messages' => [
['role' => 'system', 'content' => 'You are an expert PHP and Laravel architect.'],
['role' => 'user', 'content' => 'Explain the advantages of asynchronous queued jobs.'],
],
]);
echo $response->choices[0]->message->content . "\n";2. Server-Sent Events (SSE) Streaming
Stream token chunks directly to web clients with immediate output flushing:
<?php
require 'vendor/autoload.php';
// Disable PHP output buffering for live streaming
if (ob_get_level() > 0) {
ob_end_clean();
}
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
$client = OpenAI::factory()
->withApiKey(getenv('NROUTER_API_KEY'))
->withBaseUri('https://api.nrouter.ai/v1')
->make();
$stream = $client->chat()->createStreamed([
'model' => 'claude-haiku-4-5-20251001',
'messages' => [
['role' => 'user', 'content' => 'Write a short poem about clean architecture.'],
],
]);
foreach ($stream as $response) {
$text = $response->choices[0]->delta->content;
if ($text !== null) {
echo $text;
flush();
}
}3. Per-Request Gateway Overrides
openai-php/client forwards unknown parameters to nRouter, allowing prompt templates and cache settings:
<?php
// Execute a dashboard prompt template with variables
$response = $client->chat()->create([
'model' => 'gpt-5.5',
'messages' => [['role' => 'user', 'content' => 'Summarize quarterly user acquisition metrics.']],
'nrouter_prompt_template_id' => 'tmpl_user_acq_v1',
'nrouter_prompt_variables' => ['cohort' => 'enterprise'],
'nrouter_cache' => true,
]);Production Best Practices
Deterministic Routing & Fallbacks
Ensure application availability during cloud provider outages:
<?php
$response = $client->chat()->create([
// Primary model with automatic fallback
'model' => 'gpt-5.4-mini,claude-haiku-4-5-20251001',
'messages' => [['role' => 'user', 'content' => 'Verify order processing details.']],
]);x-nr-routing: latency: Directs requests to the lowest-latency active provider deployment.x-nr-routing: cost: Prioritizes the most cost-effective deployment matching the model specification.- Model Fallback Chain: If the primary provider reports 5xx errors or capacity exhaustion, nRouter fails over instantly to the fallback model.
Response Telemetry & FinOps Tracking
Every successful response through nRouter carries transparent telemetry headers:
x-nr-request-id— Unique ID for the call and join key for the spend ledger.x-nr-model— The specific provider model that fulfilled the request.x-nr-cost-status—exactwhen fully priced,unpricedif provider is unlisted.x-nr-request-cost— Exact USD spend incurred for this call.x-nr-input-tokens,x-nr-output-tokens,x-nr-total-tokens— Token accounting figures.
Inspect these headers from the raw response or via middleware when logging request metrics.
Troubleshooting & Error Handling
Errors returned by nRouter map directly to HTTP status codes.
Common Error Codes
| Status | Code | Cause | Recommended Action |
|---|---|---|---|
400 | guardrail_blocked | Input rejected by server-side content or injection guardrails | Verify prompt safety; review guardrail settings in nRouter dashboard. |
401 | authentication_error | Missing, incorrect, or expired virtual API key | Check NROUTER_API_KEY environment variable. |
402 | insufficient_credits | Zero organization balance or key spending limit reached | Add funds in dashboard or update key ceiling. |
429 | rate_limit_exceeded | Client exceeded RPM/TPM quota | Implement exponential backoff; check retry headers. |
500 / 503 | service_unavailable | Downstream provider error or network disruption | Use fallback model lists (model1,model2). |
Error Catching Example
<?php
use OpenAI\Exceptions\ErrorException;
use OpenAI\Exceptions\TransporterException;
try {
$response = $client->chat()->create([
'model' => 'gpt-5.4-mini',
'messages' => [['role' => 'user', 'content' => 'Execute pipeline.']],
]);
} catch (ErrorException $e) {
$msg = strtolower($e->getMessage());
if (str_contains($msg, 'guardrail')) {
error_log('Rejected by nRouter safety guardrail policy.');
} elseif ($e->getErrorCode() === 'insufficient_credits') {
error_log('Virtual key budget or account credits exhausted.');
} else {
error_log("API Error ({$e->getErrorCode()}): {$e->getMessage()}");
}
} catch (TransporterException $e) {
error_log("Network transport error: {$e->getMessage()}");
}Next Steps
- Python SDK Guide — Official nRouter Python SDK
- cURL Examples — Direct HTTP request and response inspection
- Chat Completions API — HTTP endpoint specifications
Swift / iOS SDK
The official nRouter Swift SDK for iOS, macOS, watchOS, and visionOS with Swift Package Manager support, async/await, and zero third-party dependencies.
Ruby SDK
Connect Ruby applications to nRouter using the ruby-openai gem with custom base URI settings, virtual keys, server-side guardrails, and budget ceilings.