Skip to content

About

An unofficial simple OpenRouter client in Go

Topics

Resources

Stars

8 stars

Watchers

0 watching

Forks

Latest commit

 

History

10 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

gopenrouter

Go Reference Go Report Card Go Version License

gopenrouter is a Go client for the OpenRouter API. It combines the complete generated interface from OpenRouter's official Go SDK with an ergonomic, go-openai-style compatibility interface.

Use one client for both surfaces:

  • the generated namespaces expose the complete typed OpenRouter API, including inference, Batch, Containers, Interns, Private Endpoints, Vault, SCIM, System One, the tool catalog, Decisions, analytics, BYOK, guardrails, workspaces, and API-key management;
  • the compatibility methods provide a compact interface for chat completions, streaming, Anthropic Messages, Responses, embeddings, model discovery, generation metadata, credits, OAuth, and management operations.

Requirements

  • Go 1.25.10 or newer
  • an OpenRouter API key for authenticated operations; public model discovery can be used without one

The generated surface uses official Go SDK v0.9.11, pinned in go.mod. Generated types follow that SDK's versioning and release notes.

Installation

go get github.com/iamwavecut/gopenrouter@main

Quick start

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	"github.com/iamwavecut/gopenrouter"
)

func main() {
	client := gopenrouter.NewClient(os.Getenv("OPENROUTER_API_KEY"))

	response, err := client.CreateChatCompletion(
		context.Background(),
		gopenrouter.ChatCompletionRequest{
			Model: "openai/gpt-5-nano",
			Messages: []gopenrouter.ChatCompletionMessage{
				{
					Role:    gopenrouter.RoleUser,
					Content: "Explain why the sky is blue in one sentence.",
				},
			},
		},
	)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(response.Choices[0].Message.Content)
}

Generated OpenRouter interface

Client embeds OpenRouter's generated Go client. Its namespaces and exact request, response, union, multipart, pagination, binary, error, and event-stream types are available directly:

client := gopenrouter.NewClient(os.Getenv("OPENROUTER_API_KEY"))

models, err := client.Models.List(ctx, nil)
files, err := client.Files.List(ctx, nil)
responses, err := client.Responses.Send(ctx, request, nil)

Generated model types live under github.com/OpenRouterTeam/go-sdk/models. The client currently exposes these top-level namespaces:

Analytics, Alpha, APIKeys, Batch, Benchmarks, Beta, BYOK, Chat, Classifications, Containers, Credits, Datasets, Embeddings, Endpoints, Files, Generations, Guardrails, Images, Interns, Models, OAuth, Observability, Organization, Presets, PrivateEndpoints, Providers, Rerank, Responses, Scim, STT, SystemOne, Tools, TTS, Vault, VideoGeneration, and Workspaces.

Byok, Stt, and Tts remain aliases for BYOK, STT, and TTS. Beta.Responses remains available; the current upstream SDK no longer exposes Beta.Analytics, so use Analytics directly.

client.Batch.List(ctx, nil) supports cursor pagination without modifying the caller's query and stops when has_more is false. An operation timeout applies to each page; the caller's context can bound the entire traversal. Other Batch methods use the official types unchanged. The unwrapped generated Batch client is available at client.OpenRouter.Batch.

client.Alpha.Decisions.Create shares the configured base URL. Per-operation operations.WithServerURL takes precedence. The original generated Decisions client is available at client.OpenRouter.Alpha.Decisions.

Compatibility interface

The root methods retain the library's concise, go-openai-inspired API:

response, err := client.CreateChatCompletion(ctx, request)
stream, err := client.CreateChatCompletionStream(ctx, request)

embedding, err := client.CreateEmbeddings(ctx, embeddingRequest)
anthropic, err := client.CreateAnthropicMessage(ctx, anthropicRequest)
responses, err := client.CreateResponse(ctx, responsesRequest)
generation, err := client.GetGeneration(ctx, generationID)

