PromptRails

Go SDK

Official Go SDK for PromptRails with functional options, typed errors, and automatic retries.

Go SDK

The official Go SDK for PromptRails provides a fully typed client for interacting with the PromptRails API from any Go application.

Installation

go get github.com/promptrails/[email protected]

Requires Go 1.21 or later.

Current release: v0.3.1 — streaming chat & executions via *ChatStream, typed AgentConfig interface, promptrails.Version constant. See the changelog.

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

OptionTypeDefaultDescription
WithBaseURLstringhttps://api.promptrails.aiAPI base URL
WithTimeouttime.Duration30sHTTP request timeout
WithMaxRetriesint3Maximum retry attempts on 5xx

The API key is sent via the X-API-Key header with every request.

Available Resources

ResourceFieldDescription
Agentsclient.AgentsAgent CRUD, versioning, execution
Promptsclient.PromptsPrompt CRUD, versioning, execution
Executionsclient.ExecutionsExecution listing and details
Credentialsclient.CredentialsCredential management
Data Sourcesclient.DataSourcesData source CRUD, versioning, execution
Chatclient.ChatSend messages to chat sessions
Tracesclient.TracesTrace listing and filtering
Costsclient.CostsCost analysis and summaries
MCP Toolsclient.MCPToolsMCP tool management
Approvalsclient.ApprovalsApproval request management
Scoresclient.ScoresScoring and evaluation
A2Aclient.A2AAgent-to-Agent protocol
Webhook Triggersclient.WebhookTriggersWebhook trigger management

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.Data.Output)

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)
}

Approve an Execution

err := client.Approvals.Decide(ctx, "approval-id", &promptrails.DecideApprovalParams{
    Decision: "approved",
    Reason:   "Looks good",
})

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)
    }
}

Typed Agent Config

Agents.CreateVersion takes a typed AgentConfig — an interface implemented by the five concrete variants. Each concrete type's MarshalJSON injects the required type discriminator.

import promptrails "github.com/promptrails/go-sdk"
 
// Simple agent — one prompt per execution
simple := promptrails.SimpleAgentConfig{
    PromptID: "prompt-id",
}
 
// Chain agent — prompts run sequentially
chain := promptrails.ChainAgentConfig{
    PromptIDs: []promptrails.PromptLink{
        {PromptID: "p1", Role: "step1", SortOrder: 0},
        {PromptID: "p2", Role: "step2", SortOrder: 1},
    },
}
 
_, err := client.Agents.CreateVersion(ctx, "agent-id", &promptrails.CreateVersionParams{
    Version:    "1.0.0",
    Config:     simple, // or chain, MultiAgentConfig, WorkflowAgentConfig, CompositeAgentConfig
    SetCurrent: true,
})

See Agent Versioning for the per-type field reference.

SDK Version

import promptrails "github.com/promptrails/go-sdk"
 
fmt.Println(promptrails.Version) // "0.3.1"

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, &notFound):
        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

ErrorHTTP StatusDescription
ValidationError400Invalid request parameters
UnauthorizedError401Invalid or missing API key
QuotaExceededError402Plan quota exceeded
ForbiddenError403Insufficient permissions or IP/origin restriction
NotFoundError404Resource not found
RateLimitError429Rate limit exceeded
ServerError5xxServer-side error
APIErrorAnyBase type for all API errors

All error types embed APIError which includes:

  • StatusCode -- HTTP status code
  • Message -- Human-readable error message
  • Code -- Optional error code string
  • Details -- 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.TotalPages)