Panduan SDK
PHP
Pakai openai-php/client dengan api14 lewat base URI kustom, termasuk streaming, tool calling, structured output, dan retry dengan backoff.
Gunakan openai-php/client dengan api14. Bangun klien dengan factory, atur base URI ke api14, dan gunakan ID model dalam format provider/model.
Instalasi
composer require openai-php/client guzzlehttp/guzzle
export API14_API_KEY="sk-api14-..."
Konfigurasi
<?php
require __DIR__ . '/vendor/autoload.php';
$client = OpenAI::factory()
->withApiKey(getenv('API14_API_KEY'))
->withBaseUri(getenv('API14_BASE_URL') ?: 'https://api14.com/api/v1')
->withHttpClient(new \GuzzleHttp\Client(['timeout' => 120, 'connect_timeout' => 5]))
->make();
Simpan key di environment (atau .env framework Anda), jangan pernah di source. timeout Guzzle dalam detik dan mencakup seluruh request; naikkan untuk panggilan reasoning atau streaming yang panjang.
Chat
$result = $client->chat()->create([
'model' => 'openai/gpt-5-mini',
'messages' => [
['role' => 'user', 'content' => 'Explain vector databases in two sentences.'],
],
]);
echo $result->choices[0]->message->content;
Streaming
$stream = $client->chat()->createStreamed([
'model' => 'anthropic/claude-sonnet-4.5',
'messages' => [['role' => 'user', 'content' => 'Write a haiku about APIs.']],
]);
foreach ($stream as $response) {
echo $response->choices[0]->delta->content;
}
Lihat Streaming.
Tool calling
$tools = [[
'type' => 'function',
'function' => [
'name' => 'get_weather',
'description' => 'Current weather for a city',
'parameters' => [
'type' => 'object',
'properties' => ['city' => ['type' => 'string']],
'required' => ['city'],
],
],
]];
$messages = [['role' => 'user', 'content' => "What's the weather in Istanbul?"]];
while (true) {
$response = $client->chat()->create(['model' => 'openai/gpt-5-mini', 'messages' => $messages, 'tools' => $tools]);
$message = $response->choices[0]->message;
if (empty($message->toolCalls)) {
echo $message->content;
break;
}
$messages[] = $message->toArray();
foreach ($message->toolCalls as $call) {
$args = json_decode($call->function->arguments, true);
$messages[] = [
'role' => 'tool',
'tool_call_id' => $call->id,
'content' => json_encode(getWeather($args['city'])), // your function
];
}
}
Lihat Tool calling.
Structured output
$result = $client->chat()->create([
'model' => 'openai/gpt-5-mini',
'messages' => [['role' => 'user', 'content' => 'Extract: Ada Lovelace, born 1815 in London.']],
'response_format' => [
'type' => 'json_schema',
'json_schema' => [
'name' => 'person',
'strict' => true,
'schema' => [
'type' => 'object',
'properties' => [
'name' => ['type' => 'string'],
'born' => ['type' => 'integer'],
'city' => ['type' => 'string'],
],
'required' => ['name', 'born', 'city'],
'additionalProperties' => false,
],
],
],
]);
$person = json_decode($result->choices[0]->message->content, true, flags: JSON_THROW_ON_ERROR);
Lihat Structured outputs.
Input gambar
$image = base64_encode(file_get_contents('photo.png'));
$result = $client->chat()->create([
'model' => 'google/gemini-2.5-flash',
'messages' => [[
'role' => 'user',
'content' => [
['type' => 'text', 'text' => 'What is in this picture?'],
['type' => 'image_url', 'image_url' => ['url' => "data:image/png;base64,{$image}"]],
],
]],
]);
Lihat Vision dan file.
Embeddings
$result = $client->embeddings()->create([
'model' => 'openai/text-embedding-3-small',
'input' => ['The quick brown fox', 'Lorem ipsum'],
]);
echo count($result->embeddings[0]->embedding);
Suara
$audio = $client->audio()->speech([
'model' => 'openai/gpt-4o-mini-tts',
'input' => 'Hello from api14!',
'voice' => 'alloy',
]);
file_put_contents('speech.mp3', $audio);
Error
Error gateway memakai format OpenAI, sehingga klien memunculkan OpenAI\Exceptions\ErrorException dengan status dan kode mesin:
use OpenAI\Exceptions\ErrorException;
try {
$client->chat()->create([
'model' => 'openai/gpt-5-mini',
'messages' => [['role' => 'user', 'content' => 'Hi']],
]);
} catch (ErrorException $e) {
match ($e->getStatusCode()) {
402 => error_log('Balance too low, add funds: ' . $e->getErrorCode()), // insufficient_balance
429 => error_log('Rate limited, retry in 60s: ' . $e->getErrorCode()), // rate_limited
default => throw $e,
};
}
Gateway mengirim Retry-After: 60 bersama rate_limited. Lihat Batas laju dan Error.
Retry dengan backoff
openai-php/client tidak mengulang sendiri. Bungkus panggilan dalam loop kecil yang mengulang rate_limited dan 5xx, dan menyerah pada yang lain:
use OpenAI\Exceptions\ErrorException;
use OpenAI\Exceptions\TransporterException;
function withRetry(callable $fn, int $attempts = 5): mixed
{
for ($i = 0; ; $i++) {
try {
return $fn();
} catch (ErrorException $e) {
$retryable = $e->getErrorCode() === 'rate_limited' || $e->getStatusCode() >= 500;
if (!$retryable || $i + 1 >= $attempts) throw $e;
} catch (TransporterException $e) { // network error or timeout
if ($i + 1 >= $attempts) throw $e;
}
usleep((min(60, 2 ** $i) * 1000 + random_int(0, 1000)) * 1000); // backoff + jitter
}
}
$result = withRetry(fn () => $client->chat()->create([
'model' => 'openai/gpt-5-mini',
'messages' => [['role' => 'user', 'content' => 'Hi']],
]));
daily_limit_reached dan insufficient_balance tidak diulang, karena menunggu beberapa detik tidak memperbaikinya.
Semua kemampuan
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api14.com/api/v1",
apiKey: process.env.API14_API_KEY,
});
const result = await client.chat.completions.create({
"model": "openai/gpt-5-mini",
"messages": [
{
"role": "user",
"content": "Explain vector databases in two sentences."
}
]
});
console.log(result.choices[0].message.content);