Documentation Index: Fetch llms.txt first to discover every published page. This page is also available as Markdown at /go-webhook-schema-validation.md.
Verified · 8/11/2026

Webhook Payload Schema Validation

Validate raw webhook payloads against the embedded EmailReceivedEvent JSON Schema in the Go SDK, using ValidateEmailReceivedEvent (error-raising) or SafeValidateEmailReceivedEvent (error-collecting).

The Go SDK embeds the canonical webhook JSON Schema (generated from json-schema/email-received-event.schema.json in the monorepo) and exposes ValidateEmailReceivedEvent, the function that checks an already-JSON-decoded webhook payload against it. It takes a decoded value (map[string]any or similar), not raw bytes.

Most callers never call it directly. primitive.Receive(...) and primitive.HandleWebhook(...) run this validation internally after signature verification; see Receiving and Verifying Webhooks. Reach for ValidateEmailReceivedEvent directly when you already have a parsed payload from somewhere else (a stored fixture, a replayed delivery, a test) and want the schema check without re-running signature verification.

ValidateEmailReceivedEvent#

ValidateEmailReceivedEvent validates a decoded payload against the embedded email.received schema and returns a typed *EmailReceivedEvent on success or an error on failure.

package main

import (
	"encoding/json"
	"fmt"
	"log"
	"os"

	primitive "github.com/primitivedotdev/sdks/sdk-go"
)

func main() {
	raw, err := os.ReadFile("stored-delivery.json")
	if err != nil {
		log.Fatal(err)
	}

	var payload map[string]any
	if err := json.Unmarshal(raw, &payload); err != nil {
		log.Fatal(err)
	}

	event, err := primitive.ValidateEmailReceivedEvent(payload)
	if err != nil {
		log.Fatalf("invalid email.received payload: %v", err)
	}
	fmt.Println(event.Email.Headers.Subject)
}
AspectDetail
InputA decoded value (for example map[string]any from json.Unmarshal, or the result of primitive.ParseJSONBody)
Success return*EmailReceivedEvent, nil
Failure returnnil, error
Used internally byprimitive.HandleWebhook, primitive.Receive, and primitive.ParseWebhookEvent (for the email.received case)

See Error Handling for the Go SDK's error types, including WebhookValidationError, WebhookPayloadError, and WebhookVerificationError.

Parsing raw bytes first#

primitive.ParseJSONBody turns a raw request body into the decoded value this validator expects, rejecting empty bodies, invalid UTF-8, and trailing content after the JSON value with a WebhookPayloadError. It also strips a leading UTF-8 BOM.

parsed, err := primitive.ParseJSONBody(rawBody)
if err != nil {
	log.Fatal(err)
}

event, err := primitive.ValidateEmailReceivedEvent(parsed)
if err != nil {
	log.Fatal(err)
}
_ = event

Where the schema comes from#

The embedded schema is generated, not hand-maintained inside sdk-go. Its source of truth is json-schema/email-received-event.schema.json at the monorepo root, and changing the webhook contract means editing that file and running make go-generate from the repo root rather than editing anything under sdk-go. See Monorepo Structure and Release Process for the regeneration workflow and Webhook Schema Codegen for how the schema compiles into per-language model and validator modules.

Relationship to unknown event types#

Strict schema validation applies only to email.received. ParseWebhookEvent routes payment.* bodies to a typed PaymentEvent, interaction.* bodies to InteractionEvent, and everything else to UnknownEvent for forward compatibility, so a future event type never fails validation. See Webhook Event Types for the full catalog and the X-Webhook-Event header discriminator.

Next steps#

Was this page helpful?

© Primitive SDKs

Powered by Browzer