How to Integrate OpenAI API with Laravel (Complete Guide 2026)
Laravel is the most popular PHP framework, and adding OpenAI to it is straightforward with the official openai-php/client library. This guide walks through a complete integration: installing the SDK, creating a service class, building a chat controller, streaming responses, and handling errors. By the end you’ll have a working AI chat feature in your Laravel app.
For a lower-level look at the PHP SDK itself, see OpenAI PHP SDK Guide. For using OpenAI without Laravel, see OpenAI PHP Tutorial.
Requirements
- Laravel 10 or 11
- PHP 8.1+
- Composer
- OpenAI API key
Step 1: Install the OpenAI PHP Client
Install the official OpenAI PHP SDK via Composer:
composer require openai-php/laravelThen publish the config file:
php artisan vendor:publish --provider="OpenAI\\Laravel\\ServiceProvider"This creates config/openai.php which reads the API key from your environment.
Step 2: Configure the API Key
Add your OpenAI API key to .env:
OPENAI_API_KEY=sk-proj-...
OPENAI_ORGANIZATION= # optionalStep 3: Create the OpenAI Service
Create app/Services/OpenAIService.php:
<?php
namespace App\Services;
use OpenAI\Laravel\Facades\OpenAI;
class OpenAIService
{
public function chat(array $messages, string $model = 'gpt-4o-mini'): string
{
$response = OpenAI::chat()->create([
'model' => $model,
'messages' => $messages,
'max_tokens' => 1024,
'temperature' => 0.7,
]);
return $response->choices[0]->message->content;
}
public function stream(array $messages, string $model = 'gpt-4o-mini'): \Generator
{
$stream = OpenAI::chat()->createStreamed([
'model' => $model,
'messages' => $messages,
]);
foreach ($stream as $response) {
$delta = $response->choices[0]->delta->content;
if ($delta !== null) {
yield $delta;
}
}
}
}Step 4: Create the Chat Controller
php artisan make:controller ChatControllerEdit app/Http/Controllers/ChatController.php:
<?php
namespace App\Http\Controllers;
use App\Services\OpenAIService;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
class ChatController extends Controller
{
public function __construct(private OpenAIService $openAI) {}
public function index()
{
return view('chat.index');
}
public function send(Request $request): JsonResponse
{
$request->validate([
'message' => 'required|string|max:2000',
'history' => 'array',
]);
$messages = $request->input('history', []);
$messages[] = ['role' => 'user', 'content' => $request->input('message')];
$reply = $this->openAI->chat($messages);
return response()->json([
'reply' => $reply,
'messages' => array_merge($messages, [
['role' => 'assistant', 'content' => $reply],
]),
]);
}
public function stream(Request $request)
{
$request->validate(['message' => 'required|string|max:2000']);
$messages = [
['role' => 'system', 'content' => 'You are a helpful assistant.'],
['role' => 'user', 'content' => $request->input('message')],
];
return response()->stream(function () use ($messages) {
foreach ($this->openAI->stream($messages) as $chunk) {
echo "data: " . json_encode(['chunk' => $chunk]) . "\n\n";
ob_flush();
flush();
}
echo "data: [DONE]\n\n";
}, 200, [
'Content-Type' => 'text/event-stream',
'Cache-Control' => 'no-cache',
'X-Accel-Buffering' => 'no',
]);
}
}Step 5: Register Routes
Add to routes/web.php:
use App\Http\Controllers\ChatController;
Route::get('/chat', [ChatController::class, 'index'])->name('chat.index');
Route::post('/chat/send', [ChatController::class, 'send'])->name('chat.send');
Route::post('/chat/stream', [ChatController::class, 'stream'])->name('chat.stream');Step 6: Create the Blade View
Create resources/views/chat/index.blade.php: