> ## Documentation Index
> Fetch the complete documentation index at: https://arize-ax.mintlify.site/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Annotation Configs

> List, get, create, update, and delete annotation configs (categorical, continuous, freeform) using the Arize Go SDK.

<Note>
  The `annotationconfigs` client methods are currently in **ALPHA**. The API may change without notice. A one-time warning is emitted on first use.
</Note>

An annotation config defines the shape of human annotations attached to spans or dataset examples. Each config is one of three types: `categorical` (a fixed set of labels), `continuous` (a numeric score range), or `freeform` (open text). The `Get`, `UpdateCategorical`, `UpdateContinuous`, `UpdateFreeform`, and `Delete` methods accept either a config name or an ID — when a name is passed, the parent `Space` (name or ID) is also required. Each config type has its own dedicated `Create*` and `Update*` method so required fields stay statically typed.

## List Annotation Configs

`List` returns a paginated list of annotation configs. `Space`, when non-empty, accepts a space name or ID and restricts results to that space. `Name`, when non-empty, applies a case-insensitive substring filter on the annotation config name.

**Signature:**

```go theme={null}
func (c *Client) List(ctx context.Context, req ListRequest) (*AnnotationConfigList, error)
```

**Usage Example:**

```go theme={null}
package main

import (
    "context"
    "errors"
    "fmt"
    "log"

    "github.com/Arize-ai/client-go-v2/arize"
    "github.com/Arize-ai/client-go-v2/arize/annotationconfigs"
)

func main() {
    client, err := arize.NewClient(arize.Config{APIKey: "your-api-key"})
    if err != nil {
        log.Fatal(err)
    }

    resp, err := client.AnnotationConfigs.List(context.Background(), annotationconfigs.ListRequest{
        Space: "your-space-name-or-id",
        Limit: 25,
    })
    if err != nil {
        var unauthorized *arize.UnauthorizedError
        if errors.As(err, &unauthorized) {
            log.Fatalf("unauthorized: %v", unauthorized)
        }
        log.Fatal(err)
    }

    for _, ac := range resp.AnnotationConfigs {
        if d, err := ac.Discriminator(); err == nil {
            fmt.Printf("annotation config (type=%s)\n", d)
        }
    }
}
```

## Get an Annotation Config

`Get` returns a single annotation config, resolving by name or ID. The returned `AnnotationConfig` is a discriminated union — call `ac.AsCategoricalAnnotationConfig()`, `AsContinuousAnnotationConfig()`, or `AsFreeformAnnotationConfig()` to extract the typed variant after checking the discriminator.

**Signature:**

```go theme={null}
func (c *Client) Get(ctx context.Context, req GetRequest) (*AnnotationConfig, error)
```

**Usage Example:**

```go theme={null}
package main

import (
    "context"
    "errors"
    "fmt"
    "log"

    "github.com/Arize-ai/client-go-v2/arize"
    "github.com/Arize-ai/client-go-v2/arize/annotationconfigs"
)

func main() {
    client, err := arize.NewClient(arize.Config{APIKey: "your-api-key"})
    if err != nil {
        log.Fatal(err)
    }

    ac, err := client.AnnotationConfigs.Get(
        context.Background(),
        annotationconfigs.GetRequest{
            AnnotationConfig: "your-config-name-or-id",
            Space:            "your-space-name-or-id",
        },
    )
    if err != nil {
        var notFound *arize.NotFoundError
        if errors.As(err, &notFound) {
            log.Fatalf("annotation config not found: %v", notFound)
        }
        log.Fatal(err)
    }

    if d, err := ac.Discriminator(); err == nil && d == string(annotationconfigs.AnnotationConfigTypeCategorical) {
        cat, err := ac.AsCategoricalAnnotationConfig()
        if err != nil {
            log.Fatal(err)
        }
        fmt.Printf("categorical %s with %d values\n", cat.Name, len(cat.Values))
    }
}
```

## Create a Categorical Annotation Config

`CreateCategorical` creates a new categorical annotation config (a fixed set of labeled values a scorer can choose from), resolving the parent space by name or ID. `Values` is required; `OptimizationDirection` is optional and defaults to `none` on the server.

**Signature:**

```go theme={null}
func (c *Client) CreateCategorical(
    ctx context.Context,
    req CreateCategoricalRequest,
) (*AnnotationConfig, error)
```

**Usage Example:**

