> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tinfoil.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Go

> Go SDK for Tinfoil's secure AI inference API

> [card] [View on GitHub](https://github.com/tinfoilsh/tinfoil-go)
>
> tinfoilsh/tinfoil-go

## Overview

The Tinfoil Go SDK is a wrapper around the [OpenAI Go client](https://github.com/openai/openai-go) that provides secure communication with Tinfoil enclaves. It has the same API as the OpenAI SDK with additional security features including automatic verification that the endpoint is running in a secure Tinfoil enclave and encryption of request bodies to the verified enclave with [EHBP](https://docs.tinfoil.sh/resources/ehbp.md).

> [!NOTE]
>
> V3 attestation verification in the Go SDK, including the installation below, is [beta](https://docs.tinfoil.sh/resources/feature-status.md) while deployment is ongoing.

## Installation

```bash theme={"dark"}
# Create a new directory for your project
mkdir my-tinfoil-app
cd my-tinfoil-app

# Initialize a Go module
go mod init my-tinfoil-app

# Add the Tinfoil SDK to your project
go get github.com/tinfoilsh/tinfoil-go
```

The minimum supported Go version is **1.27.2**.

## Migration from OpenAI

Migrating from OpenAI to Tinfoil is straightforward. The client is designed to be compatible with the OpenAI Go client:

```diff theme={"dark"}
// Before (OpenAI)
- import (
- 	"github.com/openai/openai-go/v3"
- 	"github.com/openai/openai-go/v3/option"
- )
-
- client := openai.NewClient(
-    option.WithAPIKey("OPENAI_API_KEY")
- )

// After (Tinfoil)
+ import (
+ 	"github.com/openai/openai-go/v3"
+ 	"github.com/openai/openai-go/v3/option"
+ 	"github.com/tinfoilsh/tinfoil-go"
+ )
+
+ client, err := tinfoil.NewClient(
+ 	option.WithAPIKey("TINFOIL_API_KEY"),
+ )
```

All method signatures remain the same since `tinfoil.NewClient()` returns a standard OpenAI client with built-in security features.

## Usage

```go theme={"dark"}
// 1. Create a client
client, err := tinfoil.NewClient(
	option.WithAPIKey(os.Getenv("TINFOIL_API_KEY")),
)
if err != nil {
	log.Fatal(err)
}

// 2. Use client as you would openai.Client 
// see https://pkg.go.dev/github.com/openai/openai-go for API documentation
```

## Model Examples

Below are specific examples for each supported model. Click on any model to see its configuration and usage example.

### Chat Models

> [accordion] GLM-5.3
>
> ```go theme={"dark"}
> package main
>
> import (
>     "context"
>     "fmt"
>     "log"
>     "os"
>
>     "github.com/openai/openai-go/v3"
>     "github.com/openai/openai-go/v3/option"
>     "github.com/tinfoilsh/tinfoil-go"
> )
>
> func main() {
>     client, err := tinfoil.NewClient(
>         option.WithAPIKey(os.Getenv("TINFOIL_API_KEY")),
>     )
>     if err != nil {
>         log.Fatal(err)
>     }
>
>     // Example: Complex reasoning task
>     chatCompletion, err := client.Chat.Completions.New(context.TODO(), openai.ChatCompletionNewParams{
>         Messages: []openai.ChatCompletionMessageParamUnion{
>             openai.UserMessage("Solve this step by step: If a train travels 120 miles in 2 hours, and then increases its speed by 25% for the next 3 hours, how far does it travel in total?"),
>         },
>         Model: "glm-5-3",
>     })
>
>     if err != nil {
>         log.Fatal(err)
>     }
>
>     fmt.Println(chatCompletion.Choices[0].Message.Content)
> }
> ```

> [accordion] Gemma 4 31B
>
> ```go theme={"dark"}
> package main
>
> import (
>     "context"
>     "encoding/base64"
>     "fmt"
>     "log"
>     "os"
>
>     "github.com/openai/openai-go/v3"
>     "github.com/openai/openai-go/v3/option"
>     "github.com/tinfoilsh/tinfoil-go"
> )
>
> func main() {
>     client, err := tinfoil.NewClient(
>         option.WithAPIKey(os.Getenv("TINFOIL_API_KEY")),
>     )
>     if err != nil {
>         log.Fatal(err)
>     }
>
>     // Example: Image analysis
>     imageData, err := os.ReadFile("image.jpg")
>     if err != nil {
>         log.Fatal(err)
>     }
>     base64Image := base64.StdEncoding.EncodeToString(imageData)
>     imageURL := fmt.Sprintf("data:image/jpeg;base64,%s", base64Image)
>
>     chatCompletion, err := client.Chat.Completions.New(context.TODO(), openai.ChatCompletionNewParams{
>         Model: "gemma4-31b",
>         Messages: []openai.ChatCompletionMessageParamUnion{
>             openai.UserMessage([]openai.ChatCompletionContentPartUnionParam{
>                 openai.TextContentPart("What's in this image?"),
>                 openai.ImageContentPart(openai.ChatCompletionContentPartImageImageURLParam{
>                     URL: imageURL,
>                 }),
>             }),
>         },
>     })
>
>     if err != nil {
>         log.Fatal(err)
>     }
>
>     fmt.Println(chatCompletion.Choices[0].Message.Content)
> }
> ```

> [accordion] Llama 3.3 70B
>
> ```go theme={"dark"}
> package main
>
> import (
>     "context"
>     "fmt"
>     "log"
>     "os"
>
>     "github.com/openai/openai-go/v3"
>     "github.com/openai/openai-go/v3/option"
>     "github.com/tinfoilsh/tinfoil-go"
> )
>
> func main() {
>     client, err := tinfoil.NewClient(
>         option.WithAPIKey(os.Getenv("TINFOIL_API_KEY")),
>     )
>     if err != nil {
>         log.Fatal(err)
>     }
>
>     // Example: Conversational AI
>     chatCompletion, err := client.Chat.Completions.New(context.TODO(), openai.ChatCompletionNewParams{
>         Messages: []openai.ChatCompletionMessageParamUnion{
>             openai.UserMessage("What are the key differences between renewable and non-renewable energy sources?"),
>         },
>         Model: "llama3-3-70b",
>     })
>
>     if err != nil {
>         log.Fatal(err)
>     }
>
>     fmt.Println(chatCompletion.Choices[0].Message.Content)
> }
> ```

> [accordion] GPT-OSS 120B
>
> ```go theme={"dark"}
> package main
>
> import (
>     "context"
>     "fmt"
>     "log"
>     "os"
>
>     "github.com/openai/openai-go/v3"
>     "github.com/openai/openai-go/v3/option"
>     "github.com/tinfoilsh/tinfoil-go"
> )
>
> func main() {
>     client, err := tinfoil.NewClient(
>         option.WithAPIKey(os.Getenv("TINFOIL_API_KEY")),
>     )
>     if err != nil {
>         log.Fatal(err)
>     }
>
>     // Example: Advanced reasoning with configurable effort levels
>     chatCompletion, err := client.Chat.Completions.New(context.TODO(), openai.ChatCompletionNewParams{
>         Messages: []openai.ChatCompletionMessageParamUnion{
>             openai.UserMessage("Analyze the trade-offs between different database architectures for a high-traffic e-commerce platform."),
>         },
>         Model: "gpt-oss-120b",
>     })
>
>     if err != nil {
>         log.Fatal(err)
>     }
>
>     fmt.Println(chatCompletion.Choices[0].Message.Content)
> }
> ```

### Audio Models

> [accordion] Voxtral Small 24B
>
> #### Transcription
>
> ```go theme={"dark"}
> package main
>
> import (
>     "context"
>     "fmt"
>     "log"
>     "os"
>
>     "github.com/openai/openai-go/v3"
>     "github.com/openai/openai-go/v3/option"
>     "github.com/tinfoilsh/tinfoil-go"
> )
>
> func main() {
>     client, err := tinfoil.NewClient(
>         option.WithAPIKey(os.Getenv("TINFOIL_API_KEY")),
>     )
>     if err != nil {
>         log.Fatal(err)
>     }
>
>     // Example: Audio transcription
>     audioFile, err := os.Open("meeting_recording.mp3")
>     if err != nil {
>         log.Fatal(err)
>     }
>     defer audioFile.Close()
>
>     transcription, err := client.Audio.Transcriptions.New(context.TODO(), openai.AudioTranscriptionNewParams{
>         Model:    "voxtral-small-24b",
>         File:     audioFile,
>         Language: openai.String("en"), // Optional: specify language for better accuracy
>         Prompt:   openai.String("This is a business meeting discussing quarterly results"), // Optional: provide context
>     })
>     if err != nil {
>         log.Fatal(err)
>     }
>
>     fmt.Println("Transcription:", transcription.Text)
> }
> ```
>
> #### Audio Q\&A
>
> ```go theme={"dark"}
> package main
>
> import (
>     "context"
>     "encoding/base64"
>     "fmt"
>     "log"
>     "os"
>
>     "github.com/openai/openai-go/v3"
>     "github.com/openai/openai-go/v3/option"
>     "github.com/tinfoilsh/tinfoil-go"
> )
>
> func main() {
>     client, err := tinfoil.NewClient(
>         option.WithAPIKey(os.Getenv("TINFOIL_API_KEY")),
>     )
>     if err != nil {
>         log.Fatal(err)
>     }
>
>     // Load audio and encode as base64
>     audioData, err := os.ReadFile("audio.mp3")
>     if err != nil {
>         log.Fatal(err)
>     }
>     audioBase64 := base64.StdEncoding.EncodeToString(audioData)
>
>     response, err := client.Chat.Completions.New(context.TODO(), openai.ChatCompletionNewParams{
>         Model: "voxtral-small-24b",
>         Messages: []openai.ChatCompletionMessageParamUnion{
>             openai.UserMessage([]openai.ChatCompletionContentPartUnionParam{
>                 openai.TextContentPart("How many words are in this audio?"),
>                 openai.InputAudioContentPart(openai.ChatCompletionContentPartInputAudioInputAudioParam{
>                     Data:   audioBase64,
>                     Format: "mp3",
>                 }),
>             }),
>         },
>     })
>     if err != nil {
>         log.Fatal(err)
>     }
>
>     fmt.Println(response.Choices[0].Message.Content)
>     // Output: "The audio contains 600 words."
> }
> ```

### Embedding Models

> [accordion] Nomic Embed Text
>
> ```go theme={"dark"}
> package main
>
> import (
>     "context"
>     "fmt"
>     "log"
>     "math"
>     "os"
>
>     "github.com/openai/openai-go/v3"
>     "github.com/openai/openai-go/v3/option"
>     "github.com/tinfoilsh/tinfoil-go"
> )
>
> func main() {
>     client, err := tinfoil.NewClient(
>         option.WithAPIKey(os.Getenv("TINFOIL_API_KEY")),
>     )
>     if err != nil {
>         log.Fatal(err)
>     }
>
>     // Example: Generate embeddings for similarity search
>     documents := []string{
>         "Artificial intelligence is transforming modern technology.",
>         "Machine learning enables computers to learn from data.",
>         "The weather today is sunny and warm.",
>         "Deep learning uses neural networks with multiple layers.",
>     }
>
>     // Generate embeddings for all documents
>     var embeddings [][]float64
>     for _, doc := range documents {
>         response, err := client.Embeddings.New(context.TODO(), openai.EmbeddingNewParams{
>             Model:          "nomic-embed-text",
>             Input:          openai.EmbeddingNewParamsInputUnion{OfArrayOfStrings: []string{doc}},
>             EncodingFormat: openai.EmbeddingNewParamsEncodingFormatFloat,
>         })
>         if err != nil {
>             log.Fatal(err)
>         }
>         embeddings = append(embeddings, response.Data[0].Embedding)
>     }
>
>     // Calculate similarity between first two documents
>     similarity := cosineSimilarity(embeddings[0], embeddings[1])
>
>     fmt.Printf("Similarity between first two AI-related documents: %.3f\n", similarity)
>     fmt.Printf("Embedding dimension: %d\n", len(embeddings[0]))
> }
>
> func cosineSimilarity(a, b []float64) float64 {
>     dotProduct := 0.0
>     normA := 0.0
>     normB := 0.0
>
>     for i := 0; i < len(a); i++ {
>         dotProduct += a[i] * b[i]
>         normA += a[i] * a[i]
>         normB += b[i] * b[i]
>     }
>
>     return dotProduct / (math.Sqrt(normA) * math.Sqrt(normB))
> }
> ```

## Advanced Functionality

For advanced use cases requiring manual verification or direct HTTP access, pin an enclave with `NewClientWithOptions` and use the client's verification and HTTP methods:

```go theme={"dark"}
import (
	"fmt"
	"log"
	"os"

	"github.com/openai/openai-go/v3/option"
	"github.com/tinfoilsh/tinfoil-go"
)

// Pin a specific enclave and config repository
client, err := tinfoil.NewClientWithOptions(
	tinfoil.WithEnclave("inference.tinfoil.sh"),
	tinfoil.WithRepo("tinfoilsh/confidential-model-router"),
	tinfoil.WithOpenAIOptions(option.WithAPIKey(os.Getenv("TINFOIL_API_KEY"))),
)
if err != nil {
	log.Fatal(err)
}

// Verify the enclave attestation again and inspect the result
verification, err := client.Verify()
if err != nil {
	log.Fatalf("verification failed: %v", err)
}
fmt.Printf("Enclave: %s\n", client.Enclave())
fmt.Printf("Repository: %s\n", client.Repo())
fmt.Printf("Release: %s\n", verification.CodeTag)

// Use the verified HTTP client for custom requests
resp, err := client.HTTPClient().Get("https://inference.tinfoil.sh/v1/models")
if err != nil {
	log.Fatal(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
```

`HTTPClient()` only sends requests to the verified enclave and encrypts request bodies to it. To pin the enclave's TLS certificate instead, add `tinfoil.WithTransport(tinfoil.TransportTLS)`.

## API Documentation

This library is a drop-in replacement for the [official OpenAI Go client](https://github.com/openai/openai-go) that can be used with Tinfoil. All methods and types are identical. See the [OpenAI Go client documentation](https://pkg.go.dev/github.com/openai/openai-go/v3) for complete API usage and documentation.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.