> ## Documentation Index
> Fetch the complete documentation index at: https://developers.telnyx.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Go SDK webhooks

> Verify Telnyx ED25519 webhook signatures and parse typed webhook events with the Go SDK.

Telnyx signs every webhook delivery with an ED25519 signature carried in the
`telnyx-signature-ed25519` and `telnyx-timestamp` request headers. The SDK's
webhook service verifies the signature against your account's public key and
parses the payload into a typed event union.

Copy your public key from the Mission Control Portal and expose it as
`TELNYX_PUBLIC_KEY` — `telnyx.NewClient()` reads it automatically, the same way
it reads `TELNYX_API_KEY`:

```bash theme={null}
export TELNYX_PUBLIC_KEY="..."
```

## Verify and parse an event

Pass the raw request body and the request headers to `client.Webhooks.Unwrap()`:

```go theme={null}
package main

import (
	"io"
	"log"
	"net/http"

	"github.com/team-telnyx/telnyx-go/v4"
)

func main() {
	client := telnyx.NewClient() // reads TELNYX_API_KEY and TELNYX_PUBLIC_KEY

	http.HandleFunc("/webhooks/telnyx", func(w http.ResponseWriter, r *http.Request) {
		payload, err := io.ReadAll(r.Body)
		if err != nil {
			w.WriteHeader(http.StatusBadRequest)
			return
		}

		event, err := client.Webhooks.Unwrap(payload, r.Header)
		if err != nil {
			// signature invalid or payload malformed
			w.WriteHeader(http.StatusBadRequest)
			return
		}

		log.Println(event.Data.EventType)
		w.WriteHeader(http.StatusOK)
	})

	log.Fatal(http.ListenAndServe(":3000", nil))
}
```

`Unwrap()` returns an error when the signature does not match, and returns the
parsed event as a union of every webhook event the API sends — switch on
`event.Data.EventType` or use the union's `As...()` accessors to handle
specific events. `client.Webhooks.Verify(payload, headers)` checks the
signature without parsing.

## Skipping verification

`client.Webhooks.UnsafeUnwrap(payload)` parses a payload without checking the
signature. Only use it for payloads you have already verified by other means,
or in tests.

## Related

* [Receiving webhooks](/docs/development/api-fundamentals/webhooks/receiving-webhooks)
  covers delivery, retries, and failover URLs.
* [Errors, retries, and timeouts](/docs/development/sdk/golang/errors-and-retries)
  covers the SDK's error types.