The catalog, embeddings, responses, anthropic, oauth, management, and shared packages provide the same compatibility contracts in focused namespaces.

The compatibility surface also covers POST /messages and the deprecated POST /credits/coinbase operation, which are present in OpenRouter's public OpenAPI contract but intentionally omitted from the generated official client.

Server tools use top-level Parameters; function tools in Chat use Function.Parameters. Function-tool codecs retain explicit nullable fields; Responses function tools encode required parameters: null when no schema is supplied. Responses output items and Anthropic content blocks retain opaque fields when replayed, including asynchronous/subagent context, tool inputs, thinking signatures, and citations. Typed field edits take precedence.

Custom compatibility decoders use json.Number for unstructured numeric values in tool schemas, tracing extensions, and Raw/Extra payloads. This preserves large integers and decimal precision. Callers that asserted float64 for these values must use json.Number.Int64 or Float64 instead; typed numeric fields keep their existing types. Use keyed struct literals: compatibility structs gain fields, and embeddings.Value also tracks decoded encoding internally.

Guardrail creation and patches keep omission distinct from explicit false and null. Use ExtraBody to clear a nullable policy or set a zero budget without changing existing pointer and slice field types:

guardrail, err := client.UpdateGuardrail(ctx, guardrailID,
	gopenrouter.GuardrailUpdateRequest{
		ExtraBody: map[string]any{
			"allowed_models": nil,
			"enforce_zdr_openai": nil,
		},
	})

Configuration

config := gopenrouter.DefaultConfig(os.Getenv("OPENROUTER_API_KEY"))
config.HTTPClient = &http.Client{Timeout: 2 * time.Minute}
config.SiteURL = "https://example.com"
config.SiteName = "Example application"
config.SiteCategories = []string{"productivity", "developer-tools"}

client := gopenrouter.NewClientWithConfig(config)

The configuration is shared by both client surfaces and controls:

  • bearer authentication;
  • the base URL and HTTP client;
  • HTTP-Referer, X-Title, and X-OpenRouter-Title;
  • X-OpenRouter-Categories.

An empty base URL uses https://openrouter.ai/api/v1; a nil HTTP client uses http.Client. Trailing slashes are normalized. A custom base URL applies to generated operations as well as compatibility methods. Decisions uses /api/alpha/decisions on the configured host, preserving any proxy prefix before /api/v1. Endpoint availability still depends on the selected region and account. Explicit per-operation server URLs and attribution headers take precedence over configuration, including intentionally empty headers.

OpenRouter-specific capabilities

  • provider routing, fallback model lists, provider preferences, ZDR and region selection, and provider-specific options;
  • BYOK model, user, and API-key restrictions;
  • service tiers, routing metadata, workspace accounting, and alignment rules and results;
  • reasoning controls and reasoning details;
  • prompt caching and cache-control directives;
  • structured outputs, strict and deferred tools, asynchronous Responses tools, server tools, and plugins;
  • text, image, audio, file, embedding, rerank, and video payloads;
  • cost and native-token accounting;
  • inline Batch submission and results, container files, and code-interpreter events;
  • typed synchronous and streaming errors;
  • Chat SSE, Responses semantic events, and Anthropic event streams.

Examples

Runnable programs are available in examples/:

Testing

The default suite uses local HTTP servers and contract fixtures; it does not call the live OpenRouter API. Tests cover the generated method surface and compatibility JSON, HTTP, pagination, and streaming behavior:

go test ./...
go test -race ./...
go vet ./...

An optional live check exercises public model discovery without an API key:

GOPENROUTER_LIVE_TEST=1 go test . -run TestLivePublicCatalog -count=1 -v

Credits

The compatibility interface is inspired by go-openai. The complete generated surface is provided by OpenRouter's official Go SDK.

License

MIT

About

An unofficial simple OpenRouter client in Go

Topics

Resources

Stars

8 stars

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages