---
title: Go SDK
description: Install, wrap your HTTP transport, and report cost data to AgentPing from any Go service.
section: sdks
order: 3
---

# Go SDK

Go 1.22+, zero-dependency (stdlib only). Functional options for config, `http.RoundTripper` instrumentation, and non-blocking background delivery. Run IDs are available immediately.

## Install

```bash
go get github.com/agent-ping/agent-ping-go
```

Package is `agentping`.

## Quickstart

```go
package main

import (
    "context"
    "os"

    "github.com/agent-ping/agent-ping-go"
)

func main() {
    _ = agentping.Init(agentping.WithAPIKey(os.Getenv("AGENTPING_API_KEY")))
    defer agentping.Shutdown(context.Background())

    run := agentping.NewRun("support-triage",
        agentping.WithCustomerID("acme-corp"),
    )
    _ = run.Event("log", map[string]any{"message": "classifying ticket"})
    _ = run.Event("llm_call", map[string]any{
        "provider":      "anthropic",
        "model":         "claude-sonnet-4-5",
        "input_tokens":  1024,
        "output_tokens": 312,
        "latency_ms":    1430,
    })
    _ = run.Finish(agentping.FinishStatusSuccess,
        agentping.WithScores(map[string]any{"confidence": 0.93}),
    )
}
```

`run.ID` is populated synchronously on return. `POST /v1/runs` dispatches in the background.

## Auto-instrumentation

Go has no equivalent global-rewrite mechanism. The SDK ships `http.RoundTripper` wrappers and helpers that build a ready-to-use `*http.Client`:

```go
import (
    "net/http"

    "github.com/agent-ping/agent-ping-go"
    "github.com/agent-ping/agent-ping-go/instrumentation"
)

run := agentping.NewRun("answer-bot")

httpClient := instrumentation.AnthropicHTTPClient(http.DefaultTransport, run)
openaiClient := instrumentation.OpenAIHTTPClient(http.DefaultTransport, run)
```

Pass the client to the Anthropic or OpenAI SDK. For finer control, use the raw transport:

```go
client := anthropic.NewClient(
    option.WithHTTPClient(&http.Client{
        Transport: instrumentation.NewAnthropicTransport(http.DefaultTransport, run),
    }),
)
```

The transport captures provider, model, token counts from the response body and emits `llm_call`. Cost is computed server-side.

## Heartbeats

```go
_ = agentping.Heartbeat("daily-summary", agentping.HeartbeatStatusOK,
    agentping.WithCostUSD(0.084),
    agentping.WithDurationMs(12_300),
    agentping.WithHeartbeatMetadata(map[string]any{"rows": 421}),
)
```

Same table as full runs.

## Streaming

Streaming is wrapped at the `http.RoundTripper` layer. The wrapper installs an `io.ReadCloser` that observes chunks, accumulates token counts, and emits a single `llm_call` on body close. Reads are never delayed.

A mid-stream error emits a `failed` event with partial counts.

## Context propagation

```go
// Env var, picked up by agentping.NewRun automatically:
// AGENTPING_PARENT_RUN=run_eu_018f3a2b9c1d7e8fa4b9c2d7e8f1a3b6

// Explicit option:
run := agentping.NewRun("price-fetcher",
    agentping.WithParentRunID("run_eu_018f3a2b9c1d7e8fa4b9c2d7e8f1a3b6"),
)
```

Explicit option wins.

## Configuration

| Option | Default | Description |
|--------|---------|-------------|
| `WithAPIKey` | `AGENTPING_API_KEY` env | `apk_<region>_<32 hex>` |
| `WithBaseURL` | derived from the key region (`https://<region>.ingest.agentping.io`); `AGENTPING_BASE_URL` also overrides | Override for self-hosting or testing |
| `WithQueueSize` | 1000 | Max envelopes in memory |
| `WithFlushInterval` | 2s | Background drain interval |
| `WithBatchSize` | 50 | Max events per HTTP POST |
| `WithHTTPClient` | `&http.Client{}` | Inject your own (useful for tests) |

## Shutdown

No atexit-style hook (not idiomatic Go). `Shutdown(ctx)` drains the queue under the caller's context:

```go
func main() {
    _ = agentping.Init(agentping.WithAPIKey(os.Getenv("AGENTPING_API_KEY")))
    defer agentping.Shutdown(context.Background())

    // your agent code
}
```

Skip `Shutdown` and in-flight events may be lost on process exit.

## Source

[github.com/agent-ping/agent-ping-go](https://github.com/agent-ping/agent-ping-go). Public surface in `agentping.go`.
