> ## 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.

# Webhooks

> List, create, update, delete, test, and subscribe webhooks for prompt and evaluator events using the Arize Go SDK.

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

A webhook is an organization-level delivery destination — an HTTPS endpoint plus the authentication used to call it. Subscriptions attach a webhook to a single event on a single prompt or evaluator. The `Get`, `Update`, `Delete`, `Test`, `ListDeliveryAttempts`, and `CreateSubscription` methods accept either a webhook name or an ID — when a name is passed, the parent `Organization` (name or ID) is also required so the SDK can resolve the name to a unique ID. Subscriptions are addressed by strict ID. For `WebhookAuthTypeHMACSHA256` webhooks the signing secret is returned only once, in the `Create` response.

## List Webhooks

`List` returns a paginated list of webhooks, most recently created first. `Organization`, when non-empty, accepts an organization name or ID and restricts results to that organization. Webhooks used as monitor notification channels are included.

**Signature:**

```go theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
func (c *Client) List(ctx context.Context, req ListRequest) (*ListWebhooks, error)
```

**Usage Example:**

```go theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
package main

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

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

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

    resp, err := client.Webhooks.List(context.Background(), webhooks.ListRequest{
        Organization: "your-org-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 _, wh := range resp.Webhooks {
        fmt.Printf("%s: %s (%s)\n", wh.Id, wh.Name, wh.Url)
    }
}
```

## Get a Webhook

`Get` returns a single webhook, resolving by name or ID.

**Signature:**

```go theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
func (c *Client) Get(ctx context.Context, req GetRequest) (*Webhook, error)
```

**Usage Example:**

```go theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
package main

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

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

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

    wh, err := client.Webhooks.Get(
        context.Background(),
        webhooks.GetRequest{
            Webhook:      "your-webhook-name-or-id",
            Organization: "your-org-name-or-id",
        },
    )
    if err != nil {
        var notFound *arize.NotFoundError
        if errors.As(err, &notFound) {
            log.Fatalf("webhook not found: %v", notFound)
        }
        log.Fatal(err)
    }

    fmt.Printf("webhook %s: %s\n", wh.Id, wh.Name)
}
```

## Create a Webhook

`Create` creates a new webhook, resolving the owning organization by name or ID. When `AuthType` is empty the server applies its default (`WebhookAuthTypeBearer`). For `WebhookAuthTypeHMACSHA256` webhooks the response carries `SigningSecret` — this is the only time the secret is returned, so store it.

**Signature:**

```go theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
func (c *Client) Create(ctx context.Context, req CreateRequest) (*CreateWebhook, error)
```

**Usage Example:**

```go theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
package main

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

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

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

    wh, err := client.Webhooks.Create(
        context.Background(),
        webhooks.CreateRequest{
            Organization: "your-org-name-or-id",
            Name:         "prompt-change-notifier",
            URL:          "https://example.com/hooks/arize",
            AuthType:     webhooks.WebhookAuthTypeHMACSHA256,
        },
    )
    if err != nil {
        var conflict *arize.ConflictError
        if errors.As(err, &conflict) {
            log.Fatalf("webhook already exists: %v", conflict)
        }
        log.Fatal(err)
    }

    fmt.Printf("created webhook %s\n", wh.Id)
    if wh.SigningSecret != nil {
        fmt.Printf("store this signing secret now: %s\n", *wh.SigningSecret)
    }
}
```

## Update a Webhook

`Update` patches a webhook, resolving by name or ID. Only non-nil patch fields are sent; nil fields are left unchanged. For nullable fields (`Description`, `AuthToken`, `Headers`), pass a pointer to the empty value to clear the field. `AuthType` cannot be changed after creation, and an HMAC signing secret cannot be rotated — create a new webhook instead. Returns `webhooks.ErrNoUpdateFields` without contacting the server when every patch field is nil.

**Signature:**

```go theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
func (c *Client) Update(ctx context.Context, req UpdateRequest) (*Webhook, error)
```

