{"schema_version":"1.0","publisher":"Primitive SDKs","canonical_url":"https://test.abhinandan.one/go-webhook-schema-validation","markdown_url":"https://test.abhinandan.one/go-webhook-schema-validation.md","article":{"id":"423463bb-5982-40cd-a9e9-67ca885daab2","article_slug":"go-webhook-schema-validation","parent_article_slug":null,"parent_article_title":null,"kind":"reference","published_at":"2026-08-11T18:54:56.907919+00:00","keywords":["ValidateEmailReceivedEvent","SafeValidateEmailReceivedEvent","EmailReceivedEvent JSON Schema","email-received-event.schema.json Go","WebhookValidationError Go","embedded schema Go SDK"],"meta_description":"ValidateEmailReceivedEvent and SafeValidateEmailReceivedEvent check a raw webhook payload against the embedded EmailReceivedEvent JSON Schema in the Go SDK.","og_image_url":null,"source_file_paths":[],"recording_id":null,"replayable":false,"task_name":"Webhook Payload Schema Validation","category":"Go SDK","summary":null,"description":"Validate raw webhook payloads against the embedded EmailReceivedEvent JSON Schema in the Go SDK, using ValidateEmailReceivedEvent (error-raising) or SafeValidateEmailReceivedEvent (error-collecting).","content_kind":"repo_page","content_markdown":"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.\n\nMost callers never call it directly. `primitive.Receive(...)` and `primitive.HandleWebhook(...)` run this validation internally after signature verification; see [Receiving and Verifying Webhooks](go-receiving-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.\n\n## ValidateEmailReceivedEvent\n\n`ValidateEmailReceivedEvent` validates a decoded payload against the embedded `email.received` schema and returns a typed `*EmailReceivedEvent` on success or an error on failure.\n\n```go\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tprimitive \"github.com/primitivedotdev/sdks/sdk-go\"\n)\n\nfunc main() {\n\traw, err := os.ReadFile(\"stored-delivery.json\")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tvar payload map[string]any\n\tif err := json.Unmarshal(raw, &payload); err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tevent, err := primitive.ValidateEmailReceivedEvent(payload)\n\tif err != nil {\n\t\tlog.Fatalf(\"invalid email.received payload: %v\", err)\n\t}\n\tfmt.Println(event.Email.Headers.Subject)\n}\n```\n\n| Aspect | Detail |\n|---|---|\n| Input | A decoded value (for example `map[string]any` from `json.Unmarshal`, or the result of `primitive.ParseJSONBody`) |\n| Success return | `*EmailReceivedEvent`, `nil` |\n| Failure return | `nil`, error |\n| Used internally by | `primitive.HandleWebhook`, `primitive.Receive`, and `primitive.ParseWebhookEvent` (for the `email.received` case) |\n\nSee [Error Handling](go-error-handling) for the Go SDK's error types, including `WebhookValidationError`, `WebhookPayloadError`, and `WebhookVerificationError`.\n\n## Parsing raw bytes first\n\n`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.\n\n```go\nparsed, err := primitive.ParseJSONBody(rawBody)\nif err != nil {\n\tlog.Fatal(err)\n}\n\nevent, err := primitive.ValidateEmailReceivedEvent(parsed)\nif err != nil {\n\tlog.Fatal(err)\n}\n_ = event\n```\n\n## Where the schema comes from\n\nThe 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](monorepo-and-releases) for the regeneration workflow and [Webhook Schema Codegen](webhook-schema-codegen) for how the schema compiles into per-language model and validator modules.\n\n## Relationship to unknown event types\n\nStrict 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](go-webhook-event-types) for the full catalog and the `X-Webhook-Event` header discriminator.\n\n## Next steps\n\n<CardGroup cols={2}>\n\n<Card title=\"Receiving and Verifying Webhooks\" href=\"go-receiving-webhooks\">\n\nSee how signature verification and this schema check compose inside Receive and HandleWebhook.\n\n</Card>\n\n<Card title=\"Error Handling\" href=\"go-error-handling\">\n\nLook up WebhookValidationError and every other error type the Go SDK returns.\n\n</Card>\n\n<Card title=\"Webhook Schema Codegen\" href=\"webhook-schema-codegen\">\n\nTrace how the shared schema file compiles into the Go SDK's embedded validator.\n\n</Card>\n\n<Card title=\"Webhook Event Types\" href=\"go-webhook-event-types\">\n\nUnderstand the email, payment, and interaction event catalog and the X-Webhook-Event header.\n\n</Card>\n\n</CardGroup>","canonical_base_url":"https://test.abhinandan.one","seo_indexing_enabled":true,"last_modified":"2026-08-21T18:22:43.359885+00:00","video_url":null,"voiceover_url":null,"tools_used":[],"demonstrated_by":[],"steps":[],"related_links":[],"intro":null,"prerequisites":[],"verification":[],"troubleshooting":[],"suggest_edit_url":null,"raise_issue_url":"https://github.com/abhi-browzer/primitive-sdks/issues/new?title=Docs+feedback%3A+Webhook+Payload+Schema+Validation&body=Page%3A+https%3A%2F%2Ftest.abhinandan.one%2Fgo-webhook-schema-validation","page_feedback_enabled":true,"verified_ref":null,"verified_at":"2026-08-11T18:38:45.205849+00:00"}}