- Go 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
|
||
| arize | ||
| examples | ||
| CHANGELOG.md | ||
| go.mod | ||
| go.sum | ||
| LICENSE | ||
| NOTICE | ||
| README.md | ||
Table of Contents
- Overview
- Status
- Installation
- Usage
- Constructing a Client
- Regions
- Endpoint Overrides
- Error Handling
- Operations on Spaces
- Operations on Projects
- Operations on Spans
- Operations on Traces
- Operations on Datasets
- Operations on Experiments
- Operations on Prompts
- Operations on Evaluators
- Operations on Annotation Configs
- Operations on AI Integrations
- Operations on Integrations
- Operations on Organizations
- Operations on Roles
- Operations on Role Bindings
- Operations on API Keys
- Operations on Resource Restrictions
- Operations on Annotation Queues
- Operations on Users
- Operations on Tasks
- SDK Configuration
- Community
Overview
A helper package to interact with Arize AI APIs from Go.
Arize is an AI engineering platform. It helps engineers develop, evaluate, and observe AI applications and agents.
Arize has both Enterprise and OSS products to support this goal:
- Arize AX — an enterprise AI engineering platform from development to production, with an embedded AI Copilot
- Phoenix — a lightweight, open-source project for tracing, prompt engineering, and evaluation
- OpenInference — an open-source instrumentation package to trace LLM applications across models and frameworks
We log over 1 trillion inferences and spans, 10 million evaluation runs, and 2 million OSS downloads every month.
Status
Pre-release (
v0.x.y). The public API surface is unstable and may change without notice until the firstv1.0.0release. Each call site logs a one-time pre-release warning.
The Go SDK v2 currently exposes the following surface area:
- Client construction with environment-aware configuration, region resolution, and on-prem endpoint overrides.
- Typed HTTP errors matchable via
errors.As(BadRequestError,UnauthorizedError,NotFoundError, …). - Resource subclients on
*arize.Client:- Spaces — list, get, create, update, delete, and manage memberships.
- Projects — list, get, create, update, delete.
- Spans — list, delete, and annotate spans.
- Traces — list traces (a trace is returned when any of its spans matches the filter).
- Datasets — list, get, create, update, delete, and manage examples.
- Experiments — list, get, create, delete, and list their runs.
- Prompts — list, get, create, update, delete, and manage versions and labels.
- Evaluators — list, get, create, update, delete, and manage versions.
- Annotation Configs — list, get, create, delete.
- AI Integrations — list, get, create, update, delete.
- Organizations — list, get, create, update, delete, and manage memberships.
- Roles & Role Bindings — manage RBAC roles and their bindings.
- API Keys — list, create, create service keys, refresh, revoke.
- Resource Restrictions — list, restrict, and unrestrict access to Arize resources.
- Annotation Queues — list, get, create, update, delete, add records, and annotate.
- Users — list, get, create, update, delete, bulk delete, resend invitations, and reset passwords.
- Tasks — list, get, create, update, delete, and trigger, list, poll, and cancel their runs.
Additional resource domains will be added incrementally.
Runnable, end-to-end programs for every subclient live in examples/.
Installation
go get github.com/Arize-ai/client-go-v2@latest
Module path:
github.com/Arize-ai/client-go-v2
Package documentation is available at pkg.go.dev/github.com/Arize-ai/client-go-v2.
Migrating from the Legacy Go Client
The legacy client_golang package lives at Arize-ai/client-go-v1. It is in maintenance mode — new feature work targets v2. The v2 surface is REST-based and intentionally diverges from v1; treat the move as a port rather than a drop-in upgrade.
Usage
Constructing a Client
The client reads its API key from Config.APIKey or the ARIZE_API_KEY environment variable. All other fields fall back to environment variables and then to documented defaults during Resolve().
package main
import (
"context"
"log"
"github.com/Arize-ai/client-go-v2/arize"
)
func main() {
client, err := arize.NewClient(arize.Config{
APIKey: "<your-api-key>", // or set ARIZE_API_KEY
})
if err != nil {
log.Fatal(err)
}
_ = context.Background()
_ = client
}
NewClient resolves the config (applies env vars and defaults), validates it, and returns an error if anything is missing or inconsistent. Common sentinel errors:
if errors.Is(err, arize.ErrMissingAPIKey) { /* APIKey unset */ }
if errors.Is(err, arize.ErrMultipleEndpointOverrides) { /* Region + SingleHost + BaseDomain conflict */ }
Regions
Set Config.Region (or the ARIZE_REGION env var) to route the client at a specific Arize deployment region. Known regions:
| Constant | Value |
|---|---|
RegionUSCentral |
us-central-1a |
RegionEUWest |
eu-west-1a |
RegionCACentral |
ca-central-1a |
RegionUSEast |
us-east-1b |
client, err := arize.NewClient(arize.Config{
APIKey: "<your-api-key>",
Region: arize.RegionEUWest,
})
To inspect the endpoints a region resolves to without constructing a client:
endpoints, ok := arize.RegionEndpointsFor(arize.RegionEUWest)
// endpoints.APIHost == "api.eu-west-1a.arize.com"
Endpoint Overrides
For on-prem deployments, use one of the following override fields. Setting more than one returns arize.ErrMultipleEndpointOverrides from Validate().
// 1. Base domain — derives api.<domain>, otlp.<domain>, flight.<domain>
client, _ := arize.NewClient(arize.Config{
APIKey: "<your-api-key>",
BaseDomain: "arize.example.com",
})
// 2. Single host — points API, OTLP, and Flight at the same host
client, _ = arize.NewClient(arize.Config{
APIKey: "<your-api-key>",
SingleHost: "arize.internal",
SinglePort: 8443, // optional; rewrites FlightPort
})
// 3. Explicit per-component host/scheme
client, _ = arize.NewClient(arize.Config{
APIKey: "<your-api-key>",
APIHost: "arize.internal:8080",
APIScheme: "http",
})
Error Handling
All HTTP errors implement error and embed arize.APIError. Match on a specific status class with errors.As:
import "errors"
err := client.ResourceRestrictions.Unrestrict(ctx, resourcerestrictions.UnrestrictRequest{ResourceID: "nonexistent"})
var nfe *arize.NotFoundError
if errors.As(err, &nfe) {
// HTTP 404 — handle the missing-resource case
}
var apiErr *arize.APIError
if errors.As(err, &apiErr) {
// Any HTTP error — read apiErr.StatusCode, apiErr.Body, etc.
}
Available typed errors: BadRequestError, UnauthorizedError, ForbiddenError, NotFoundError, ConflictError, RateLimitError, ServerError. Compare with errors.Is / errors.As, never with == — wrapping with fmt.Errorf("...: %w", err) breaks direct comparison.
Every method takes (ctx context.Context, req XRequest) — path identifiers, body fields, and query
params all live on req. Fields named for a bare resource (Space, Project, Organization, …) accept
either a name or an ID; the SDK resolves them internally. ID-only fields use the <Resource>ID suffix.
The snippets below assume ctx and client are in scope and the matching subclient package is imported
(e.g. import "github.com/Arize-ai/client-go-v2/arize/spaces"). Each subclient has a full runnable
program in examples/.
Operations on Spaces
Use client.Spaces to manage spaces (containers for projects, datasets, …) and their
memberships. Organization accepts a name or ID.
Space responses from list, get, create, and update include OrganizationId,
the ID of the parent organization, when the server supports this field.
Older server versions may omit it.
A full runnable example lives in examples/spaces.
List Spaces
resp, err := client.Spaces.List(ctx, spaces.ListRequest{
Organization: "<org-id-or-name>",
Limit: 25,
})
Omit Organization to list accessible spaces from all organizations. The SDK
sends the resolved organization ID as the REST query parameter org_id.
Get a Space
space, err := client.Spaces.Get(ctx, spaces.GetRequest{Space: "<space-id-or-name>"})
Create a Space
space, err := client.Spaces.Create(ctx, spaces.CreateRequest{
Name: "my-space",
Organization: "<org-id-or-name>", // accepts a name or ID
Description: "optional",
IsPrivate: true, // omit or set false for a public space (default)
})
Private spaces are visible only to their members and account/org/space admins.
A warning is logged when IsPrivate: true to remind you to add members before
the space becomes inaccessible to other users.
Update a Space
Patch semantics: nil fields are preserved.
newName := "renamed-space"
isPrivate := false // set to true to make the space private
space, err := client.Spaces.Update(ctx, spaces.UpdateRequest{
Space: "<space-id-or-name>",
Name: &newName,
IsPrivate: &isPrivate, // nil preserves the current visibility
})
Delete a Space
Irreversible — removes all child resources.
err := client.Spaces.Delete(ctx, spaces.DeleteRequest{Space: "<space-id>"})
Add a Space Member
Build the role with AssignPredefinedRole or AssignCustomRole.
m, err := client.Spaces.AddUser(ctx, spaces.AddUserRequest{
Space: "<space-id>", UserID: "<user-id>",
Role: spaces.AssignPredefinedRole(spaces.UserSpaceRoleMember),
})
Remove a Space Member
err := client.Spaces.RemoveUser(ctx, spaces.RemoveUserRequest{Space: "<space-id>", UserID: "<user-id>"})
Operations on Projects
Use client.Projects to manage projects, which are namespaces for organizing tracing
data. Space is required when Project is a name.
A full runnable example lives in examples/projects.
List Projects
resp, err := client.Projects.List(ctx, projects.ListRequest{
Space: "<space-id-or-name>", // optional filter
Name: "prod", // optional substring filter
Limit: 50,
})
Get a Project
proj, err := client.Projects.Get(ctx, projects.GetRequest{
Project: "<project-id-or-name>",
Space: "<space-id-or-name>", // required when Project is a name
})
Create a Project
proj, err := client.Projects.Create(ctx, projects.CreateRequest{
Name: "my-project", // must be unique within the space
Space: "<space-id-or-name>",
})
Update a Project
proj, err := client.Projects.Update(ctx, projects.UpdateRequest{
Project: "<project-id-or-name>",
Space: "<space-id-or-name>",
Name: "renamed-project",
})
Delete a Project
err := client.Projects.Delete(ctx, projects.DeleteRequest{Project: "<project-id-or-name>", Space: "<space-id-or-name>"})
Operations on Spans
Use client.Spans to list, delete, and annotate spans. List is a POST under the hood
(the filter DSL can be too large for a query string), so its body fields (project,
time range, filter) and query params (limit, cursor) are flattened into one
ListRequest.
A full runnable example lives in examples/spans.
List Spans
Name-or-ID Project, optional time range, filter DSL, and column projection.
Set either IncludedColumns to return only selected columns, or
ExcludedColumns to omit selected columns. The two fields are mutually
exclusive. Fixed span fields are always returned. Set TruncateStringLength
to shorten long string values inside each span's attributes object. Strings
longer than the limit are cut and end with …, which counts toward the limit.
Only attributes string values are affected; span IDs, names, status,
timestamps, annotations, evaluations, and events are not truncated.
resp, err := client.Spans.List(ctx, spans.ListRequest{
Project: "<project-id-or-name>",
Space: "<space-id-or-name>", // required when Project is a name
End: time.Now(),
Filter: "status_code = 'ERROR'",
IncludedColumns: []string{
"attributes.llm.model_name",
"eval.hallucination.score",
},
Limit: 50,
})
To return most columns but skip a large column, use ExcludedColumns instead:
resp, err := client.Spans.List(ctx, spans.ListRequest{
Project: "<project-id-or-name>",
Space: "<space-id-or-name>",
ExcludedColumns: []string{"attributes.embedding.vectors"},
TruncateStringLength: 200,
})
Delete Spans
A partial success returns a non-nil *SpanDeletePartial (HTTP 200); a full delete returns nil (HTTP 204).
partial, err := client.Spans.Delete(ctx, spans.DeleteRequest{
Project: "<project-id-or-name>",
Space: "<space-id-or-name>",
SpanIDs: []string{"span-1", "span-2"},
})
Annotate Spans
Up to 1000 records per call (100 for GranularitySESSION); re-submitting the same config name overwrites (no duplicates).
Granularity selects what each RecordId identifies: a span (GranularitySPAN, the default), a trace's root span (GranularityTRACE), or a session (GranularitySESSION, written to the root span of the session's earliest trace).
err := client.Spans.Annotate(ctx, spans.AnnotateRequest{
Project: "<project-id-or-name>",
Space: "<space-id-or-name>",
Annotations: []spans.AnnotateRecordInput{ /* RecordId + AnnotationInput values */ },
Granularity: spans.GranularitySESSION, // optional; defaults to GranularitySPAN
})
Operations on Traces
Use client.Traces to manage traces. Space is required when Project is a name.
A full runnable example lives in examples/traces.
List Traces
Name-or-ID Project, optional time range and filter DSL, opaque cursor pagination.
resp, err := client.Traces.List(ctx, traces.ListRequest{
Project: "<project-id-or-name>",
Space: "<space-id-or-name>", // required when Project is a name
End: time.Now(),
Filter: "status_code = 'ERROR'",
Limit: 50,
})
Operations on Datasets
Use client.Datasets to manage datasets and their examples. Space is required when
Dataset is a name. Each example is an arbitrary set of user-defined fields.
A full runnable example lives in examples/datasets.
List Datasets
resp, err := client.Datasets.List(ctx, datasets.ListRequest{Space: "<space-id-or-name>", Limit: 25})
Get a Dataset
ds, err := client.Datasets.Get(ctx, datasets.GetRequest{Dataset: "<dataset-id-or-name>", Space: "<space-id-or-name>"})
Create a Dataset
At least one example is required (empty returns datasets.ErrNoExamples).
ds, err := client.Datasets.Create(ctx, datasets.CreateRequest{
Name: "my-dataset",
Space: "<space-id-or-name>",
Examples: []datasets.CreateDatasetExampleInput{
{"input": "What is Arize?", "output": "An AI observability platform."},
},
})
Update a Dataset
ds, err := client.Datasets.Update(ctx, datasets.UpdateRequest{Dataset: "<dataset-id-or-name>", Space: "<space-id-or-name>", Name: "renamed"})
Delete a Dataset
err := client.Datasets.Delete(ctx, datasets.DeleteRequest{Dataset: "<dataset-id>"})
List Examples
Lists the examples of a dataset. Filter is an optional SQL-like expression over example fields for complex queries.
ex, err := client.Datasets.ListExamples(ctx, datasets.ListExamplesRequest{Dataset: "<dataset-id-or-name>", Space: "<space-id-or-name>", Limit: 50})
ex, err = client.Datasets.ListExamples(ctx, datasets.ListExamplesRequest{
Dataset: "<dataset-id-or-name>", Space: "<space-id-or-name>",
Filter: "input = 'What is Arize?'",
Limit: 50,
})
Append Examples
Appends to the latest dataset version.
ins, err := client.Datasets.AppendExamples(ctx, datasets.AppendExamplesRequest{
Dataset: "<dataset-id-or-name>", Space: "<space-id-or-name>",
Examples: []datasets.CreateDatasetExampleInput{{"input": "q", "output": "a"}},
})
Update Examples
Updates existing examples by ID. Set NewVersion to capture the update as a
new dataset version; leave it empty to update the selected version in place.
example := datasets.UpdateDatasetExampleInput{Id: "<example-id>"}
example.Set("input", "updated")
resp, err := client.Datasets.UpdateExamples(ctx, datasets.UpdateDatasetExamplesRequest{
Dataset: "<dataset-id-or-name>", Space: "<space-id-or-name>",
DatasetVersionID: "<dataset-version-id>",
Examples: []datasets.UpdateDatasetExampleInput{example},
NewVersion: "v2",
})
Delete Examples
Removes examples from a specific dataset version. The delete is partial-tolerant:
the result reports DeletedExampleIds and NotDeletedExampleIds, and a false
Completed means the full request should be retried (the operation is idempotent).
resp, err := client.Datasets.DeleteExamples(ctx, datasets.DeleteExamplesRequest{
Dataset: "<dataset-id-or-name>", Space: "<space-id-or-name>",
DatasetVersionID: "<dataset-version-id>",
ExampleIDs: []string{"<example-id>"},
})
Annotate Examples
err := client.Datasets.AnnotateExamples(ctx, datasets.AnnotateExamplesRequest{
Dataset: "<dataset-id-or-name>", Space: "<space-id-or-name>",
Annotations: []datasets.AnnotateRecordInput{ /* RecordId + AnnotationInput values */ },
})
Operations on Experiments
Use client.Experiments to manage experiments — a named set of task runs over a dataset,
optionally carrying evaluator results. Dataset is required to create or resolve an
experiment by name; Space is required when Dataset is itself a name. On Create,
each run is a row of user-named columns: TaskFields names the example-ID and output
columns, and EvaluatorColumns remaps evaluator result columns to the wire format.
A full runnable example lives in examples/experiments.
List Experiments
resp, err := client.Experiments.List(ctx, experiments.ListRequest{
Dataset: "<dataset-id-or-name>", // optional filter
Space: "<space-id-or-name>", // required when Dataset is a name
Limit: 25,
})
Get an Experiment
exp, err := client.Experiments.Get(ctx, experiments.GetRequest{
Experiment: "<experiment-id-or-name>",
Dataset: "<dataset-id-or-name>", // required when Experiment is a name
Space: "<space-id-or-name>", // required when Dataset is also a name
})
Create an Experiment
Each run maps your column names to the wire format via TaskFields (required) and
EvaluatorColumns (optional). Non-string outputs are JSON-encoded automatically.
exp, err := client.Experiments.Create(ctx, experiments.CreateRequest{
Dataset: "<dataset-id-or-name>",
Space: "<space-id-or-name>", // required when Dataset is a name
Name: "my-experiment",
Runs: []map[string]any{
{"example_id": "ex-1", "answer": "Paris", "relevance_score": 0.9, "relevance_label": "relevant"},
},
TaskFields: experiments.TaskFields{ExampleID: "example_id", Output: "answer"},
EvaluatorColumns: map[string]experiments.EvaluatorFields{
"relevance": {Score: "relevance_score", Label: "relevance_label"},
},
})
Delete an Experiment
err := client.Experiments.Delete(ctx, experiments.DeleteRequest{Experiment: "<experiment-id>"})
List Runs
Optionally narrow the results with an SQL-like filter over id, output, example_id, custom run columns, and eval.<name>.* / annotation.<name>.* fields. Limit defaults to 50 (max 500); page through results with Cursor from Pagination.NextCursor, keeping Filter unchanged between pages.
runs, err := client.Experiments.ListRuns(ctx, experiments.ListRunsRequest{
Experiment: "<experiment-id-or-name>",
Dataset: "<dataset-id-or-name>", // required when Experiment is a name
Space: "<space-id-or-name>", // required when Dataset is also a name
Limit: 50,
})
filter := "eval.correctness.score < 0.8"
filtered, err := client.Experiments.ListRuns(ctx, experiments.ListRunsRequest{
Experiment: "<experiment-id-or-name>",
Dataset: "<dataset-id-or-name>", // required when Experiment is a name
Space: "<space-id-or-name>", // required when Dataset is also a name
Filter: filter,
Limit: 50,
})
Append Runs
Append between 1 and 1000 new runs to an existing experiment. Each run must include ExampleId (the ID of an example from the experiment's dataset) and Output; additional user-defined fields go in AdditionalProperties. The response includes the updated experiment and the generated run IDs in input order.
result, err := client.Experiments.AppendRuns(ctx, experiments.AppendRunsRequest{
ExperimentID: "<experiment-id>",
ExperimentRuns: []experiments.ExperimentRunInput{
{ExampleId: "example-1", Output: "An AI observability platform."},
{ExampleId: "example-2", Output: "A unit of work in a trace."},
},
})
Operations on Prompts
Use client.Prompts to manage prompts, their versions, and version labels. Space is
required when Prompt is a name; version-by-ID and label operations take a strict
VersionID.
A full runnable example lives in examples/prompts.
List Prompts
resp, err := client.Prompts.List(ctx, prompts.ListRequest{Limit: 25})
Get a Prompt
Get accepts an optional VersionID or Label to pin a version.
p, err := client.Prompts.Get(ctx, prompts.GetRequest{Prompt: "<prompt-id-or-name>", Space: "<space-id-or-name>"})
Create a Prompt
Created with the initial version.
content := "You are a helpful assistant. Answer: {question}"
p, err := client.Prompts.Create(ctx, prompts.CreateRequest{
Name: "my-prompt",
Space: "<space-id-or-name>",
Version: prompts.PromptVersionCreate{
CommitMessage: "initial version",
Provider: prompts.LlmProviderOpenAi,
Messages: []prompts.LLMMessage{{Role: prompts.MessageRoleSystem, Content: &content}},
},
})
Update a Prompt
Description is a PATCH pointer.
desc := "new description"
p, err := client.Prompts.Update(ctx, prompts.UpdateRequest{Prompt: "<prompt-id-or-name>", Space: "<space-id-or-name>", Description: &desc})
Delete a Prompt
err := client.Prompts.Delete(ctx, prompts.DeleteRequest{Prompt: "<prompt-id>"})
List Versions
versions, err := client.Prompts.ListVersions(ctx, prompts.ListVersionsRequest{Prompt: "<prompt-id-or-name>", Space: "<space-id-or-name>", Limit: 25})
Create a Version
content := "You are a helpful assistant. Answer: {question}"
v, err := client.Prompts.CreateVersion(ctx, prompts.CreateVersionRequest{
Prompt: "<prompt-id-or-name>", Space: "<space-id-or-name>",
CommitMessage: "tweak", Provider: prompts.LlmProviderOpenAi,
Messages: []prompts.LLMMessage{{Role: prompts.MessageRoleSystem, Content: &content}},
})
Get a Version
v, err := client.Prompts.GetVersion(ctx, prompts.GetVersionRequest{VersionID: "<version-id>"})
Get a Version by Label
v, err := client.Prompts.GetVersionByLabel(ctx, prompts.GetVersionByLabelRequest{Prompt: "<prompt-id-or-name>", Space: "<space-id-or-name>", LabelName: "production"})
Set Version Labels
Replaces all labels on a version.
labels, err := client.Prompts.SetVersionLabels(ctx, prompts.SetVersionLabelsRequest{VersionID: "<version-id>", Labels: []string{"production"}})
Delete a Version Label
Removes one label.
err := client.Prompts.DeleteVersionLabel(ctx, prompts.DeleteVersionLabelRequest{VersionID: "<version-id>", LabelName: "production"})
Operations on Evaluators
Use client.Evaluators to manage evaluators and their versions. Three evaluator
types are supported: TEMPLATE (LLM-based), CODE (managed built-in or custom Python),
and REMOTE (customer-hosted HTTP endpoint via an EVALUATOR integration). Space is
required when Evaluator is a name.
A full runnable example lives in examples/evaluators.
List Evaluators
resp, err := client.Evaluators.List(ctx, evaluators.ListRequest{Limit: 25})
Get an Evaluator
The returned version is a oneOf — read the active variant via ValueByDiscriminator and a type switch.
ev, err := client.Evaluators.Get(ctx, evaluators.GetRequest{Evaluator: "<evaluator-id-or-name>", Space: "<space-id-or-name>"})
if v, err := ev.Version.ValueByDiscriminator(); err == nil {
switch v := v.(type) {
case evaluators.EvaluatorVersionTemplate:
_ = v.TemplateConfig.Template
case evaluators.EvaluatorVersionCode:
_ = v.CodeConfig
case evaluators.EvaluatorVersionRemote:
_ = v.RemoteConfig.IntegrationId
}
}
Create a Template Evaluator
ev, err := client.Evaluators.CreateTemplateEvaluator(ctx, evaluators.CreateTemplateEvaluatorRequest{
Name: "relevance",
Space: "<space-id-or-name>",
CommitMessage: "initial version",
Config: evaluators.TemplateConfigInput{
Name: "relevance",
Template: "Is the answer relevant?\n{{input}}",
ClassificationChoices: &map[string]float32{"relevant": 1, "irrelevant": 0},
LlmConfig: &evaluators.EvaluatorLlmConfigRequest{AiIntegrationId: "<ai-integration-id>", ModelName: "gpt-4o"},
},
})
Create a Code Evaluator
ev, err := client.Evaluators.CreateCodeEvaluator(ctx, evaluators.CreateCodeEvaluatorRequest{
Name: "hallucination",
Space: "<space-id-or-name>",
CommitMessage: "initial version",
Config: evaluators.CodeConfig{
Managed: &evaluators.ManagedCodeConfig{
Name: "hallucination",
ManagedEvaluator: "hallucination",
Variables: []string{"input", "output", "context"},
},
},
})
Create a Remote Evaluator
Create a REMOTE evaluator backed by an existing EVALUATOR integration. Requires the
enableRemoteEvalTasks feature flag on the account.
ev, err := client.Evaluators.CreateRemoteEvaluator(ctx, evaluators.CreateRemoteEvaluatorRequest{
Name: "my-remote-eval",
Space: "<space-id-or-name>",
CommitMessage: "initial version",
IntegrationID: "<evaluator-integration-id>",
})
Update an Evaluator
Name/Description are PATCH pointers — at least one is required, else evaluators.ErrNoUpdateFields.
newName := "renamed-evaluator"
md, err := client.Evaluators.Update(ctx, evaluators.UpdateRequest{Evaluator: "<evaluator-id-or-name>", Space: "<space-id-or-name>", Name: &newName})
Delete an Evaluator
err := client.Evaluators.Delete(ctx, evaluators.DeleteRequest{Evaluator: "<evaluator-id>"})
List Versions
vers, err := client.Evaluators.ListVersions(ctx, evaluators.ListVersionsRequest{Evaluator: "<evaluator-id-or-name>", Space: "<space-id-or-name>", Limit: 25})
Create a Template Version
ver, err := client.Evaluators.CreateTemplateVersion(ctx, evaluators.CreateTemplateVersionRequest{
Evaluator: "<evaluator-id-or-name>",
Space: "<space-id-or-name>",
CommitMessage: "tighten rubric",
Config: evaluators.TemplateConfigInput{ /* ... */ },
})
Create a Code Version
ver, err := client.Evaluators.CreateCodeVersion(ctx, evaluators.CreateCodeVersionRequest{
Evaluator: "<evaluator-id-or-name>",
Space: "<space-id-or-name>",
CommitMessage: "update logic",
Config: evaluators.CodeConfig{
Custom: &evaluators.CustomCodeConfig{
Name: "my-custom",
Code: "class Eval:\n def evaluate(self, **kwargs):\n return 1",
Variables: []string{"input"},
},
},
})
Create a Remote Version
ver, err := client.Evaluators.CreateRemoteVersion(ctx, evaluators.CreateRemoteVersionRequest{
Evaluator: "<evaluator-id-or-name>",
Space: "<space-id-or-name>",
CommitMessage: "switch endpoint",
IntegrationID: "<evaluator-integration-id>",
})
Get a Version
ver, err := client.Evaluators.GetVersion(ctx, evaluators.GetVersionRequest{VersionID: "<version-id>"})
Delete Versions
Removes versions from an evaluator. Versions that exist and belong to that
evaluator are deleted; missing or foreign IDs come back in
NotDeletedVersionIds. Re-sending already-deleted IDs is safe. On HTTP 200,
Completed is true because the request finished, not because every ID was
found. If a deleted version was pinned to a running online task, that pin is
cleared and the task uses the latest version.
resp, err := client.Evaluators.DeleteVersions(ctx, evaluators.DeleteVersionsRequest{
Evaluator: "<evaluator-id-or-name>",
Space: "<space-id-or-name>",
VersionIDs: []string{"<version-id>"},
})
Operations on Annotation Configs
Use client.AnnotationConfigs to manage annotation configs. The config type
(Categorical, Continuous, Freeform) selects which fields are required. The
returned AnnotationConfig is a discriminated union — read it via
ValueByDiscriminator and a type switch over the variant.
A full runnable example lives in examples/annotationconfigs.
List Annotation Configs
resp, err := client.AnnotationConfigs.List(ctx, annotationconfigs.ListRequest{Space: "<space-id-or-name>", Limit: 25})
Get an Annotation Config
ac, err := client.AnnotationConfigs.Get(ctx, annotationconfigs.GetRequest{AnnotationConfig: "<config-id-or-name>", Space: "<space-id-or-name>"})
if v, err := ac.ValueByDiscriminator(); err == nil {
if cfg, ok := v.(annotationconfigs.CategoricalAnnotationConfig); ok {
_ = cfg.Values
}
}
Create an Annotation Config
Use the type-specific method matching the config you want: CreateCategorical (Values required), CreateContinuous (MinimumScore/MaximumScore required), or CreateFreeform (no extra fields).
score1, score0 := 1.0, 0.0
categorical, err := client.AnnotationConfigs.CreateCategorical(ctx, annotationconfigs.CreateCategoricalRequest{
Space: "<space-id-or-name>",
Name: "quality",
Values: []annotationconfigs.CategoricalAnnotationValue{
{Label: "good", Score: &score1},
{Label: "bad", Score: &score0},
},
})
continuous, err := client.AnnotationConfigs.CreateContinuous(ctx, annotationconfigs.CreateContinuousRequest{
Space: "<space-id-or-name>",
Name: "score",
MinimumScore: 0.0,
MaximumScore: 1.0,
})
freeform, err := client.AnnotationConfigs.CreateFreeform(ctx, annotationconfigs.CreateFreeformRequest{
Space: "<space-id-or-name>",
Name: "notes",
})
Update an Annotation Config
There is a distinct Update* method per annotation config type — UpdateCategorical,
UpdateContinuous, and UpdateFreeform. Leave a patch field nil to preserve its
current value.
name := "quality-v2"
ac, err := client.AnnotationConfigs.UpdateCategorical(ctx, annotationconfigs.UpdateCategoricalRequest{
AnnotationConfig: "<config-id-or-name>",
Space: "<space-id-or-name>",
Name: &name,
Values: &[]annotationconfigs.CategoricalAnnotationValue{
{Label: "good"},
{Label: "bad"},
},
})
maxScore := 10.0
ac, err := client.AnnotationConfigs.UpdateContinuous(ctx, annotationconfigs.UpdateContinuousRequest{
AnnotationConfig: "<config-id-or-name>",
Space: "<space-id-or-name>",
MaximumScore: &maxScore,
})
name := "notes-v2"
ac, err := client.AnnotationConfigs.UpdateFreeform(ctx, annotationconfigs.UpdateFreeformRequest{
AnnotationConfig: "<config-id-or-name>",
Space: "<space-id-or-name>",
Name: &name,
})
Delete an Annotation Config
err := client.AnnotationConfigs.Delete(ctx, annotationconfigs.DeleteRequest{AnnotationConfig: "<config-id>"})
Operations on AI Integrations
Use client.AIIntegrations to manage connections to LLM providers (OpenAI, Anthropic,
AWS Bedrock, Vertex AI, …). On Update, nil patch fields are preserved and
pointer-to-empty-string clears a clearable field.
A full runnable example lives in examples/aiintegrations.
List AI Integrations
resp, err := client.AIIntegrations.List(ctx, aiintegrations.ListRequest{Limit: 25})
Get an AI Integration
ai, err := client.AIIntegrations.Get(ctx, aiintegrations.GetRequest{Integration: "<integration-id-or-name>"})
Create an AI Integration
Provider key inline, or ProviderMetadata for AWS Bedrock / Vertex AI.
ai, err := client.AIIntegrations.Create(ctx, aiintegrations.CreateRequest{
Name: "my-anthropic",
Provider: aiintegrations.AIIntegrationProviderAnthropic,
APIKey: "<provider-api-key>",
})
Update an AI Integration
Rotate the key, clear the base URL (&"" emits JSON null), preserve everything else.
newKey, clearBaseURL := "<new-key>", ""
ai, err := client.AIIntegrations.Update(ctx, aiintegrations.UpdateRequest{
Integration: "<integration-id>", APIKey: &newKey, BaseURL: &clearBaseURL,
})
Delete an AI Integration
err := client.AIIntegrations.Delete(ctx, aiintegrations.DeleteRequest{Integration: "<integration-id>"})
Operations on Integrations
Use client.Integrations for the polymorphic /v2/integrations surface covering
both LLM (model-provider) and agent (customer-hosted endpoint) integrations.
Integration names are unique per account and type, so Type is required when
resolving a name; an ID always works on its own.
Alpha: integrations are a pre-release feature. Every method emits a one-time pre-release warning and the API may change in a backward-incompatible way.
A full runnable example lives in examples/integrations.
List Integrations
Type is an optional filter. Omit it to list every type in one call; each item
is a type-tagged union — read the active variant with Discriminator() and
unwrap with AsLlmIntegration / AsAgentIntegration.
resp, err := client.Integrations.List(ctx, integrations.ListRequest{Type: integrations.IntegrationTypeLLM, Limit: 25})
all, err := client.Integrations.List(ctx, integrations.ListRequest{})
Get an Integration
By ID, or by name plus Type.
it, err := client.Integrations.Get(ctx, integrations.GetRequest{
Integration: "my-openai", Type: integrations.IntegrationTypeLLM,
})
Create an LLM Integration
Set exactly one provider field on CreateLLMConfig; the SDK fills in the
provider discriminator. All ten providers are supported: OpenAI,
Anthropic, Gemini, AWSBedrock, Custom, VertexAI, NvidiaNIM,
LiteLLM, Fireworks and TogetherAi.
it, err := client.Integrations.CreateLLM(ctx, integrations.CreateLLMRequest{
Name: "my-openai",
Config: integrations.CreateLLMConfig{
OpenAI: &integrations.CreateOpenAIConfig{APIKey: "<provider-api-key>"},
},
})
A hosted provider that resolves its own model list needs only the key. Arize
reads the models the key can reach from the Fireworks account, so an
integration created without ModelNames still has a selectable model list.
it, err := client.Integrations.CreateLLM(ctx, integrations.CreateLLMRequest{
Name: "my-fireworks",
Config: integrations.CreateLLMConfig{
Fireworks: &integrations.CreateFireworksConfig{APIKey: "<provider-api-key>"},
},
})
Together AI resolves its own model list the same way.
it, err := client.Integrations.CreateLLM(ctx, integrations.CreateLLMRequest{
Name: "my-together-ai",
Config: integrations.CreateLLMConfig{
TogetherAi: &integrations.CreateTogetherAiConfig{APIKey: "<provider-api-key>"},
},
})
Create an Agent Integration
it, err := client.Integrations.CreateAgent(ctx, integrations.CreateAgentRequest{
Name: "my-agent",
Endpoint: "https://agent.example.com/invoke",
InputSchema: map[string]any{
"type": "object",
"properties": map[string]any{"input": map[string]any{"type": "string"}},
},
})
Update an Integration
Updates are split by type: UpdateLLM / UpdateAgent. Nil patch fields are
preserved; nullable fields clear with a pointer-to-empty value (emits JSON null).
newKey := "<new-key>"
it, err := client.Integrations.UpdateLLM(ctx, integrations.UpdateLLMRequest{
Integration: "my-openai", APIKey: &newKey,
})
Delete an Integration
By ID, or by name plus Type. Irreversible.
err := client.Integrations.Delete(ctx, integrations.DeleteRequest{
Integration: "my-agent", Type: integrations.IntegrationTypeAgent,
})
Operations on Organizations
Use client.Organizations to manage organizations and their memberships. Organization
accepts a name or ID.
A full runnable example lives in examples/organizations.
List Organizations
resp, err := client.Organizations.List(ctx, organizations.ListRequest{Limit: 25})
Get an Organization
org, err := client.Organizations.Get(ctx, organizations.GetRequest{Organization: "<org-id-or-name>"})
Create an Organization
org, err := client.Organizations.Create(ctx, organizations.CreateRequest{Name: "acme"})
Update an Organization
Name/Description are PATCH pointers.
newName := "acme-renamed"
org, err := client.Organizations.Update(ctx, organizations.UpdateRequest{Organization: "<org-id-or-name>", Name: &newName})
Delete an Organization
Irreversible.
err := client.Organizations.Delete(ctx, organizations.DeleteRequest{Organization: "<org-id>"})
Add a User
The returned membership's Role is a discriminated union — read it via ValueByDiscriminator and a type switch.
m, err := client.Organizations.AddUser(ctx, organizations.AddUserRequest{
Organization: "<org-id>", UserID: "<user-id>",
Role: organizations.PredefinedOrgRole{Name: organizations.OrganizationRoleMember},
})
Remove a User
err := client.Organizations.RemoveUser(ctx, organizations.RemoveUserRequest{Organization: "<org-id>", UserID: "<user-id>"})
Operations on Roles
Use client.Roles to manage RBAC roles. Permissions are referenced through the typed
roles.Permissions namespace. Role accepts a name or ID.
A full runnable example lives in examples/roles.
List Roles
IsPredefined is a tri-state filter: &true (system roles), &false (custom), nil (both).
predefined := true
resp, err := client.Roles.List(ctx, roles.ListRequest{IsPredefined: &predefined, Limit: 25})
Get a Role
role, err := client.Roles.Get(ctx, roles.GetRequest{Role: "<role-id-or-name>"})
Create a Role
role, err := client.Roles.Create(ctx, roles.CreateRequest{
Name: "read-only",
Description: "read-only access to projects",
Permissions: []roles.Permission{roles.Permissions.ProjectRead, roles.Permissions.ProjectSpanRead},
})
Update a Role
PATCH pointers: nil preserves, non-nil replaces; &"" clears Description (Name/Permissions cannot be emptied).
desc := ""
role, err := client.Roles.Update(ctx, roles.UpdateRequest{
Role: "<role-id>",
Description: &desc,
Permissions: &[]roles.Permission{roles.Permissions.ProjectRead, roles.Permissions.DatasetRead},
})
Delete a Role
Predefined roles cannot be deleted (server returns 400).
err := client.Roles.Delete(ctx, roles.DeleteRequest{Role: "<role-id>"})
Operations on Role Bindings
Use client.RoleBindings to bind a role to a user on a resource. These take strict IDs
(no name resolution).
A full runnable example lives in examples/rolebindings.
Get a Role Binding
rb, err := client.RoleBindings.Get(ctx, rolebindings.GetRequest{RoleBindingID: "<binding-id>"})
Create a Role Binding
rb, err := client.RoleBindings.Create(ctx, rolebindings.CreateRequest{
ResourceID: "<space-id>",
ResourceType: rolebindings.RoleBindingResourceTypeSPACE,
RoleID: "<role-id>",
UserID: "<user-id>",
})
UserID is the ID of the user to bind the role to. To bind a service key, pass its
bot user's ID instead of your own — it is returned as BotUser.ID from
APIKeys.CreateServiceKey (see Create a Service Key below).
Update a Role Binding
rb, err := client.RoleBindings.Update(ctx, rolebindings.UpdateRequest{RoleBindingID: "<binding-id>", RoleID: "<new-role-id>"})
Delete a Role Binding
err := client.RoleBindings.Delete(ctx, rolebindings.DeleteRequest{RoleBindingID: "<binding-id>"})
Operations on API Keys
Use client.APIKeys to manage API keys. The plaintext key is returned only at creation
or refresh — store it immediately, it cannot be retrieved later. CreateServiceKey
provisions a bot user with space/org/account roles.
A full runnable example lives in examples/apikeys.
List API Keys
Filter by key type and status. Each returned apikeys.APIKey is a discriminated union — use
Discriminator() (or try AsServiceApiKey()/AsUserApiKey() directly) to read it. A service
key's variant includes BotUser, the same bot user detail returned by CreateServiceKey — use
BotUser.Id as the UserID when creating a role binding for that key.
resp, err := client.APIKeys.List(ctx, apikeys.ListRequest{
KeyType: apikeys.APIKeyTypeUser,
Status: apikeys.APIKeyStatusActive,
Limit: 25,
})
for _, k := range resp.ApiKeys {
if svc, err := k.AsServiceApiKey(); err == nil {
fmt.Println(svc.Name, svc.BotUser.Id)
continue
}
user, err := k.AsUserApiKey()
fmt.Println(user.Name)
}
Create an API Key
created.Key holds the only copy of the secret.
created, err := client.APIKeys.Create(ctx, apikeys.CreateRequest{
Name: "example-key",
ExpiresAt: time.Now().Add(30 * 24 * time.Hour), // zero = never expires
})
Create a Service Key
A key bound to a dedicated bot user scoped to one or more organizations and spaces.
svc, err := client.APIKeys.CreateServiceKey(ctx, apikeys.CreateServiceKeyRequest{
Name: "ci-bot",
Orgs: []apikeys.OrgBinding{
{
OrgID: "<org-hmac-id>",
// Role is optional; zero = server applies predefined read-only role.
// Use AssignPredefinedOrgRole or AssignCustomOrgRole to set explicitly.
Spaces: []apikeys.SpaceBinding{
{Space: "<space-name-or-id>", Role: apikeys.AssignPredefinedSpaceRole(apikeys.SpaceRoleMember)},
},
},
},
})
// svc.BotUser.Id — the bot user created for this key
// svc.Key — the raw key value, returned only once; store it securely
Refresh an API Key
Refresh rotates an existing API key, invalidating the old one and returning a new key value. Use GracePeriodSeconds to keep the old key valid for a short overlap period while rolling over clients.
newKey, err := client.APIKeys.Refresh(ctx, apikeys.RefreshRequest{
APIKeyID: "<api-key-id>",
ExpiresAt: time.Now().Add(90 * 24 * time.Hour), // optional; zero = never expires
GracePeriodSeconds: 3600, // optional; if not specified, old key is deleted immediately
})
// newKey.ApiKeyValue — the new raw key value (only returned at refresh time)
Revoke an API Key
Revoke sets the key's status to revoked, deactivating it immediately. Revoking is
irreversible; revoking an already-revoked key is a no-op and still succeeds.
err := client.APIKeys.Revoke(ctx, apikeys.RevokeRequest{APIKeyID: "<key-id>"})
Operations on Resource Restrictions
Use client.ResourceRestrictions to restrict a resource (e.g. a project), preventing
roles bound at higher levels (space, org, account) from granting access. Both
calls take the restricted resource ID (e.g. a project ID), not a
restriction-record ID. Only PROJECT resources are supported today.
A full runnable example lives in examples/resourcerestrictions.
List Resource Restrictions
resp, err := client.ResourceRestrictions.List(ctx, resourcerestrictions.ListRequest{
Limit: 50, // optional
})
Restrict a Resource
Restrict is idempotent — restricting an already-restricted resource returns the existing restriction without error.
rr, err := client.ResourceRestrictions.Restrict(ctx, resourcerestrictions.RestrictRequest{
ResourceID: "<resource-id>",
})
_ = rr // *ResourceRestriction
Unrestrict a Resource
if err := client.ResourceRestrictions.Unrestrict(ctx, resourcerestrictions.UnrestrictRequest{ResourceID: "<resource-id>"}); err != nil {
var nfe *arize.NotFoundError
if errors.As(err, &nfe) {
// resource restriction already gone
}
}
Operations on Annotation Queues
Use client.AnnotationQueues to manage annotation queues — collections of records
(spans, traces, sessions, or dataset examples) routed to annotators for human
labeling.
A full runnable example lives in examples/annotationqueues.
List Annotation Queues
resp, err := client.AnnotationQueues.List(ctx, annotationqueues.ListRequest{
Space: "<space-id-or-name>", // optional
Name: "eval", // optional substring filter
Limit: 50, // optional
})
Get an Annotation Queue
queue, err := client.AnnotationQueues.Get(ctx, annotationqueues.GetRequest{
AnnotationQueue: "<queue-id-or-name>",
Space: "<space-id-or-name>", // required when AnnotationQueue is a name
})
Create an Annotation Queue
queue, err := client.AnnotationQueues.Create(ctx, annotationqueues.CreateRequest{
Space: "<space-id-or-name>",
Name: "my-queue",
Instructions: "Rate each response for helpfulness.", // optional
AnnotatorEmails: []annotationqueues.Email{"annotator@example.com"}, // optional
AssignmentMethod: annotationqueues.AssignmentMethodAll, // optional
})
Add Records to a Queue
Build a record source with NewSpanRecordSource, NewTraceRecordSource,
NewSessionRecordSource, or NewExampleRecordSource, then add up to two sources
per request. A request may resolve up to 500 records, including at most 100
sessions.
src, err := annotationqueues.NewSessionRecordSource(annotationqueues.AnnotationQueueSessionRecordInput{
ProjectId: "<project-id>",
StartTime: time.Now().Add(-24 * time.Hour),
EndTime: time.Now(),
SessionIds: []string{"<session-id>"},
})
if err != nil {
// handle error
}
resp, err := client.AnnotationQueues.AddRecords(ctx, annotationqueues.AddRecordsRequest{
AnnotationQueue: "<queue-id-or-name>",
Space: "<space-id-or-name>",
RecordSources: []annotationqueues.AnnotationQueueRecordInput{src},
})
Annotate a Record
Beta: annotating and assigning records is a pre-release feature.
AnnotateandAssigneach emit a one-time pre-release warning and their API may change in a backward-incompatible way.
RecordID is a strict ID (no name resolution) — read it from ListRecords.
score := 0.9
result, err := client.AnnotationQueues.Annotate(ctx, annotationqueues.AnnotateRequest{
AnnotationQueue: "<queue-id-or-name>",
Space: "<space-id-or-name>",
RecordID: "<record-id>",
Annotations: []annotationqueues.AnnotationInput{{Name: "helpfulness", Score: &score}},
})
Update an Annotation Queue
Patch semantics: a nil field is left unchanged, a non-nil field replaces the value.
instructions := "Updated instructions."
queue, err := client.AnnotationQueues.Update(ctx, annotationqueues.UpdateRequest{
AnnotationQueue: "<queue-id-or-name>",
Space: "<space-id-or-name>", // required when AnnotationQueue is a name
Instructions: &instructions,
})
Delete an Annotation Queue
err := client.AnnotationQueues.Delete(ctx, annotationqueues.DeleteRequest{
AnnotationQueue: "<queue-id-or-name>",
Space: "<space-id-or-name>", // required when AnnotationQueue is a name
})
Operations on Users
Use client.Users to manage account users. These take strict user IDs, except Get,
whose User field accepts a user ID or an email address.
Beta: users are a pre-release feature. Every method emits a one-time pre-release warning and the API may change in a backward-incompatible way.
A full runnable example lives in examples/users.
List Users
Email is a case-insensitive substring filter; Status filters by account state
(active, invited, expired).
resp, err := client.Users.List(ctx, users.ListRequest{
Status: []users.UserStatus{users.UserStatusActive, users.UserStatusInvited},
Limit: 25,
})
Get a User
User accepts a user ID or an email address (resolved by case-insensitive exact
match; a non-matching email yields a *ResourceNotFoundError).
user, err := client.Users.Get(ctx, users.GetRequest{User: "user@example.com"})
Create a User
Build the account-level role with AssignPredefinedRole (or AssignCustomRole).
InviteMode controls whether and how an invitation is sent.
user, err := client.Users.Create(ctx, users.CreateRequest{
Name: "Ada Lovelace",
Email: "user@example.com",
Role: users.AssignPredefinedRole(users.UserRoleMember),
InviteMode: users.InviteModeEmailLink,
})
Update a User
Name/IsDeveloper are PATCH pointers: nil preserves the current value, non-nil
sets it. At least one must be non-nil.
newName := "Ada Lovelace"
isDeveloper := true
user, err := client.Users.Update(ctx, users.UpdateRequest{
UserID: "<user-id>",
Name: &newName,
IsDeveloper: &isDeveloper,
})
Delete a User
Soft-delete; cascades to org/space memberships, API keys, and role bindings. Idempotent.
err := client.Users.Delete(ctx, users.DeleteRequest{UserID: "<user-id>"})
Bulk Delete Users
Delete by ID and/or email. Per-user outcomes are returned rather than aborting
the batch: an unresolved email is DeletionStatusNotFound, a failed delete is
DeletionStatusFailed.
results, err := client.Users.BulkDelete(ctx, users.BulkDeleteRequest{
UserIDs: []string{"<user-id>"},
Emails: []string{"user@example.com"},
})
for _, r := range results {
// UserID is set for resolved users; Email is set when the user was
// specified by email (and is the only identifier for not_found).
fmt.Printf("user=%q email=%q: %s\n", r.UserID, r.Email, r.Status)
}
Resend an Invitation
The target user must still be in the invited state.
err := client.Users.ResendInvitation(ctx, users.ResendInvitationRequest{UserID: "<user-id>"})
Reset a Password
Password-auth users only (not SSO/SAML); the account must be verified.
err := client.Users.ResetPassword(ctx, users.ResetPasswordRequest{UserID: "<user-id>"})
Operations on Tasks
Use client.Tasks to manage tasks — automated jobs that evaluate data
(template_evaluation / code_evaluation) or run experiments
(run_experiment) — and their async runs.
Beta: tasks are a pre-release feature. Every method emits a one-time pre-release warning and the API may change in a backward-incompatible way.
A full runnable example lives in examples/tasks.
List Tasks
Space, Project, and Dataset accept a name or ID and filter results;
Type filters by task type.
resp, err := client.Tasks.List(ctx, tasks.ListRequest{
Space: "demo",
Type: tasks.TaskTypeTemplateEvaluation,
Limit: 25,
})
Get a Task
Task accepts a task name or ID; Space is required when it is a name.
task, err := client.Tasks.Get(ctx, tasks.GetRequest{Task: "my-task", Space: "demo"})
Create an Evaluation Task
Creates a template_evaluation or code_evaluation task (set Type).
Exactly one of Project or Dataset must be set; dataset-based tasks
require at least one entry in ExperimentIDs, and SamplingRate /
IsContinuous apply only to project-based tasks.
Each evaluator is either a [SpanEvaluatorInput] (span-granularity) or a [TraceOrSessionEvaluatorInput] (trace/session-granularity) — supply one type per entry; they are mutually exclusive.
Span-granularity task — uses QueryFilter at the task level and
SpanEvaluatorInput per evaluator:
task, err := client.Tasks.CreateEvaluationTask(ctx, tasks.CreateEvaluationTaskRequest{
Name: "relevance-eval",
Type: tasks.TaskTypeTemplateEvaluation,
Project: "my-project",
Space: "demo",
QueryFilter: "span_kind = 'LLM'",
Evaluators: []tasks.EvaluatorInput{
tasks.SpanEvaluatorInput{
EvaluatorID: "<evaluator-id>",
ColumnMappings: map[string]string{"input": "attributes.input.value", "output": "attributes.output.value"},
},
},
SamplingRate: 0.5,
})
Trace/session-granularity task (multi-span query) — uses QueryFilters
at the task level and TraceOrSessionEvaluatorInput per evaluator:
expr := "A AND B"
task, err := client.Tasks.CreateEvaluationTask(ctx, tasks.CreateEvaluationTaskRequest{
Name: "trace-eval",
Type: tasks.TaskTypeTemplateEvaluation,
Project: "my-project",
Space: "demo",
QueryFilters: &tasks.TaskQueryFilters{
Filters: []tasks.TaskQueryFilter{
{Id: "A", Filter: "span_kind = 'LLM'"},
{Id: "B", Filter: "span_kind = 'RETRIEVER'"},
},
Expression: &expr,
},
Evaluators: []tasks.EvaluatorInput{
tasks.TraceOrSessionEvaluatorInput{
EvaluatorID: "<evaluator-id>",
QueryMappings: []tasks.TaskQueryMapping{
{VariableName: "input", QueryIds: []string{"A"}, AttributePath: "attributes.input.value"},
{VariableName: "output", QueryIds: []string{"B"}, AttributePath: "attributes.output.value"},
},
},
},
})
Create a Run-Experiment Task
RunConfiguration is a oneOf — populate exactly one variant via
FromLlmGenerationRunConfig or FromTemplateEvaluationRunConfig.
var rc tasks.RunConfiguration
err := rc.FromTemplateEvaluationRunConfig(tasks.TemplateEvaluationRunConfig{
AiIntegrationId: "<ai-integration-id>",
Template: "Is the answer relevant?\n{{input}}",
ProvideExplanation: true,
})
task, err := client.Tasks.CreateRunExperimentTask(ctx, tasks.CreateRunExperimentTaskRequest{
Name: "nightly-experiment",
Dataset: "my-dataset",
Space: "demo",
RunConfiguration: rc,
})
Update a Task
Patch fields are pointers: nil preserves the current value, non-nil sets it
(a pointer to "" clears QueryFilter). The SDK fetches the task first to
validate the fields against its type — SamplingRate, IsContinuous,
QueryFilter/QueryFilters, and Evaluators apply only to evaluation tasks;
RunConfiguration only to run_experiment tasks. An empty patch returns
tasks.ErrNoUpdateFields.
rate := float32(0.25)
task, err := client.Tasks.Update(ctx, tasks.UpdateRequest{
Task: "relevance-eval",
Space: "demo",
SamplingRate: &rate,
})
To switch a task to the trace/session shape, supply QueryFilters and
TraceOrSessionEvaluatorInput entries:
expr := "A"
task, err := client.Tasks.Update(ctx, tasks.UpdateRequest{
Task: "trace-eval",
Space: "demo",
QueryFilters: &tasks.TaskQueryFilters{
Filters: []tasks.TaskQueryFilter{{Id: "A", Filter: "span_kind = 'LLM'"}},
Expression: &expr,
},
Evaluators: []tasks.EvaluatorInput{
tasks.TraceOrSessionEvaluatorInput{
EvaluatorID: "<evaluator-id>",
QueryMappings: []tasks.TaskQueryMapping{
{VariableName: "input", QueryIds: []string{"A"}, AttributePath: "attributes.input.value"},
},
},
},
})
Delete a Task
Irreversible; cascades to the task's runs and configurations.
err := client.Tasks.Delete(ctx, tasks.DeleteRequest{Task: "relevance-eval", Space: "demo"})
Trigger a Run
Starts an async run (returned in pending status). The SDK fetches the task
first to validate the fields against its type: evaluation tasks take
DataStartTime / DataEndTime / MaxSpans / OverrideEvaluations /
ExperimentIDs; run_experiment tasks take ExperimentName (required),
DatasetVersionID, ExampleIDs / MaxExamples (mutually exclusive),
TracingMetadata, and EvaluationTaskIDs.
run, err := client.Tasks.TriggerRun(ctx, tasks.TriggerRunRequest{
Task: "relevance-eval",
Space: "demo",
DataStartTime: time.Now().Add(-time.Hour),
MaxSpans: 1000,
})
List Task Runs
Status filters by run state (pending, running, completed, failed, cancelled).
resp, err := client.Tasks.ListRuns(ctx, tasks.ListRunsRequest{
Task: "relevance-eval",
Space: "demo",
Status: tasks.TaskRunStatusCompleted,
})
Get a Run
Takes a strict run ID; use it to poll a run triggered by TriggerRun.
run, err := client.Tasks.GetRun(ctx, tasks.GetRunRequest{RunID: "<run-id>"})
Cancel a Run
Only valid while the run is pending or running.
run, err := client.Tasks.CancelRun(ctx, tasks.CancelRunRequest{RunID: "<run-id>"})
Wait for a Run
Polls until the run reaches a terminal state (completed, failed, or
cancelled). Defaults: 5s poll interval, 10m timeout; on expiry the error
wraps tasks.ErrWaitTimeout.
run, err := client.Tasks.WaitForRun(ctx, tasks.WaitForRunRequest{
RunID: "<run-id>",
PollInterval: 5 * time.Second,
Timeout: 5 * time.Minute,
})
SDK Configuration
Environment Variables
Most Config fields fall back to an environment variable when unset. Highlights:
| Env var | Config field | Default |
|---|---|---|
ARIZE_API_KEY |
APIKey |
(required) |
ARIZE_API_HOST |
APIHost |
api.arize.com |
ARIZE_API_SCHEME |
APIScheme |
https |
ARIZE_REGION |
Region |
(unset) |
ARIZE_BASE_DOMAIN |
BaseDomain |
(unset) |
ARIZE_SINGLE_HOST |
SingleHost |
(unset) |
ARIZE_SINGLE_PORT |
SinglePort |
(unset) |
ARIZE_REQUEST_VERIFY |
InsecureSkipVerify |
false (verified) |
ARIZE_MAX_HTTP_PAYLOAD_SIZE_MB |
MaxHTTPPayloadSizeMB |
8 |
ARIZE_DIRECTORY |
ArizeDirectory |
~/.arize |
ARIZE_ENABLE_CACHING |
DisableCaching |
true (caching on) |
ARIZE_MAX_PAST_YEARS |
MaxPastYears |
5 |
Boolean env vars accept 1, true, yes, on (case-insensitive) as truthy; any other non-empty value is treated as false.
Note:
InsecureSkipVerifyandDisableCachingare named for the negative so their Go zero values give the safe default (TLS verification on, caching on). The corresponding env vars (ARIZE_REQUEST_VERIFY,ARIZE_ENABLE_CACHING) keep the positive name.
TLS Verification
InsecureSkipVerify defaults to false — TLS certificates are verified. To opt out (e.g. for testing against a local server with a self-signed cert):
client, _ := arize.NewClient(arize.Config{
APIKey: "<your-api-key>",
InsecureSkipVerify: true, // or set ARIZE_REQUEST_VERIFY=false
})
HTTP Timeout
client, _ := arize.NewClient(arize.Config{
APIKey: "<your-api-key>",
HTTPTimeout: 60 * time.Second, // defaults to 30s
})
Local Directory and Caching
ArizeDirectory is reserved for SDK-managed local files (cache, logs). DisableCaching is wired through Config but caching itself is not yet active in v2 — these knobs exist now to keep call sites stable as features land.
client, _ := arize.NewClient(arize.Config{
APIKey: "<your-api-key>",
ArizeDirectory: "/var/lib/arize",
DisableCaching: true,
})
Community
Join our community to connect with thousands of AI builders.
- 🌍 Join our Slack community.
- 📚 Read our documentation.
- 💡 Ask questions and provide feedback in the #arize-support channel.
- 𝕏 Follow us on 𝕏.
- 🧑🏫 Deep dive into everything Agents and LLM Evaluations on Arize's Learning Hubs.
Copyright 2026 Arize AI, Inc. All Rights Reserved.