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

# Go SDK reference

> Every public export in github.com/trulayer/client-go.

This page documents the public surface of `github.com/trulayer/client-go`. For narrative usage, see the [overview](/sdks/go/overview) and [tutorial](/sdks/go/tutorial). For auto-instrumentation, see [instruments](/sdks/go/instruments).

<Info>
  **Status: Alpha.** APIs are pre-`1.0.0` and may change between minor releases. Pin a specific version in production until `1.0.0` ships.
</Info>

## Source and issues

* **Source:** [github.com/trulayer/client-go](https://github.com/trulayer/client-go)
* **Issues / bug reports:** [github.com/trulayer/client-go/issues](https://github.com/trulayer/client-go/issues)
* **Module:** `github.com/trulayer/client-go` on [pkg.go.dev](https://pkg.go.dev/github.com/trulayer/client-go)

## `Client`

The entry point for the SDK. Construct once per process and reuse — `Client` is safe for concurrent use from multiple goroutines.

### `NewClient`

```go theme={null}
func NewClient(apiKey string, opts ...ClientOption) *Client
```

Constructs a client. Pass your API key as the first argument. Call `Shutdown` when the process exits to drain the send queue.

```go theme={null}
tl := trulayer.NewClient(os.Getenv("TRULAYER_API_KEY"))
defer tl.Shutdown(context.Background())
```

Pass an empty string for `apiKey` and set `TRULAYER_DRY_RUN=true` for offline development or CI.

#### Client options

| Option              | Signature                        | Default                   | Purpose                                   |
| ------------------- | -------------------------------- | ------------------------- | ----------------------------------------- |
| `WithBaseURL`       | `(u string) ClientOption`        | `https://api.trulayer.ai` | Override the API base URL                 |
| `WithBatchSize`     | `(n int) ClientOption`           | `50`                      | Max traces buffered before a forced flush |
| `WithFlushInterval` | `(d time.Duration) ClientOption` | `2s`                      | Periodic flush cadence                    |
| `WithHTTPClient`    | `(h *http.Client) ClientOption`  | stdlib default            | Override the HTTP client                  |

### `NewTrace`

```go theme={null}
func (c *Client) NewTrace(ctx context.Context, name string, opts ...TraceOption) (*Trace, context.Context)
```

Begins a new trace. Returns the `*Trace` and a child context that carries the trace — pass the child context to downstream calls so spans can link to it.

```go theme={null}
trace, ctx := tl.NewTrace(ctx, "answer-question")
defer trace.End(ctx)
```

#### Trace options

| Option                | Signature                                 | Purpose                                                        |
| --------------------- | ----------------------------------------- | -------------------------------------------------------------- |
| `WithTraceExternalID` | `(id string) TraceOption`                 | Attach an external identifier (e.g. a request ID)              |
| `WithTags`            | `(tags map[string]string) TraceOption`    | Structured key-value tags. Max 20 keys, 64 chars per key/value |
| `WithTraceMetadata`   | `(md map[string]interface{}) TraceOption` | Arbitrary metadata map                                         |

### `Flush`

```go theme={null}
func (c *Client) Flush(ctx context.Context) error
```

Blocks until all enqueued traces have been attempted. The context bounds how long `Flush` waits. Use this at the end of a short-lived process (e.g. a Lambda handler) to ensure all traces ship before the runtime reclaims memory.

### `Shutdown`

```go theme={null}
func (c *Client) Shutdown(ctx context.Context) error
```

Drains the queue, performs a final flush, and stops the background goroutine. Subsequent `NewTrace` calls still succeed but the resulting traces will not be sent. Call at process exit — typically via `defer`.

Pass a context with a deadline to cap the drain time:

```go theme={null}
shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
tl.Shutdown(shutdownCtx)
```

### `SubmitFeedback`

```go theme={null}
func (c *Client) SubmitFeedback(ctx context.Context, traceID string, f FeedbackData) error
```

Posts a feedback record for a previously ingested trace. Returns a non-nil error on transport or server failure. In dry-run mode it is a no-op and returns `nil`.

## `Trace`

A unit of work that groups one or more spans. Create via `Client.NewTrace`.

### Methods

| Method        | Signature                                                                                            | Purpose                                                  |
| ------------- | ---------------------------------------------------------------------------------------------------- | -------------------------------------------------------- |
| `ID`          | `() string`                                                                                          | Returns the UUIDv7 trace identifier                      |
| `SetInput`    | `(s string)`                                                                                         | Record the trace-level input (e.g. the user's prompt)    |
| `SetOutput`   | `(s string)`                                                                                         | Record the trace-level output (e.g. the final response)  |
| `SetModel`    | `(m string)`                                                                                         | Record the model identifier                              |
| `SetError`    | `(msg string)`                                                                                       | Mark the trace as errored; pass an empty string to clear |
| `SetTag`      | `(k, v string)`                                                                                      | Add a single key-value tag. Max 20 keys, 64 chars each   |
| `SetMetadata` | `(md map[string]interface{})`                                                                        | Merge arbitrary metadata into the trace                  |
| `NewSpan`     | `(ctx context.Context, name string, spanType SpanType, opts ...SpanOption) (*Span, context.Context)` | Create a child span                                      |
| `End`         | `(ctx context.Context)`                                                                              | Finalise and queue the trace for sending. Idempotent     |

### `NewSpan`

```go theme={null}
func (t *Trace) NewSpan(ctx context.Context, name string, spanType SpanType, opts ...SpanOption) (*Span, context.Context)
```

Creates a new span attached to this trace. The returned context carries the span, so nested spans can find their parent automatically.

```go theme={null}
span, ctx := trace.NewSpan(ctx, "embed-query", trulayer.SpanTypeRetrieval)
defer span.End(ctx)
```

#### Span options

| Option             | Signature                                | Purpose                  |
| ------------------ | ---------------------------------------- | ------------------------ |
| `WithSpanInput`    | `(s string) SpanOption`                  | Initial input string     |
| `WithSpanModel`    | `(s string) SpanOption`                  | Initial model identifier |
| `WithSpanMetadata` | `(md map[string]interface{}) SpanOption` | Initial metadata map     |

## `Span`

A unit of work inside a trace (e.g. an LLM call, a tool invocation, a retrieval step). Create via `Trace.NewSpan`.

### Methods

| Method        | Signature                     | Purpose                                                         |
| ------------- | ----------------------------- | --------------------------------------------------------------- |
| `ID`          | `() string`                   | Returns the UUIDv7 span identifier                              |
| `SetInput`    | `(v string)`                  | Record the span input (e.g. the prompt)                         |
| `SetOutput`   | `(v string)`                  | Record the span output (e.g. the completion)                    |
| `SetModel`    | `(m string)`                  | Record the model identifier                                     |
| `SetTokens`   | `(prompt, completion int)`    | Record prompt and completion token counts                       |
| `SetCost`     | `(usd float64)`               | Record the USD cost of this span                                |
| `SetError`    | `(msg string)`                | Mark the span as errored                                        |
| `SetMetadata` | `(md map[string]interface{})` | Merge arbitrary metadata into the span                          |
| `End`         | `(ctx context.Context)`       | Finalise the span and attach it to the parent trace. Idempotent |

## `SpanType`

```go theme={null}
type SpanType string

const (
    SpanTypeLLM       SpanType = "llm"
    SpanTypeTool      SpanType = "tool"
    SpanTypeRetrieval SpanType = "retrieval"
    SpanTypeOther     SpanType = "other"
)
```

| Constant            | Wire value    | Description                                 |
| ------------------- | ------------- | ------------------------------------------- |
| `SpanTypeLLM`       | `"llm"`       | A language model call                       |
| `SpanTypeTool`      | `"tool"`      | A tool or function call                     |
| `SpanTypeRetrieval` | `"retrieval"` | A vector search or document fetch step      |
| `SpanTypeOther`     | `"other"`     | Any other step; use when no other type fits |

Pass one of these constants to `Trace.NewSpan`. The TruLayer dashboard uses the span type to group and filter spans.

## Context helpers

### `TraceFromContext`

```go theme={null}
func TraceFromContext(ctx context.Context) *Trace
```

Returns the active `*Trace` stored in `ctx` by `NewTrace`, or `nil` if no trace is present. Use this in middleware or auto-instrumentation code that receives a context from the caller rather than constructing a trace itself.

```go theme={null}
// In a handler that receives a context already carrying a trace:
if trace := trulayer.TraceFromContext(ctx); trace != nil {
    trace.SetTag("user_id", userID)
}
```

### `SpanFromContext`

```go theme={null}
func SpanFromContext(ctx context.Context) *Span
```

Returns the active `*Span` stored in `ctx` by `NewSpan`, or `nil` if no span is present. Useful for attaching metadata inside deeply nested helpers without threading the span explicitly.

```go theme={null}
if span := trulayer.SpanFromContext(ctx); span != nil {
    span.SetMetadata(map[string]interface{}{"cache_hit": true})
}
```

## Types

### `TraceData`

Wire representation of a trace. Returned when you read traces from the API; also the shape of the payload sent to the ingest endpoint.

```go theme={null}
type TraceData struct {
    ID         string                 // UUIDv7
    ExternalID string                 // optional; correlate with your own request IDs
    Name       string
    Input      string
    Output     string
    Model      string
    LatencyMs  int64
    Cost       float64
    Error      string                 // empty string means no error
    Tags       map[string]string
    Metadata   map[string]interface{}
    Spans      []SpanData
}
```

### `SpanData`

Wire representation of a span.

```go theme={null}
type SpanData struct {
    ID               string
    ParentSpanID     string             // empty for root spans
    Name             string
    Type             SpanType           // "llm" | "tool" | "retrieval" | "other"
    Input            string
    Output           string
    Model            string
    LatencyMs        int64
    Cost             float64
    Error            string
    PromptTokens     int
    CompletionTokens int
    Metadata         map[string]interface{}
    StartTime        time.Time
    EndTime          *time.Time         // nil until End() is called
}
```

### `FeedbackData`

Payload for `Client.SubmitFeedback`.

```go theme={null}
type FeedbackData struct {
    TraceID  string
    Label    string                 // "good" | "bad" | "neutral"
    Score    *float64               // optional 0–1 score
    Comment  string                 // optional free-text
    Metadata map[string]interface{}
}
```

## Auto-instrumentation

`InstrumentOpenAI` and `InstrumentAnthropic` live in optional sub-modules. See [auto-instrumentation](/sdks/go/instruments) for full documentation.

```go theme={null}
import instruments_openai "github.com/trulayer/client-go/instruments/openai"
import instruments_anthropic "github.com/trulayer/client-go/instruments/anthropic"
```

## Environment variables

| Variable           | Values             | Description                                                                                                 |
| ------------------ | ------------------ | ----------------------------------------------------------------------------------------------------------- |
| `TRULAYER_DRY_RUN` | `true`, `1`, `yes` | Disables all HTTP calls without requiring any code changes. No API key is needed. Use in CI and unit tests. |

When dry-run mode is active, `NewTrace` and `NewSpan` still return valid objects so your code runs normally — no traces are sent over the network.

## Error handling

The SDK never panics and never propagates transport or serialisation errors to your call site. Failed flushes are logged with `log.Printf` and the traces are dropped. In dry-run mode all network operations are skipped silently.

* Batches that fail to send are retried up to three times with exponential backoff.
* After retries are exhausted, the batch is dropped and a `log.Printf` warning is emitted.
* `NewTrace` and `NewSpan` never return errors — failures are contained inside the SDK.

To detect dropped traces in production, watch for `trulayer:` prefixed log lines at `ERROR` level from the SDK's logger. A future release will expose an `OnError` hook — track [github.com/trulayer/client-go/issues](https://github.com/trulayer/client-go/issues) for availability.