**Usage Example:**

```go theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
package main

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

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

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

    newURL := "https://example.com/hooks/arize-v2"
    wh, err := client.Webhooks.Update(
        context.Background(),
        webhooks.UpdateRequest{
            Webhook:      "your-webhook-name-or-id",
            Organization: "your-org-name-or-id",
            URL:          &newURL,
        },
    )
    if err != nil {
        if errors.Is(err, webhooks.ErrNoUpdateFields) {
            log.Fatal("no fields to update")
        }
        var notFound *arize.NotFoundError
        if errors.As(err, &notFound) {
            log.Fatalf("webhook not found: %v", notFound)
        }
        log.Fatal(err)
    }

    fmt.Printf("updated webhook %s: %s\n", wh.Id, wh.Url)
}
```

## Delete a Webhook

`Delete` removes a webhook, resolving by name or ID. The webhook stops receiving events and is detached from every prompt, evaluator, and monitor it was subscribed to. It returns only an error.

**Signature:**

```go theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
func (c *Client) Delete(ctx context.Context, req DeleteRequest) error
```

**Usage Example:**

```go theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
package main

import (
    "context"
    "errors"
    "log"

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

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

    err = client.Webhooks.Delete(
        context.Background(),
        webhooks.DeleteRequest{
            Webhook:      "your-webhook-name-or-id",
            Organization: "your-org-name-or-id",
        },
    )
    if err != nil {
        var notFound *arize.NotFoundError
        if errors.As(err, &notFound) {
            log.Printf("no webhook to remove: %v", notFound)
            return
        }
        log.Fatal(err)
    }
}
```

## Test a Webhook

`Test` sends a test event to a webhook's endpoint, resolving the webhook by name or ID. A nil error means the test ran — inspect `StatusCode` and `ErrorMessage` on the response for the endpoint's outcome (`StatusCode` is 502 when no response was received). Test deliveries are not supported for `WebhookAuthTypeHMACSHA256` webhooks.

**Signature:**

```go theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
func (c *Client) Test(ctx context.Context, req TestRequest) (*TestWebhook, error)
```

**Usage Example:**

```go theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
package main

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

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

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

    result, err := client.Webhooks.Test(
        context.Background(),
        webhooks.TestRequest{
            Webhook:      "your-webhook-name-or-id",
            Organization: "your-org-name-or-id",
        },
    )
    if err != nil {
        var notFound *arize.NotFoundError
        if errors.As(err, &notFound) {
            log.Fatalf("webhook not found: %v", notFound)
        }
        log.Fatal(err)
    }

    fmt.Printf("test delivery returned HTTP %d\n", result.StatusCode)
}
```

## List Delivery Attempts

`ListDeliveryAttempts` returns a paginated list of a webhook's delivery attempts, most recent first, resolving the webhook by name or ID. Failed deliveries are retried, so one event may have several attempts.

**Signature:**

```go theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
func (c *Client) ListDeliveryAttempts(
    ctx context.Context,
    req ListDeliveryAttemptsRequest,
) (*ListWebhookDeliveryAttempts, error)
```

**Usage Example:**

```go theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
package main

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

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

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

    resp, err := client.Webhooks.ListDeliveryAttempts(
        context.Background(),
        webhooks.ListDeliveryAttemptsRequest{
            Webhook:      "your-webhook-name-or-id",
            Organization: "your-org-name-or-id",
            Limit:        50,
        },
    )
    if err != nil {
        var notFound *arize.NotFoundError
        if errors.As(err, &notFound) {
            log.Fatalf("webhook not found: %v", notFound)
        }
        log.Fatal(err)
    }

    for _, attempt := range resp.DeliveryAttempts {
        fmt.Printf("attempt #%d: HTTP %d\n", attempt.AttemptNumber, attempt.StatusCode)
    }
}
```

## List Subscriptions

`ListSubscriptions` returns a paginated list of webhook subscriptions, most recently created first. `SourceType` and `SourceID` must be set together; `webhooks.ErrUnpairedSourceFilter` is returned when only one is set. Subscriptions whose webhook has since been deleted are dropped after the page is read, so a page may hold fewer than `Limit` items while `Pagination.HasMore` is still true — keep paging until it is false.

**Signature:**

```go theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
func (c *Client) ListSubscriptions(
    ctx context.Context,
    req ListSubscriptionsRequest,
) (*ListWebhookSubscriptions, error)
```

**Usage Example:**

```go theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
package main

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

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

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

    resp, err := client.Webhooks.ListSubscriptions(
        context.Background(),
        webhooks.ListSubscriptionsRequest{
            SourceType: webhooks.WebhookSourceTypePrompt,
            SourceID:   "your-prompt-id",
            Limit:      50,
        },
    )
    if err != nil {
        if errors.Is(err, webhooks.ErrUnpairedSourceFilter) {
            log.Fatal("set SourceType and SourceID together")
        }
        log.Fatal(err)
    }

    for _, sub := range resp.Subscriptions {
        fmt.Printf("%s: %s\n", sub.Id, sub.Event)
    }
}
```

## Create a Subscription

`CreateSubscription` subscribes a webhook (resolved by name or ID) to one event on one prompt or evaluator. `Event` must belong to `SourceType`. To deliver several events to the same webhook, create one subscription per event.

**Signature:**

```go theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
func (c *Client) CreateSubscription(
    ctx context.Context,
    req CreateSubscriptionRequest,
) (*WebhookSubscription, error)
```

**Usage Example:**

```go theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
package main

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

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

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

    sub, err := client.Webhooks.CreateSubscription(
        context.Background(),
        webhooks.CreateSubscriptionRequest{
            Webhook:      "your-webhook-name-or-id",
            Organization: "your-org-name-or-id",
            SourceType:   webhooks.WebhookSourceTypePrompt,
            SourceID:     "your-prompt-id",
            Event:        webhooks.WebhookEventTypePromptVersionCreated,
        },
    )
    if err != nil {
        var badRequest *arize.BadRequestError
        if errors.As(err, &badRequest) {
            log.Fatalf("invalid subscription: %v", badRequest)
        }
        log.Fatal(err)
    }

    fmt.Printf("created subscription %s\n", sub.Id)
}
```

## Get a Subscription

`GetSubscription` returns a single webhook subscription by its strict ID. A 404 is returned when the subscription does not exist, its source is not readable, or its webhook has since been deleted.

**Signature:**

```go theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
func (c *Client) GetSubscription(
    ctx context.Context,
    req GetSubscriptionRequest,
) (*WebhookSubscription, error)
```

**Usage Example:**

```go theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
package main

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

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

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

    sub, err := client.Webhooks.GetSubscription(
        context.Background(),
        webhooks.GetSubscriptionRequest{SubscriptionID: "your-subscription-id"},
    )
    if err != nil {
        var notFound *arize.NotFoundError
        if errors.As(err, &notFound) {
            log.Fatalf("subscription not found: %v", notFound)
        }
        log.Fatal(err)
    }

    fmt.Printf("subscription %s delivers %s\n", sub.Id, sub.Event)
}
```

## Delete a Subscription

`DeleteSubscription` removes a webhook subscription by its strict ID. Other subscriptions on the source and the webhook itself are unaffected. It returns only an error.

**Signature:**

```go theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
func (c *Client) DeleteSubscription(ctx context.Context, req DeleteSubscriptionRequest) error
```

**Usage Example:**

```go theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
package main

import (
    "context"
    "errors"
    "log"

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

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

    err = client.Webhooks.DeleteSubscription(
        context.Background(),
        webhooks.DeleteSubscriptionRequest{SubscriptionID: "your-subscription-id"},
    )
    if err != nil {
        var notFound *arize.NotFoundError
        if errors.As(err, &notFound) {
            log.Printf("no subscription to remove: %v", notFound)
            return
        }
        log.Fatal(err)
    }
}
```
