Go API Reference
Import
NewClient
The Gateway has one Chat Completions model entry point. Responses uses its native /openai/v1/responses endpoint; Messages is converted locally to and from Chat Completions. No Anthropic HTTP request or anthropic-version header is emitted.
WithAPIKey is required for model calls, model metadata and pricing. If it is missing, these methods return joytoken.ErrMissingAPIKey before sending a request. ListModels is the only unauthenticated catalog method.
Method chooser
Primitive methods auto-run only SDK fallback tools selected when no request-level or Client-registered tools exist. Caller-owned tools require an explicit Run* method for SDK execution.
Compatible API Methods
OpenAI
Anthropic
Configure WithAPIBaseURL once. Use WithOpenAIBaseURL only for an explicit model URL override.
CreateChatCompletion
Calls POST /openai/v1/chat/completions and returns a non-streaming Chat Completions response.
StreamChatCompletion
Reads SSE chunks. io.EOF means the stream is complete.
A metadata/usage-only SSE event has len(chunk.Choices) == 0. The SDK
preserves the event, normalizes Choices to an empty slice, and may derive
chunk.Usage from metadata.billing. Check the length or range over choices
before indexing.
CreateResponse
Calls POST /openai/v1/responses and returns a non-streaming Responses result. Input accepts a string or message input items.
StreamResponse
Reads Responses SSE events including response.output_text.delta and response.completed.
GenerateImage
Calls POST /openai/v1/images/generations. Model and Prompt are required. Image generation is non-streaming: GenerateImage returns once with the complete JSON response and does not expose an SSE stream. Do not pass stream: true. The response contains generated images in Data and JoyToken routing and billing details in Metadata when available.
EditImage
Calls POST /openai/v1/images/edits. Prompt and Image are required; Model must be ModelAuto. Image accepts a single http(s) URL or base64 data URI, or multiple images as a slice. Image editing is non-streaming: EditImage returns once with the complete JSON response and does not expose an SSE stream. Do not pass stream: true. Output defaults to b64_json; set ResponseFormat to "url" only when you need a hosted URL. The response contains edited images in Data and JoyToken routing and billing details in Metadata when available.
Tool Calling
Tool ownership follows one precedence rule:
- Non-nil request
Tools, including an empty slice, is copied unchanged and suppresses every default. - Otherwise Client-registered tools replace defaults.
- Only when neither source exists does the SDK inject and automatically execute its fallback tools.
Create* and raw Stream* never execute request-level or Client-registered tools. Explicit Run* methods execute only matching handlers. Primitive Create* methods auto-run only SDK-owned fallback tools from rule 3.
Registering tools
Register your own tools with WithToolHandler (or WithTools) when constructing the client. A non-empty registered set replaces the default local set.
RunChatCompletion
Runs a bounded Chat Completions tool loop. RunChatOptions.MaxSteps bounds the rounds (zero uses the default of 8). Returns *RunChatResult with FinalText, Messages, per-turn Steps, StoppedBy, and a provider-neutral FinishReason.
RunResponse / RunMessage / streaming runs
RunResponse runs the loop over native Responses items, and RunMessage runs it over Messages-compatible content blocks. RunChatCompletionStream, RunResponseStream, and RunMessageStream accept callbacks for text deltas and tool results while returning the final collected response.
ToolCall.ExtraContent stores opaque provider extensions and is serialized as extra_content. The SDK preserves it across non-streaming and streaming continuations, Messages tool_use conversion, Responses function-call items, and Agent loops. Gemini google.thought_signature is one example. Manual loops must retain the complete returned tool call rather than reconstructing only its standard fields. A separate top-level thought_signature is exposed as ToolCall.ThoughtSignature (serialized as thought_signature) for providers such as Gemini that return it directly on the tool_call; it is preserved and echoed back verbatim on continuation turns.
When a later turn fails, explicit Run* methods return a non-nil partial result together with the error. Completed Steps, tool results, and the accumulated Messages or Input remain available for diagnostics and recovery.
Request declarations contain no executable Go code. If a Run* request includes Tools, only Client handlers registered under the same function names may execute. Unknown names produce a structured tool_handler_not_found result for the model.
Hosted Responses tools
WithDefaultBuiltinTools(true) opts into web_search_preview; it is disabled by default. Hosted file_search must always be supplied explicitly with valid vector_store_ids. Do not send multiple vendor aliases such as web_search, web_search_20250305, and web_search_preview together—unknown types may be rejected by the Gateway.
Confirm hosted search execution by checking for a web_search_call output item in the Responses result.
Side-effecting tools are gated
The default local tool set includes read-only tools that run freely (file_read, list_dir, file_search) plus two side-effecting tools that are always declared to the model but fail-safe at execution time: file_write and shell. They only run when you supply a permission callback.
ShellPermissionRequest carries Command and WorkingDir; FilePermissionRequest carries the resolved Root. Configure roots with WithShellWorkspace and WithFileWorkspace so a host can show and enforce exactly where the call runs. To drop a tool entirely instead of gating it, exclude it by name:
WithoutDefaultTools only filters default tools — tools you register with WithTools / WithToolHandler always take precedence and are never removed.
Run loops keep the resolved declarations on every continuation turn and append each tool result once. After the first tool call, a forced tool choice is relaxed to auto so the model can return a final answer. The default loop bound is eight turns.
ListModels
Calls the unauthenticated GET /api/v1/models endpoint. ModelLocaleEN returns English descriptions and ModelLocaleZH returns Chinese descriptions. ListModels(ctx) leaves locale unset and uses the API default of English. The SDK preserves the HTTP envelope, so catalog entries are in models.Data.Models.
GetModelMeta
Calls GET /api/v1/models/meta with the configured API key and returns catalog filter metadata.
GetPricing
Calls GET /api/v1/pricing with the configured API key and returns customer-facing tier exchange pricing metadata.
ErrMissingAPIKey
Timeout and retry policy
WithTimeout covers the complete non-streaming request or lifetime of a consumed stream. A non-positive duration disables the SDK timeout.
WithMaxRetries(n) retries HTTP 429, 5xx, and transport failures using bounded exponential backoff with jitter and Retry-After support. The default is 0. Enable retries only when replaying a non-idempotent model POST—and possible duplicate execution or billing—is acceptable.
APIError
ChatCompletionResponse.Metadata, streamed Chat metadata, and Messages-adapter metadata preserve Gateway routing and billing details when present. Log request IDs and stop reasons for diagnostics, but never log API keys or unredacted sensitive tool inputs.
Use RequestID() on Chat, Responses, Messages, stream chunks/events, and image
responses, or call RequestIDFromMetadata. Body metadata.request_id is the
primary source; a successful response request-ID header is used as a fallback.
When protocol-level usage is absent, Chat and Responses derive token counts from
metadata.billing, and the Messages adapter maps the normalized Chat usage.
