Panduan SDK
Go
Pakai library openai-go resmi dengan api14 lewat option.WithBaseURL, termasuk streaming, tool calling, structured output, dan pengaturan retry.
Gunakan library resmi openai-go dengan api14. Arahkan option.WithBaseURL ke api14 dan kirim ID model apa pun (misalnya openai/gpt-5-mini) sebagai model.
Instalasi
go get github.com/openai/openai-go
export API14_API_KEY="sk-api14-..."
Konfigurasi
package main
import (
"context"
"fmt"
"os"
"github.com/openai/openai-go"
"github.com/openai/openai-go/option"
)
var client = openai.NewClient(
option.WithBaseURL("https://api14.com/api/v1/"),
option.WithAPIKey(os.Getenv("API14_API_KEY")),
)
var ctx = context.Background()
// The snippets below run inside func main().
openai.NewClient() tanpa opsi membaca OPENAI_BASE_URL dan OPENAI_API_KEY, jadi Anda juga dapat mengonfigurasinya dari environment:
export OPENAI_BASE_URL="https://api14.com/api/v1/"
export OPENAI_API_KEY="sk-api14-..."
Chat
resp, err := client.Chat.Completions.New(ctx, openai.ChatCompletionNewParams{
Model: "openai/gpt-5-mini",
Messages: []openai.ChatCompletionMessageParamUnion{
openai.UserMessage("Explain vector databases in two sentences."),
},
})
if err != nil {
panic(err)
}
fmt.Println(resp.Choices[0].Message.Content)
Streaming
stream := client.Chat.Completions.NewStreaming(ctx, openai.ChatCompletionNewParams{
Model: "anthropic/claude-sonnet-4.5",
Messages: []openai.ChatCompletionMessageParamUnion{openai.UserMessage("Write a haiku about APIs.")},
})
for stream.Next() {
chunk := stream.Current()
if len(chunk.Choices) > 0 {
fmt.Print(chunk.Choices[0].Delta.Content)
}
}
if err := stream.Err(); err != nil {
panic(err)
}
Lihat Streaming.
Tool calling
params := openai.ChatCompletionNewParams{
Model: "openai/gpt-5-mini",
Messages: []openai.ChatCompletionMessageParamUnion{openai.UserMessage("What's the weather in Istanbul?")},
Tools: []openai.ChatCompletionToolParam{{
Function: openai.FunctionDefinitionParam{
Name: "get_weather",
Description: openai.String("Current weather for a city"),
Parameters: openai.FunctionParameters{
"type": "object",
"properties": map[string]any{"city": map[string]string{"type": "string"}},
"required": []string{"city"},
},
},
}},
}
for {
resp, err := client.Chat.Completions.New(ctx, params)
if err != nil {
panic(err)
}
msg := resp.Choices[0].Message
if len(msg.ToolCalls) == 0 {
fmt.Println(msg.Content)
break
}
params.Messages = append(params.Messages, msg.ToParam())
for _, call := range msg.ToolCalls {
var args struct{ City string }
json.Unmarshal([]byte(call.Function.Arguments), &args)
params.Messages = append(params.Messages, openai.ToolMessage(getWeather(args.City), call.ID))
}
}
getWeather adalah fungsi Anda yang mengembalikan string. Lihat Tool calling.
Structured output
schema := map[string]any{
"type": "object",
"properties": map[string]any{
"name": map[string]string{"type": "string"},
"born": map[string]string{"type": "integer"},
},
"required": []string{"name", "born"},
"additionalProperties": false,
}
resp, err := client.Chat.Completions.New(ctx, openai.ChatCompletionNewParams{
Model: "openai/gpt-5-mini",
Messages: []openai.ChatCompletionMessageParamUnion{openai.UserMessage("Extract: Ada Lovelace, born 1815.")},
ResponseFormat: openai.ChatCompletionNewParamsResponseFormatUnion{
OfJSONSchema: &openai.ResponseFormatJSONSchemaParam{
JSONSchema: openai.ResponseFormatJSONSchemaJSONSchemaParam{
Name: "person", Schema: schema, Strict: openai.Bool(true),
},
},
},
})
var person struct {
Name string `json:"name"`
Born int `json:"born"`
}
_ = json.Unmarshal([]byte(resp.Choices[0].Message.Content), &person)
Lihat Structured outputs.
Input gambar
resp, err := client.Chat.Completions.New(ctx, openai.ChatCompletionNewParams{
Model: "google/gemini-2.5-flash",
Messages: []openai.ChatCompletionMessageParamUnion{
openai.UserMessage([]openai.ChatCompletionContentPartUnionParam{
openai.TextContentPart("What is in this picture?"),
openai.ImageContentPart(openai.ChatCompletionContentPartImageImageURLParam{
URL: "https://example.com/photo.jpg", // or a data:image/png;base64,... URL
}),
}),
},
})
Lihat Vision dan file.
Parameter tambahan
Field yang tidak punya tipe di SDK, yaitu reasoning, provider, models, ditambahkan dengan option.WithJSONSet:
resp, err := client.Chat.Completions.New(ctx, params,
option.WithJSONSet("reasoning", map[string]any{"effort": "high"}),
option.WithJSONSet("provider", map[string]any{"sort": "throughput"}),
)
Embeddings
emb, err := client.Embeddings.New(ctx, openai.EmbeddingNewParams{
Model: "openai/text-embedding-3-small",
Input: openai.EmbeddingNewParamsInputUnion{OfArrayOfStrings: []string{"The quick brown fox", "Lorem ipsum"}},
})
if err == nil {
fmt.Println(len(emb.Data[0].Embedding))
}
Error
Error API dikembalikan sebagai *openai.Error, yang membawa status HTTP, Code mesin, dan respons mentah:
import "errors"
var apiErr *openai.Error
if errors.As(err, &apiErr) {
switch apiErr.StatusCode {
case 402: // insufficient_balance
fmt.Println("Balance too low, add funds:", apiErr.Code)
case 429: // rate_limited or daily_limit_reached
fmt.Println("Retry after", apiErr.Response.Header.Get("Retry-After"), "s:", apiErr.Code)
}
}
Lihat Error.
Timeout dan retry
Klien mengulang 408, 409, 429, dan 5xx sebanyak dua kali secara default dengan exponential backoff. Atur jumlah retry dan timeout per percobaan sebagai opsi klien atau request, dan batasi seluruh panggilan dengan context:
client := openai.NewClient(
option.WithBaseURL("https://api14.com/api/v1/"),
option.WithAPIKey(os.Getenv("API14_API_KEY")),
option.WithMaxRetries(4),
option.WithRequestTimeout(60*time.Second), // per attempt
)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) // all attempts
defer cancel()
Mengulang tidak membantu untuk daily_limit_reached atau insufficient_balance. Lihat Batas laju.
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);