Skip to content

Latest commit

 

History

24 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation


Go Reference


Table of Contents

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 first v1.0.0 release. 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.

A full runnable example lives in examples/spaces.

List Spaces

resp, err := client.Spaces.List(ctx, spaces.ListRequest{Limit: 25})

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.

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

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.

resp, err := client.APIKeys.List(ctx, apikeys.ListRequest{
    KeyType: apikeys.APIKeyTypeUser,
    Status:  apikeys.APIKeyStatusActive,
    Limit:   25,
})

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. Annotate and Assign each 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: InsecureSkipVerify and DisableCaching are 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.

Copyright 2026 Arize AI, Inc. All Rights Reserved.

About

Go client for the Arize REST API. go get github.com/Arize-ai/client-go-v2

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages