Go SDK for AI Agents
Install the official PromptRails Go SDK, run an agent from Go, stream executions, send LLM traces, and manage prompts with a typed client.
Best for
Engineers building against the API, SDKs, CLI, MCP, or local tooling
Go SDK for AI Agents
The official PromptRails Go SDK is the typed Go client for running AI agents, managing prompts and executions, and sending LLM traces from Go services. The module is published at github.com/promptrails/go-sdk and documented on pkg.go.dev.
Use the Go SDK when a Go service needs to execute agents, send traces, inspect runs, or manage workspace resources from backend code. You do not need it for product-side experimentation; use Studio, chat, triggers, or Agent UI deployments first when the workflow can be tested without code.
For production services, keep the API key scoped to the operations the service actually performs and use traces to verify runtime behavior.
Installation
go get github.com/promptrails/go-sdk@v0.7.0Requires Go 1.21 or later.
Current release: v0.7.0. This release removes the retired agent-memory API; use knowledge sources for retrieval workflows. The standalone tracing package remains available for sending spans from any Go code. See the
changelog.
Go SDK Quickstart
Create a client with a PromptRails API key, execute an agent, and read its typed output:
package main
import (
"context"
"fmt"
"log"
promptrails "github.com/promptrails/go-sdk"
)
func main() {
client := promptrails.NewClient("pr_key_...")
result, err := client.Agents.Execute(
context.Background(),
"agent-id",
&promptrails.ExecuteAgentParams{
Input: map[string]any{"query": "Summarize this week's sales"},
},
)
if err != nil {
log.Fatal(err)
}
fmt.Println(result.Output)
}Create a scoped key under Settings → API Keys, keep it in a secret manager or environment variable, and pass a request-scoped context.Context in production. See API Keys and Scopes before deploying the client.
When to Use the Go SDK
| Requirement | Recommended interface |
|---|---|
| Run agents from a Go API, worker, or scheduled job | Go SDK |
| Add PromptRails traces to an existing Go service | Go SDK tracing package |
| Explore a workflow before writing application code | Studio or Agent UI |
| Automate PromptRails from CI or shell scripts | CLI |
| Call the platform from another language | Python SDK, JavaScript SDK, or REST API |
Technical detailsClient setup and resource reference
Client Initialization
import promptrails "github.com/promptrails/go-sdk"
client := promptrails.NewClient("your-api-key")With Options
import (
"time"
promptrails "github.com/promptrails/go-sdk"
)
client := promptrails.NewClient("your-api-key",
promptrails.WithBaseURL("https://api.promptrails.ai"), // default
promptrails.WithTimeout(30 * time.Second), // default
promptrails.WithMaxRetries(3), // default
)Configuration
| Option | Type | Default | Description |
|---|---|---|---|
WithBaseURL | string | https://api.promptrails.ai | API base URL |
WithTimeout | time.Duration | 30s | HTTP request timeout |
WithMaxRetries | int | 3 | Maximum retry attempts on 5xx |
The API key is sent via the X-API-Key header with every request.
Available Resources
| Resource | Field | Description |
|---|---|---|
| Agents | client.Agents | Agent CRUD, versioning, execution, playground, guardrails |
| Prompts | client.Prompts | Prompt CRUD and content-only versioning |
| Executions | client.Executions | Listing, trees, cancel, approval inbox, approve/deny, stream |
| Credentials | client.Credentials | Credential management |
| Data Sources | client.DataSources | Data source CRUD, versioning, query |
| Chat | client.Chat | Chat sessions and message streaming |
| Traces | client.Traces | Trace listing, summary, PII report, ingest |
| MCP Tools | client.MCPTools | MCP tool management |
| Guardrails | client.Guardrails | Scanner catalog and guardrail configuration |
| LLM Models | client.LLMModels | Available LLM models |
| A2A | client.A2A | Agent-to-Agent protocol |
| Agent Triggers | client.AgentTriggers | Agent trigger management (generic webhook, Slack, Telegram, Teams, WhatsApp, schedule) |
| Agent VFS | client.AgentVFS | Read, write, move, copy, grep, and inspect an agent’s virtual files |
| Assets | client.Assets | List, retrieve, sign, and delete generated assets |
Common Operations
Execute an Agent
ctx := context.Background()
result, err := client.Agents.Execute(ctx, "agent-id", &promptrails.ExecuteAgentParams{
Input: map[string]any{"message": "Hello, world!"},
Sync: true,
})
if err != nil {
log.Fatal(err)
}
fmt.Println(result.Output)Technical detailsMore Go SDK operations
List Agents
agents, err := client.Agents.List(ctx, &promptrails.ListAgentsParams{
Page: 1,
Limit: 20,
})
if err != nil {
log.Fatal(err)
}
for _, agent := range agents.Data {
fmt.Printf("%s (%s)\n", agent.Name, agent.Type)
}Create a Prompt
prompt, err := client.Prompts.Create(ctx, &promptrails.CreatePromptParams{
Name: "Summarizer",
Description: "Summarizes text",
})
if err != nil {
log.Fatal(err)
}
fmt.Println(prompt.Data.ID)View Executions
executions, err := client.Executions.List(ctx, &promptrails.ListExecutionsParams{
Page: 1,
Limit: 10,
})
if err != nil {
log.Fatal(err)
}
for _, exec := range executions.Data {
fmt.Printf("ID: %s, Status: %s\n", exec.ID, exec.Status)
}Inspect an Execution Tree
tree, err := client.Executions.Tree(ctx, "execution-id") // children populated
if err != nil {
log.Fatal(err)
}
for _, child := range tree.Children {
fmt.Printf("%s %s $%.6f\n", child.AgentID, child.Status, child.Cost)
}Approve or Deny an Execution
Approvals are execution-scoped in API v2. Runs parked at waiting_approval are resumed from the inbox:
inbox, err := client.Executions.ApprovalInbox(ctx, nil)
if err != nil {
log.Fatal(err)
}
for _, exec := range inbox.Data {
_, _ = client.Executions.Approve(ctx, exec.ID, &promptrails.DecideParams{Reason: "Looks good"})
// or: client.Executions.Deny(ctx, exec.ID, &promptrails.DecideParams{Reason: "Denied"})
}Stream a Chat Turn
Chat.SendMessageStream posts a user message and returns a *ChatStream
that yields typed events on the same HTTP connection. Cancel by
cancelling ctx; always defer stream.Close().
session, err := client.Chat.CreateSession(ctx, &promptrails.CreateSessionParams{
AgentID: "agent-id",
})
if err != nil {
log.Fatal(err)
}
stream, err := client.Chat.SendMessageStream(ctx, session.ID, &promptrails.SendMessageParams{
Content: "What is PromptRails?",
})
if err != nil {
log.Fatal(err)
}
defer stream.Close()
for stream.Next() {
switch e := stream.Event().(type) {
case *promptrails.ExecutionEvent:
log.Printf("execution_id: %s", e.ExecutionID)
case *promptrails.ThinkingEvent:
log.Printf("[thinking] %s", e.Content)
case *promptrails.ToolStartEvent:
log.Printf("[tool_start] %s", e.Name)
case *promptrails.ToolEndEvent:
log.Printf("[tool_end] %s (%s)", e.Name, e.Summary)
case *promptrails.ContentEvent:
fmt.Print(e.Content)
case *promptrails.DoneEvent:
fmt.Printf("\n[done] %d tokens\n", e.TokenUsage.TotalTokens)
case *promptrails.ErrorEvent:
log.Fatalf("[error] %s", e.Message)
}
}
if err := stream.Err(); err != nil {
log.Fatal(err)
}Stream an Existing Execution
When an execution was started outside a chat (e.g. Agents.Execute),
subscribe to its live event stream:
stream, err := client.Executions.Stream(ctx, executionID)
if err != nil {
log.Fatal(err)
}
defer stream.Close()
for stream.Next() {
if e, ok := stream.Event().(*promptrails.ContentEvent); ok {
fmt.Print(e.Content)
}
}Technical detailsGo SDK advanced details
Typed Agent Config
Agents.CreateVersion takes a typed AgentConfig — an interface
implemented by the two API v2 kinds, PromptAgentConfig (an agent) and
WorkflowAgentConfig (a workflow). Each type’s MarshalJSON injects the
required type discriminator. Model, sampling, budget, approval policy,
cache TTL and the tool / sub-agent / guardrail attachments are not part
of Config — they are siblings passed to CreateVersionParams.
import promptrails "github.com/promptrails/go-sdk"
temp := 0.2
maxCost := 1.0
_, err := client.Agents.CreateVersion(ctx, "agent-id", &promptrails.CreateVersionParams{
Version: "1.0.0",
Config: promptrails.PromptAgentConfig{PromptID: "prompt-id"},
ModelConfig: &promptrails.ModelConfig{ModelID: "llm-model-id", Temperature: &temp},
RunBudget: &promptrails.RunBudget{MaxCost: &maxCost},
Tools: []promptrails.ToolAttachment{{MCPToolID: "tool-id", RequiresApproval: true}},
SubAgents: []promptrails.SubAgentAttachment{{AgentID: "sub-id", Alias: "researcher"}},
SetCurrent: true,
})For the workflow kind, set Config to promptrails.WorkflowAgentConfig{Nodes: []promptrails.WorkflowNode{...}}.
See Agent Versioning for the full field reference.
Tracing
The github.com/promptrails/go-sdk/tracing package sends spans to PromptRails from any code, without managing your prompts or agents on the platform. It depends only on the standard library and needs an API key with the traces:write scope.
import "github.com/promptrails/go-sdk/tracing"
tracer := tracing.NewTracer("pr_...")
defer tracer.Shutdown()
_ = tracer.Span(ctx, "agent-run", tracing.KindAgent, func(ctx context.Context, root *tracing.Span) error {
root.SetInput(map[string]any{"q": "weather?"})
return tracer.Span(ctx, "llm-call", tracing.KindLLM, func(ctx context.Context, llm *tracing.Span) error {
// SetUsage(promptTokens, completionTokens, totalTokens); pass -1 for an
// unknown count — total is computed from prompt+completion when it is -1.
llm.SetModel("gpt-4o").SetUsage(120, 30, -1)
return nil
})
})Spans created from a child context automatically share the trace and link to their parent. OpenTelemetry users can point a standard OTLP/HTTP exporter at the PromptRails OTLP endpoint instead — see the Tracing guide.
SDK Version
import promptrails "github.com/promptrails/go-sdk"
fmt.Println(promptrails.Version) // "0.7.0"Every request is sent with User-Agent: promptrails-go/<version> so
backend telemetry can attribute traffic to the SDK release.
Error Handling
The SDK returns typed errors for different HTTP status codes. Use errors.As to handle specific error types:
import "errors"
result, err := client.Agents.Execute(ctx, "invalid-id", &promptrails.ExecuteAgentParams{
Input: map[string]any{},
})
if err != nil {
var notFound *promptrails.NotFoundError
var validation *promptrails.ValidationError
var unauthorized *promptrails.UnauthorizedError
var forbidden *promptrails.ForbiddenError
var rateLimit *promptrails.RateLimitError
var serverErr *promptrails.ServerError
switch {
case errors.As(err, ¬Found):
fmt.Printf("Agent not found: %s\n", notFound.Message)
case errors.As(err, &validation):
fmt.Printf("Invalid input: %s\n", validation.Message)
case errors.As(err, &unauthorized):
fmt.Printf("Invalid API key: %s\n", unauthorized.Message)
case errors.As(err, &forbidden):
fmt.Printf("Insufficient permissions: %s\n", forbidden.Message)
case errors.As(err, &rateLimit):
fmt.Printf("Rate limited: %s\n", rateLimit.Message)
case errors.As(err, &serverErr):
fmt.Printf("Server error: %s\n", serverErr.Message)
default:
fmt.Printf("Unexpected error: %v\n", err)
}
}Error Types
| Error | HTTP Status | Description |
|---|---|---|
ValidationError | 400 | Invalid request parameters |
UnauthorizedError | 401 | Invalid or missing API key |
QuotaExceededError | 402 | Plan quota exceeded |
ForbiddenError | 403 | Insufficient permissions or IP/origin restriction |
NotFoundError | 404 | Resource not found |
RateLimitError | 429 | Rate limit exceeded |
ServerError | 5xx | Server-side error |
APIError | Any | Base type for all API errors |
All error types embed APIError which includes:
StatusCode— HTTP status codeMessage— Human-readable error messageCode— Optional error code stringDetails— Optional map with additional error details
Context Support
All SDK methods require a context.Context as the first argument, enabling cancellation and timeouts:
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
result, err := client.Agents.Execute(ctx, "agent-id", &promptrails.ExecuteAgentParams{
Input: map[string]any{"message": "Hello"},
Sync: true,
})Pagination
List endpoints return paginated responses:
// Page-based pagination
page1, _ := client.Agents.List(ctx, &promptrails.ListAgentsParams{Page: 1, Limit: 20})
page2, _ := client.Agents.List(ctx, &promptrails.ListAgentsParams{Page: 2, Limit: 20})
fmt.Printf("Total: %d, Pages: %d\n", page1.Meta.Total, page1.Meta.Pages)Production Checklist
- Pin the module version — commit
go.modandgo.sumso deployments use the reviewed SDK release. - Scope API keys — grant only the agent, prompt, trace, or asset permissions the service needs.
- Propagate context — pass the incoming request context so cancellations and deadlines stop downstream work.
- Handle typed errors — distinguish validation, authorization, quota, rate-limit, and server failures instead of retrying every error.
- Trace important runs — connect application work to LLM traces so model usage, latency, cost, and failures remain inspectable.
- Test version changes — verify agent and prompt versions before promoting them to production.
Go SDK Questions
What Go version does the PromptRails SDK require?
The SDK requires Go 1.21 or later. Install it with go get github.com/promptrails/go-sdk@v0.7.0, or omit the version to select the latest compatible release.
Can I use only the tracing package?
Yes. Import github.com/promptrails/go-sdk/tracing when an existing Go service only needs to send spans. The tracing package depends on the standard library and does not require you to manage agents or prompts through the API client.
Does the Go SDK retry failed requests?
The client retries network errors and 5xx responses up to three times by default. Use WithMaxRetries to change that behavior, and handle authentication, validation, quota, and rate-limit errors explicitly.
Where is the Go API reference?
Use pkg.go.dev for exported Go types and methods. This guide covers the recommended workflows; the REST API reference documents the underlying HTTP endpoints.
Related Topics
- Examples — Ready-to-run code examples
- Quickstart — Getting started guide
- Python SDK — Python alternative
- JavaScript SDK — JavaScript/TypeScript alternative
- CLI — Command-line interface
- API Keys and Scopes — API key management
- Prompt Versioning — Test, promote, and roll back prompt changes
- Tracing — Inspect model calls, tool calls, cost, and latency
- REST API Reference — Underlying REST API