```go theme={null}
package main

import (
    "context"
    "errors"
    "fmt"
    "log"

    "github.com/Arize-ai/client-go-v2/arize"
    "github.com/Arize-ai/client-go-v2/arize/annotationconfigs"
)

func main() {
    client, err := arize.NewClient(arize.Config{APIKey: "your-api-key"})
    if err != nil {
        log.Fatal(err)
    }

    ac, err := client.AnnotationConfigs.CreateCategorical(
        context.Background(),
        annotationconfigs.CreateCategoricalRequest{
            Space: "your-space-name-or-id",
            Name:  "quality",
            Values: []annotationconfigs.CategoricalAnnotationValue{
                {Label: "correct"},
                {Label: "incorrect"},
            },
            OptimizationDirection: annotationconfigs.OptimizationDirectionMaximize,
        },
    )
    if err != nil {
        var conflict *arize.ConflictError
        if errors.As(err, &conflict) {
            log.Fatalf("annotation config already exists: %v", conflict)
        }
        log.Fatal(err)
    }

    if cat, err := ac.AsCategoricalAnnotationConfig(); err == nil {
        fmt.Printf("created categorical annotation config %s\n", cat.Name)
    }
}
```

## Create a Continuous Annotation Config

`CreateContinuous` creates a new continuous annotation config (a numeric score within a fixed range), resolving the parent space by name or ID. `MinimumScore` and `MaximumScore` are required.

**Signature:**

```go theme={null}
func (c *Client) CreateContinuous(
    ctx context.Context,
    req CreateContinuousRequest,
) (*AnnotationConfig, error)
```

**Usage Example:**

```go theme={null}
package main

import (
    "context"
    "errors"
    "fmt"
    "log"

    "github.com/Arize-ai/client-go-v2/arize"
    "github.com/Arize-ai/client-go-v2/arize/annotationconfigs"
)

func main() {
    client, err := arize.NewClient(arize.Config{APIKey: "your-api-key"})
    if err != nil {
        log.Fatal(err)
    }

    ac, err := client.AnnotationConfigs.CreateContinuous(
        context.Background(),
        annotationconfigs.CreateContinuousRequest{
            Space:                 "your-space-name-or-id",
            Name:                  "helpfulness",
            MinimumScore:          0,
            MaximumScore:          1,
            OptimizationDirection: annotationconfigs.OptimizationDirectionMaximize,
        },
    )
    if err != nil {
        var conflict *arize.ConflictError
        if errors.As(err, &conflict) {
            log.Fatalf("annotation config already exists: %v", conflict)
        }
        log.Fatal(err)
    }

    if cont, err := ac.AsContinuousAnnotationConfig(); err == nil {
        fmt.Printf("created continuous annotation config %s\n", cont.Name)
    }
}
```

## Create a Freeform Annotation Config

`CreateFreeform` creates a new freeform annotation config (open-ended text feedback with no predefined scale), resolving the parent space by name or ID. Only `Space` and `Name` are required.

**Signature:**

```go theme={null}
func (c *Client) CreateFreeform(
    ctx context.Context,
    req CreateFreeformRequest,
) (*AnnotationConfig, error)
```

**Usage Example:**

```go theme={null}
package main

import (
    "context"
    "errors"
    "fmt"
    "log"

    "github.com/Arize-ai/client-go-v2/arize"
    "github.com/Arize-ai/client-go-v2/arize/annotationconfigs"
)

func main() {
    client, err := arize.NewClient(arize.Config{APIKey: "your-api-key"})
    if err != nil {
        log.Fatal(err)
    }

    ac, err := client.AnnotationConfigs.CreateFreeform(
        context.Background(),
        annotationconfigs.CreateFreeformRequest{
            Space: "your-space-name-or-id",
            Name:  "comments",
        },
    )
    if err != nil {
        var conflict *arize.ConflictError
        if errors.As(err, &conflict) {
            log.Fatalf("annotation config already exists: %v", conflict)
        }
        log.Fatal(err)
    }

    if free, err := ac.AsFreeformAnnotationConfig(); err == nil {
        fmt.Printf("created freeform annotation config %s\n", free.Name)
    }
}
```

## Update a Categorical Annotation Config

`UpdateCategorical` patches an existing categorical annotation config, resolving by name or ID. All patch fields are optional — leave a field `nil` to preserve its current value. When non-nil, `Values` replaces the full set of allowed labels (2–100 items).

**Signature:**

```go theme={null}
func (c *Client) UpdateCategorical(
    ctx context.Context,
    req UpdateCategoricalRequest,
) (*AnnotationConfig, error)
```

**Usage Example:**

