Browse documentation

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/guzzle

Setup & 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-key

Basic 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:

ParameterTypeDefaultDescription
withApiKeystringEnvironmentYour nRouter virtual key (sk-nrouter-...).
withBaseUristringhttps://api.nrouter.ai/v1Unified gateway base URI. Must include /v1.
withHttpClientClientInterfaceGuzzleHttp\ClientCustom Guzzle instance with custom timeouts and connection pooling.
withHttpHeaderstring, stringNoneCustom 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 — exact when fully priced, unpriced if 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

StatusCodeCauseRecommended Action
400guardrail_blockedInput rejected by server-side content or injection guardrailsVerify prompt safety; review guardrail settings in nRouter dashboard.
401authentication_errorMissing, incorrect, or expired virtual API keyCheck NROUTER_API_KEY environment variable.
402insufficient_creditsZero organization balance or key spending limit reachedAdd funds in dashboard or update key ceiling.
429rate_limit_exceededClient exceeded RPM/TPM quotaImplement exponential backoff; check retry headers.
500 / 503service_unavailableDownstream provider error or network disruptionUse 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

Was this page helpful?