Key facts
| Chat endpoint | POST https://api.plugsky.com/v1/chat/completions |
| Go client | github.com/sashabaranov/go-openai (community OpenAI SDK listed in Plugsky docs) |
| Go version | 1.21+ per the Plugsky SDK reference |
| Base URL | https://api.plugsky.com/v1 set via cfg.BaseURL |
| Auth | Authorization: Bearer sk-live-… set via cfg.APIKey |
| Streaming | CreateChatCompletionStream returns SSE chunks to a Recv loop |
| Tools and JSON | tools, tool_choice and response_format are supported on chat completions |
| Product status | Live; audio, images, batch and fine-tuning are coming soon |
TL;DR
- One client config reaches 30+ models: BaseURL plus your sk-live-… key.
- Same typed request and response structs as OpenAI.
- Streaming uses CreateChatCompletionStream and io.EOF to stop.
- Context propagation handles cancellation and timeouts cleanly.
- Tool calling and JSON mode work through the standard request fields.
How it works, step by step
- Create a Go module and add github.com/sashabaranov/go-openai.
- Build a config with DefaultConfig and set BaseURL to https://api.plugsky.com/v1.
- Load your key from PLUGSKY_API_KEY — never hard-code it in the binary.
- Send a ChatCompletionRequest with model plugsky-pro and verify the response.
- Add streaming with CreateChatCompletionStream and print delta content.
- Define tools with the openai.Tool struct and handle tool_calls in the response loop.
- Set an http.Client timeout and retry 429/5xx responses with exponential backoff.
Original data
Try it yourself
Open the OpenAI-compatible API tester →
Set up the client
Create a module and pull the OpenAI-compatible Go client listed in the Plugsky SDK docs:
go mod init example.com/plugsky-demo
go get github.com/sashabaranov/go-openaiThen build one client and reuse it. HTTP connection pooling matters in Go services, so do not create a client per request:
package main
import (
"context"
"fmt"
"os"
openai "github.com/sashabaranov/go-openai"
)
func main() {
cfg := openai.DefaultConfig(os.Getenv("PLUGSKY_API_KEY"))
cfg.BaseURL = "https://api.plugsky.com/v1"
client := openai.NewClientWithConfig(cfg)
resp, err := client.CreateChatCompletion(context.Background(),
openai.ChatCompletionRequest{
Model: "plugsky-pro",
Messages: []openai.ChatCompletionMessage{{
Role: openai.ChatMessageRoleUser,
Content: "Summarise this incident report in three bullets.",
}},
})
if err != nil {
panic(err)
}
fmt.Println(resp.Choices[0].Message.Content)
}Streaming with context cancellation
Streaming is the default shape for user-facing features. Pass the request context so a canceled HTTP request stops the upstream stream too:
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
defer cancel()
stream, err := client.CreateChatCompletionStream(ctx, req)
if err != nil {
panic(err)
}
defer stream.Close()
for {
chunk, err := stream.Recv()
if errors.Is(err, io.EOF) {
break
}
if err != nil {
panic(err)
}
fmt.Print(chunk.Choices[0].Delta.Content)
}Because Plugsky returns server-sent events in the OpenAI format, the SDK already knows how to decode each frame. There is no custom parser to maintain.
Tools and structured output
Function calling uses Tools and ToolChoice on the request. Define each function with a JSON schema, then loop: if the response contains ToolCalls, execute them, append tool messages and call the model again. For structured extraction, set:
req.ResponseFormat = &openai.ChatCompletionResponseFormat{
Type: openai.ChatCompletionResponseFormatTypeJSONObject,
}Validate the JSON with encoding/json before trusting it downstream. Models that emit malformed JSON should be retried with a stricter prompt, not silently accepted — the same discipline you would apply to any external service.
Timeouts, retries and idempotency
Production Go clients need three things. First, an explicit http.Client timeout — the default has none:
cfg.HTTPClient = &http.Client{Timeout: 60 * time.Second}
cfg.HTTPClient.Transport = &http.Transport{
MaxIdleConns: 100,
MaxIdleConnsPerHost: 20,
}Second, retry on 429 and 5xx using Retry-After when present; the error body follows the OpenAI schema with message, type, code and param. Third, send an Idempotency-Key header on POSTs if you retry writes, so a retried request returns the cached result instead of double-processing. For multi-region workloads, set PLUGSKY_REGION in your deployment to pin traffic to the right region.
Honest comparison
| Capability | Plugsky + go-openai | Raw net/http client | Self-hosted gateway |
|---|---|---|---|
| Setup | DefaultConfig plus two fields | Hand-rolled JSON structs and headers | Run a proxy in front of a model server |
| Streaming | CreateChatCompletionStream and a Recv loop | Decode SSE frames yourself | Depends on the gateway |
| Tools | openai.Tool structs map to function calling | Map JSON by hand | Depends on engine support |
| Types | Typed request and response structs | map[string]any everywhere | Your own schema |
| Timeouts and retries | Context plus your http.Client policy | Same, with more code | You build and operate it |
| Ops | Managed API | Managed API | GPUs, upgrades and on-call |
Frequently asked questions
Which Go client should I use?
The Plugsky docs list the community OpenAI client github.com/sashabaranov/go-openai. It supports a custom BaseURL, so it works with api.plugsky.com without a fork.
What Go version is required?
The Plugsky SDK reference lists Go 1.21+. Any currently supported Go release will work with the OpenAI-compatible client.
How do I stream a response in Go?
Call CreateChatCompletionStream, then loop on stream.Recv() until errors.Is(err, io.EOF), printing chunk.Choices[0].Delta.Content.
Does function calling work?
Yes. Build openai.Tool definitions, check resp.Choices[0].Message.ToolCalls and append tool results before calling the model again.
How should I handle rate limits?
Catch 429 responses, read the Retry-After header, and retry with exponential backoff plus jitter. Reuse one client so connections are pooled.
Can I keep my key out of the binary?
Yes. Read PLUGSKY_API_KEY from the environment or a secret manager at startup; never compile keys into Go binaries.
Is JSON mode supported?
Yes. Set response_format to the JSON object type and validate the output with encoding/json before using it.
What is coming soon?
Audio, images, moderation, files, batch, fine-tuning, assistants and the responses endpoint are roadmap items — check the status page before designing around them.