```go theme={null}
package main

import (
    "context"
    "errors"
    "fmt"
    "log"

    "github.com/Arize-ai/client-go-v2/arize"
    "github.com/Arize-ai/client-go-v2/arize/annotationconfigs"
)

func main() {
    client, err := arize.NewClient(arize.Config{APIKey: "your-api-key"})
    if err != nil {
        log.Fatal(err)
    }

    newValues := []annotationconfigs.CategoricalAnnotationValue{
        {Label: "correct"},
        {Label: "partial"},
        {Label: "incorrect"},
    }
    ac, err := client.AnnotationConfigs.UpdateCategorical(
        context.Background(),
        annotationconfigs.UpdateCategoricalRequest{
            AnnotationConfig: "your-config-name-or-id",
            Space:            "your-space-name-or-id",
            Values:           &newValues,
        },
    )
    if err != nil {
        var notFound *arize.NotFoundError
        if errors.As(err, &notFound) {
            log.Fatalf("annotation config not found: %v", notFound)
        }
        log.Fatal(err)
    }

    if cat, err := ac.AsCategoricalAnnotationConfig(); err == nil {
        fmt.Printf("updated categorical annotation config %s (%d values)\n", cat.Name, len(cat.Values))
    }
}
```

## Update a Continuous Annotation Config

`UpdateContinuous` patches an existing continuous annotation config, resolving by name or ID. All patch fields are optional — leave a field `nil` to preserve its current value.

**Signature:**

```go theme={null}
func (c *Client) UpdateContinuous(
    ctx context.Context,
    req UpdateContinuousRequest,
) (*AnnotationConfig, error)
```

**Usage Example:**

```go theme={null}
package main

import (
    "context"
    "errors"
    "fmt"
    "log"

    "github.com/Arize-ai/client-go-v2/arize"
    "github.com/Arize-ai/client-go-v2/arize/annotationconfigs"
)

func main() {
    client, err := arize.NewClient(arize.Config{APIKey: "your-api-key"})
    if err != nil {
        log.Fatal(err)
    }

    newMax := 10.0
    ac, err := client.AnnotationConfigs.UpdateContinuous(
        context.Background(),
        annotationconfigs.UpdateContinuousRequest{
            AnnotationConfig: "your-config-name-or-id",
            Space:            "your-space-name-or-id",
            MaximumScore:     &newMax,
        },
    )
    if err != nil {
        var notFound *arize.NotFoundError
        if errors.As(err, &notFound) {
            log.Fatalf("annotation config not found: %v", notFound)
        }
        log.Fatal(err)
    }

    if cont, err := ac.AsContinuousAnnotationConfig(); err == nil {
        fmt.Printf("updated continuous annotation config %s\n", cont.Name)
    }
}
```

## Update a Freeform Annotation Config

`UpdateFreeform` patches an existing freeform annotation config, resolving by name or ID. Only `Name` may be patched — leave it `nil` to preserve the current value.

**Signature:**

```go theme={null}
func (c *Client) UpdateFreeform(
    ctx context.Context,
    req UpdateFreeformRequest,
) (*AnnotationConfig, error)
```

**Usage Example:**

```go theme={null}
package main

import (
    "context"
    "errors"
    "fmt"
    "log"

    "github.com/Arize-ai/client-go-v2/arize"
    "github.com/Arize-ai/client-go-v2/arize/annotationconfigs"
)

func main() {
    client, err := arize.NewClient(arize.Config{APIKey: "your-api-key"})
    if err != nil {
        log.Fatal(err)
    }

    newName := "renamed-comments"
    ac, err := client.AnnotationConfigs.UpdateFreeform(
        context.Background(),
        annotationconfigs.UpdateFreeformRequest{
            AnnotationConfig: "your-config-name-or-id",
            Space:            "your-space-name-or-id",
            Name:             &newName,
        },
    )
    if err != nil {
        var notFound *arize.NotFoundError
        if errors.As(err, &notFound) {
            log.Fatalf("annotation config not found: %v", notFound)
        }
        log.Fatal(err)
    }

    if free, err := ac.AsFreeformAnnotationConfig(); err == nil {
        fmt.Printf("updated freeform annotation config %s\n", free.Name)
    }
}
```

## Delete an Annotation Config

`Delete` removes an annotation config, resolving by name or ID. It returns only an error.

**Signature:**

```go theme={null}
func (c *Client) Delete(ctx context.Context, req DeleteRequest) error
```

**Usage Example:**

```go theme={null}
package main

import (
    "context"
    "errors"
    "log"

    "github.com/Arize-ai/client-go-v2/arize"
    "github.com/Arize-ai/client-go-v2/arize/annotationconfigs"
)

func main() {
    client, err := arize.NewClient(arize.Config{APIKey: "your-api-key"})
    if err != nil {
        log.Fatal(err)
    }

    err = client.AnnotationConfigs.Delete(
        context.Background(),
        annotationconfigs.DeleteRequest{
            AnnotationConfig: "your-config-name-or-id",
            Space:            "your-space-name-or-id",
        },
    )
    if err != nil {
        var notFound *arize.NotFoundError
        if errors.As(err, &notFound) {
            log.Printf("no annotation config to remove: %v", notFound)
            return
        }
        log.Fatal(err)
    }
}
```
