Skip to content
Sign In Get Started

Go SDK (floopy-go)

floopy-go is the official Floopy SDK for Go. It wraps the official openai-go package and points it at the Floopy gateway, so Chat, Embeddings and Models stay a 1:1 drop-in while Floopy-only features (audit, experiments, constraints, decision export, feedback, routing dry-run, sessions) get first-class typed methods.

Prefer the zero-SDK approach? The Go page shows how to use the raw go-openai client with Floopy headers. Use floopy-go when you also want the typed Floopy resources and a single client for both.

A single *floopy.Client is concurrency-safe and shared across goroutines; every call takes a context.Context. There is no separate async client (Go uses goroutines). Requires Go >= 1.23.

Terminal window
go get github.com/FloopyAI/floopy-go@latest
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/FloopyAI/floopy-go"
"github.com/openai/openai-go/v3"
)
func main() {
client, err := floopy.NewClient(os.Getenv("FLOOPY_API_KEY"))
if err != nil {
log.Fatal(err)
}
resp, err := client.OpenAI().Chat.Completions.New(context.Background(), openai.ChatCompletionNewParams{
Model: openai.ChatModelGPT4o,
Messages: []openai.ChatCompletionMessageParamUnion{
openai.UserMessage("Hello from Floopy!"),
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Choices[0].Message.Content)
}

Set FLOOPY_API_KEY in your environment. You can create one in the dashboard.

import "github.com/openai/openai-go/v3"
import "github.com/openai/openai-go/v3/option"
client := openai.NewClient(option.WithAPIKey(os.Getenv("OPENAI_API_KEY")))
import "github.com/FloopyAI/floopy-go"
fl, _ := floopy.NewClient(os.Getenv("FLOOPY_API_KEY"))
client := fl.OpenAI()
resp, err := client.Chat.Completions.New(ctx, openai.ChatCompletionNewParams{ /* ... */ })

client.OpenAI() returns a lazily-built *openai.Client pre-pointed at the gateway, so types and runtime behaviour are identical. Security updates to the OpenAI SDK reach you on go get -u without forks or parity drift.

floopy.Options map to Floopy-* headers and are forwarded to every request (both OpenAI-compat calls and Floopy-only ones). Per-call overrides are available via a trailing ...floopy.RequestOption on every resource method.

client, _ := floopy.NewClient(os.Getenv("FLOOPY_API_KEY"),
floopy.WithOptions(floopy.Options{
Cache: &floopy.CacheOptions{Enabled: floopy.Ptr(true), BucketMaxSize: floopy.Ptr(3)},
PromptID: "cd4249d5-44d5-46c8-8961-9eb3861e1f7e",
PromptVersion: "1",
LLMSecurityEnabled: floopy.Ptr(true),
}),
)
OptionHeaderPurpose
Cache.EnabledFloopy-Cache-EnabledToggle exact + semantic cache
Cache.BucketMaxSizeFloopy-Cache-Bucket-Max-SizeMax entries per semantic bucket
PromptIDFloopy-Prompt-IdStored prompt to resolve
PromptVersionFloopy-Prompt-VersionPinned version for PromptID
LLMSecurityEnabledfloopy-llm-security-enabledLLM firewall pre-check

See the Headers Reference for the full list.

Each resource maps to a public /v1/* gateway endpoint and is typed end-to-end. Pages and Iterate are Go 1.23 range-over-func iterators that yield (value, error).

ctx := context.Background()
// Feedback
client.Feedback.Submit(ctx, floopy.FeedbackSubmitParams{Score: 9, Useful: true, SessionID: resp.ID})
// Decisions (paginated iterators)
d, _ := client.Decisions.Get(ctx, requestID)
for d, err := range client.Decisions.Iterate(ctx, floopy.DecisionListParams{From: since, Limit: 50}) {
_ = d; _ = err
}
// Experiments (auto X-Floopy-Confirm: experiments header)
exp, _ := client.Experiments.Create(ctx, floopy.ExperimentCreateParams{
Name: "cost-vs-quality",
VariantARoutingRuleID: ruleA,
VariantBRoutingRuleID: ruleB,
})
client.Experiments.Rollback(ctx, exp.ID)
// Constraints (full-replace PUT)
client.Constraints.Put(ctx, floopy.OrgConstraints{CostLimitMonthlyUSD: floopy.Ptr(100.0)})
// Export (streamed JSONL + trailer)
stream := client.Export.DecisionsWithTrailer(ctx, floopy.ExportDecisionsParams{From: start, To: end})
for row, err := range stream.Rows {
_ = row; _ = err
}
fmt.Println(stream.Trailer())
// Evaluations
run, _ := client.Evaluations.Create(ctx, floopy.EvaluationCreateParams{DatasetID: dsID, Model: "gpt-4o"})
results, _ := client.Evaluations.Results(ctx, run.ID, 100, "")
// Routing dry-run (Pro plan)
explain, _ := client.Routing.Explain(ctx, floopy.RoutingExplainParams{Model: "gpt-4o", Messages: messages})
// Sessions — restore a stored conversation
session, _ := client.Sessions.Get(ctx, sessionID)
client.OpenAI().Chat.Completions.New(ctx, openai.ChatCompletionNewParams{
Model: openai.ChatModelGPT4o, Messages: session.Messages,
})

Every Floopy-only call returns a *floopy.FloopyError subtype; branch with errors.As:

import "errors"
_, err := client.Export.Decisions(ctx, floopy.ExportDecisionsParams{From: start, To: end})
var rl *floopy.RateLimitError
var plan *floopy.PlanError
switch {
case errors.As(err, &rl):
time.Sleep(time.Duration(max(rl.RetryAfterSeconds, 1)) * time.Second)
case errors.As(err, &plan):
log.Printf("upgrade plan: feature %s not in current plan", plan.Feature)
}

floopy.AsError(err) recovers the base *floopy.FloopyError from any Floopy error. Errors from Chat / Embeddings are emitted by openai-go (*openai.Error), not this package.

  • The API key is only ever sent in the Authorization header; the SDK never logs request or response bodies.
  • TLS certificate verification is on by default (net/http).
  • Releases are immutable Git tags verified by the Go checksum database (sum.golang.org) — there is no registry account or long-lived token in the publishing path.

See the Security guide for gateway-side controls.